From cf94bdc0742c13e2a0cac864c478b8626b266e1b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/clap-3.2.20/.cargo-checksum.json | 1 + vendor/clap-3.2.20/Cargo.lock | 746 + vendor/clap-3.2.20/Cargo.toml | 471 + vendor/clap-3.2.20/LICENSE-APACHE | 201 + vendor/clap-3.2.20/LICENSE-MIT | 21 + vendor/clap-3.2.20/README.md | 43 + .../clap-3.2.20/examples/cargo-example-derive.md | 43 + .../clap-3.2.20/examples/cargo-example-derive.rs | 20 + vendor/clap-3.2.20/examples/cargo-example.md | 43 + vendor/clap-3.2.20/examples/cargo-example.rs | 19 + vendor/clap-3.2.20/examples/demo.md | 19 + vendor/clap-3.2.20/examples/demo.rs | 22 + .../examples/derive_ref/augment_args.rs | 27 + .../examples/derive_ref/augment_subcommands.rs | 21 + .../clap-3.2.20/examples/derive_ref/custom-bool.md | 47 + .../clap-3.2.20/examples/derive_ref/custom-bool.rs | 32 + .../examples/derive_ref/flatten_hand_args.rs | 81 + .../examples/derive_ref/hand_subcommand.rs | 81 + .../examples/derive_ref/interop_tests.md | 256 + .../examples/escaped-positional-derive.md | 63 + .../examples/escaped-positional-derive.rs | 25 + vendor/clap-3.2.20/examples/escaped-positional.md | 63 + vendor/clap-3.2.20/examples/escaped-positional.rs | 36 + vendor/clap-3.2.20/examples/git-derive.md | 138 + vendor/clap-3.2.20/examples/git-derive.rs | 105 + vendor/clap-3.2.20/examples/git.md | 136 + vendor/clap-3.2.20/examples/git.rs | 101 + vendor/clap-3.2.20/examples/multicall-busybox.md | 42 + vendor/clap-3.2.20/examples/multicall-busybox.rs | 48 + vendor/clap-3.2.20/examples/multicall-hostname.md | 10 + vendor/clap-3.2.20/examples/multicall-hostname.rs | 17 + vendor/clap-3.2.20/examples/pacman.md | 85 + vendor/clap-3.2.20/examples/pacman.rs | 111 + vendor/clap-3.2.20/examples/repl.rs | 92 + .../examples/tutorial_builder/01_quick.md | 37 + .../examples/tutorial_builder/01_quick.rs | 63 + .../examples/tutorial_builder/02_app_settings.md | 19 + .../examples/tutorial_builder/02_app_settings.rs | 19 + .../examples/tutorial_builder/02_apps.md | 19 + .../examples/tutorial_builder/02_apps.rs | 20 + .../examples/tutorial_builder/02_crate.md | 18 + .../examples/tutorial_builder/02_crate.rs | 18 + .../examples/tutorial_builder/03_01_flag_bool.md | 23 + .../examples/tutorial_builder/03_01_flag_bool.rs | 14 + .../examples/tutorial_builder/03_01_flag_count.md | 23 + .../examples/tutorial_builder/03_01_flag_count.rs | 9 + .../examples/tutorial_builder/03_02_option.md | 32 + .../examples/tutorial_builder/03_02_option.rs | 9 + .../examples/tutorial_builder/03_03_positional.md | 22 + .../examples/tutorial_builder/03_03_positional.rs | 9 + .../examples/tutorial_builder/03_04_subcommands.md | 64 + .../examples/tutorial_builder/03_04_subcommands.rs | 22 + .../tutorial_builder/03_05_default_values.md | 22 + .../tutorial_builder/03_05_default_values.rs | 14 + .../examples/tutorial_builder/04_01_enum.md | 29 + .../examples/tutorial_builder/04_01_enum.rs | 66 + .../examples/tutorial_builder/04_01_possible.md | 29 + .../examples/tutorial_builder/04_01_possible.rs | 26 + .../examples/tutorial_builder/04_02_parse.md | 31 + .../examples/tutorial_builder/04_02_parse.rs | 17 + .../examples/tutorial_builder/04_02_validate.md | 31 + .../examples/tutorial_builder/04_02_validate.rs | 36 + .../examples/tutorial_builder/04_03_relations.md | 58 + .../examples/tutorial_builder/04_03_relations.rs | 80 + .../examples/tutorial_builder/04_04_custom.md | 57 + .../examples/tutorial_builder/04_04_custom.rs | 88 + .../examples/tutorial_builder/05_01_assert.rs | 25 + .../examples/tutorial_derive/01_quick.md | 37 + .../examples/tutorial_derive/01_quick.rs | 69 + .../examples/tutorial_derive/02_app_settings.md | 19 + .../examples/tutorial_derive/02_app_settings.rs | 19 + .../examples/tutorial_derive/02_apps.md | 19 + .../examples/tutorial_derive/02_apps.rs | 20 + .../examples/tutorial_derive/02_crate.md | 18 + .../examples/tutorial_derive/02_crate.rs | 17 + .../examples/tutorial_derive/03_01_flag_bool.md | 23 + .../examples/tutorial_derive/03_01_flag_bool.rs | 14 + .../examples/tutorial_derive/03_01_flag_count.md | 23 + .../examples/tutorial_derive/03_01_flag_count.rs | 14 + .../examples/tutorial_derive/03_02_option.md | 32 + .../examples/tutorial_derive/03_02_option.rs | 14 + .../examples/tutorial_derive/03_03_positional.md | 22 + .../examples/tutorial_derive/03_03_positional.rs | 14 + .../examples/tutorial_derive/03_04_subcommands.md | 64 + .../examples/tutorial_derive/03_04_subcommands.rs | 30 + .../tutorial_derive/03_04_subcommands_alt.rs | 33 + .../tutorial_derive/03_05_default_values.md | 22 + .../tutorial_derive/03_05_default_values.rs | 14 + .../examples/tutorial_derive/04_01_enum.md | 29 + .../examples/tutorial_derive/04_01_enum.rs | 28 + .../examples/tutorial_derive/04_02_parse.md | 31 + .../examples/tutorial_derive/04_02_parse.rs | 15 + .../examples/tutorial_derive/04_02_validate.md | 31 + .../examples/tutorial_derive/04_02_validate.rs | 34 + .../examples/tutorial_derive/04_03_relations.md | 58 + .../examples/tutorial_derive/04_03_relations.rs | 72 + .../examples/tutorial_derive/04_04_custom.md | 57 + .../examples/tutorial_derive/04_04_custom.rs | 93 + .../examples/tutorial_derive/05_01_assert.rs | 21 + vendor/clap-3.2.20/examples/typed-derive.md | 84 + vendor/clap-3.2.20/examples/typed-derive.rs | 44 + vendor/clap-3.2.20/src/_cookbook/cargo_example.rs | 7 + .../clap-3.2.20/src/_cookbook/cargo_example_derive | 0 .../src/_cookbook/cargo_example_derive.rs | 7 + .../src/_cookbook/escaped_positional.rs | 7 + .../src/_cookbook/escaped_positional_derive.rs | 7 + vendor/clap-3.2.20/src/_cookbook/git.rs | 7 + vendor/clap-3.2.20/src/_cookbook/git_derive.rs | 7 + vendor/clap-3.2.20/src/_cookbook/mod.rs | 55 + .../clap-3.2.20/src/_cookbook/multicall_busybox.rs | 7 + .../src/_cookbook/multicall_hostname.rs | 7 + vendor/clap-3.2.20/src/_cookbook/pacman.rs | 7 + vendor/clap-3.2.20/src/_cookbook/repl.rs | 5 + vendor/clap-3.2.20/src/_cookbook/typed_derive.rs | 7 + vendor/clap-3.2.20/src/_derive/_tutorial.rs | 205 + vendor/clap-3.2.20/src/_derive/mod.rs | 510 + vendor/clap-3.2.20/src/_faq.rs | 95 + vendor/clap-3.2.20/src/_features.rs | 27 + vendor/clap-3.2.20/src/_tutorial.rs | 204 + vendor/clap-3.2.20/src/bin/stdio-fixture.rs | 14 + vendor/clap-3.2.20/src/builder/action.rs | 325 + vendor/clap-3.2.20/src/builder/app_settings.rs | 864 + vendor/clap-3.2.20/src/builder/arg.rs | 5494 ++++++ vendor/clap-3.2.20/src/builder/arg_group.rs | 633 + vendor/clap-3.2.20/src/builder/arg_predicate.rs | 14 + vendor/clap-3.2.20/src/builder/arg_settings.rs | 456 + vendor/clap-3.2.20/src/builder/command.rs | 5189 ++++++ vendor/clap-3.2.20/src/builder/debug_asserts.rs | 851 + vendor/clap-3.2.20/src/builder/macros.rs | 180 + vendor/clap-3.2.20/src/builder/mod.rs | 61 + vendor/clap-3.2.20/src/builder/possible_value.rs | 259 + vendor/clap-3.2.20/src/builder/regex.rs | 88 + vendor/clap-3.2.20/src/builder/tests.rs | 56 + vendor/clap-3.2.20/src/builder/usage_parser.rs | 1277 ++ vendor/clap-3.2.20/src/builder/value_hint.rs | 95 + vendor/clap-3.2.20/src/builder/value_parser.rs | 2089 +++ vendor/clap-3.2.20/src/derive.rs | 577 + vendor/clap-3.2.20/src/error/context.rs | 55 + vendor/clap-3.2.20/src/error/kind.rs | 440 + vendor/clap-3.2.20/src/error/mod.rs | 1153 ++ vendor/clap-3.2.20/src/lib.rs | 232 + vendor/clap-3.2.20/src/macros.rs | 1058 ++ vendor/clap-3.2.20/src/mkeymap.rs | 193 + vendor/clap-3.2.20/src/output/fmt.rs | 158 + vendor/clap-3.2.20/src/output/help.rs | 1176 ++ vendor/clap-3.2.20/src/output/mod.rs | 7 + vendor/clap-3.2.20/src/output/usage.rs | 449 + vendor/clap-3.2.20/src/parser/arg_matcher.rs | 280 + vendor/clap-3.2.20/src/parser/error.rs | 67 + vendor/clap-3.2.20/src/parser/features/mod.rs | 1 + .../clap-3.2.20/src/parser/features/suggestions.rs | 105 + vendor/clap-3.2.20/src/parser/matches/any_value.rs | 112 + .../clap-3.2.20/src/parser/matches/arg_matches.rs | 1896 +++ .../clap-3.2.20/src/parser/matches/matched_arg.rs | 240 + vendor/clap-3.2.20/src/parser/matches/mod.rs | 17 + .../clap-3.2.20/src/parser/matches/value_source.rs | 11 + vendor/clap-3.2.20/src/parser/mod.rs | 27 + vendor/clap-3.2.20/src/parser/parser.rs | 1729 ++ vendor/clap-3.2.20/src/parser/validator.rs | 692 + vendor/clap-3.2.20/src/util/color.rs | 62 + vendor/clap-3.2.20/src/util/fnv.rs | 46 + vendor/clap-3.2.20/src/util/graph.rs | 49 + vendor/clap-3.2.20/src/util/id.rs | 92 + vendor/clap-3.2.20/src/util/mod.rs | 40 + vendor/clap-3.2.20/src/util/str_to_bool.rs | 21 + vendor/clap/.cargo-checksum.json | 1 - vendor/clap/Cargo.lock | 746 - vendor/clap/Cargo.toml | 471 - vendor/clap/LICENSE-APACHE | 201 - vendor/clap/LICENSE-MIT | 21 - vendor/clap/README.md | 43 - vendor/clap/examples/cargo-example-derive.md | 43 - vendor/clap/examples/cargo-example-derive.rs | 20 - vendor/clap/examples/cargo-example.md | 43 - vendor/clap/examples/cargo-example.rs | 19 - vendor/clap/examples/demo.md | 19 - vendor/clap/examples/demo.rs | 22 - vendor/clap/examples/derive_ref/augment_args.rs | 27 - .../examples/derive_ref/augment_subcommands.rs | 21 - vendor/clap/examples/derive_ref/custom-bool.md | 47 - vendor/clap/examples/derive_ref/custom-bool.rs | 32 - .../clap/examples/derive_ref/flatten_hand_args.rs | 81 - vendor/clap/examples/derive_ref/hand_subcommand.rs | 81 - vendor/clap/examples/derive_ref/interop_tests.md | 256 - vendor/clap/examples/escaped-positional-derive.md | 63 - vendor/clap/examples/escaped-positional-derive.rs | 25 - vendor/clap/examples/escaped-positional.md | 63 - vendor/clap/examples/escaped-positional.rs | 36 - vendor/clap/examples/git-derive.md | 138 - vendor/clap/examples/git-derive.rs | 105 - vendor/clap/examples/git.md | 136 - vendor/clap/examples/git.rs | 101 - vendor/clap/examples/multicall-busybox.md | 42 - vendor/clap/examples/multicall-busybox.rs | 48 - vendor/clap/examples/multicall-hostname.md | 10 - vendor/clap/examples/multicall-hostname.rs | 17 - vendor/clap/examples/pacman.md | 85 - vendor/clap/examples/pacman.rs | 111 - vendor/clap/examples/repl.rs | 92 - vendor/clap/examples/tutorial_builder/01_quick.md | 37 - vendor/clap/examples/tutorial_builder/01_quick.rs | 63 - .../examples/tutorial_builder/02_app_settings.md | 19 - .../examples/tutorial_builder/02_app_settings.rs | 19 - vendor/clap/examples/tutorial_builder/02_apps.md | 19 - vendor/clap/examples/tutorial_builder/02_apps.rs | 20 - vendor/clap/examples/tutorial_builder/02_crate.md | 18 - vendor/clap/examples/tutorial_builder/02_crate.rs | 18 - .../examples/tutorial_builder/03_01_flag_bool.md | 23 - .../examples/tutorial_builder/03_01_flag_bool.rs | 14 - .../examples/tutorial_builder/03_01_flag_count.md | 23 - .../examples/tutorial_builder/03_01_flag_count.rs | 9 - .../clap/examples/tutorial_builder/03_02_option.md | 32 - .../clap/examples/tutorial_builder/03_02_option.rs | 9 - .../examples/tutorial_builder/03_03_positional.md | 22 - .../examples/tutorial_builder/03_03_positional.rs | 9 - .../examples/tutorial_builder/03_04_subcommands.md | 64 - .../examples/tutorial_builder/03_04_subcommands.rs | 22 - .../tutorial_builder/03_05_default_values.md | 22 - .../tutorial_builder/03_05_default_values.rs | 14 - .../clap/examples/tutorial_builder/04_01_enum.md | 29 - .../clap/examples/tutorial_builder/04_01_enum.rs | 66 - .../examples/tutorial_builder/04_01_possible.md | 29 - .../examples/tutorial_builder/04_01_possible.rs | 26 - .../clap/examples/tutorial_builder/04_02_parse.md | 31 - .../clap/examples/tutorial_builder/04_02_parse.rs | 17 - .../examples/tutorial_builder/04_02_validate.md | 31 - .../examples/tutorial_builder/04_02_validate.rs | 36 - .../examples/tutorial_builder/04_03_relations.md | 58 - .../examples/tutorial_builder/04_03_relations.rs | 80 - .../clap/examples/tutorial_builder/04_04_custom.md | 57 - .../clap/examples/tutorial_builder/04_04_custom.rs | 88 - .../clap/examples/tutorial_builder/05_01_assert.rs | 25 - vendor/clap/examples/tutorial_derive/01_quick.md | 37 - vendor/clap/examples/tutorial_derive/01_quick.rs | 69 - .../examples/tutorial_derive/02_app_settings.md | 19 - .../examples/tutorial_derive/02_app_settings.rs | 19 - vendor/clap/examples/tutorial_derive/02_apps.md | 19 - vendor/clap/examples/tutorial_derive/02_apps.rs | 20 - vendor/clap/examples/tutorial_derive/02_crate.md | 18 - vendor/clap/examples/tutorial_derive/02_crate.rs | 17 - .../examples/tutorial_derive/03_01_flag_bool.md | 23 - .../examples/tutorial_derive/03_01_flag_bool.rs | 14 - .../examples/tutorial_derive/03_01_flag_count.md | 23 - .../examples/tutorial_derive/03_01_flag_count.rs | 14 - .../clap/examples/tutorial_derive/03_02_option.md | 32 - .../clap/examples/tutorial_derive/03_02_option.rs | 14 - .../examples/tutorial_derive/03_03_positional.md | 22 - .../examples/tutorial_derive/03_03_positional.rs | 14 - .../examples/tutorial_derive/03_04_subcommands.md | 64 - .../examples/tutorial_derive/03_04_subcommands.rs | 30 - .../tutorial_derive/03_04_subcommands_alt.rs | 33 - .../tutorial_derive/03_05_default_values.md | 22 - .../tutorial_derive/03_05_default_values.rs | 14 - vendor/clap/examples/tutorial_derive/04_01_enum.md | 29 - vendor/clap/examples/tutorial_derive/04_01_enum.rs | 28 - .../clap/examples/tutorial_derive/04_02_parse.md | 31 - .../clap/examples/tutorial_derive/04_02_parse.rs | 15 - .../examples/tutorial_derive/04_02_validate.md | 31 - .../examples/tutorial_derive/04_02_validate.rs | 34 - .../examples/tutorial_derive/04_03_relations.md | 58 - .../examples/tutorial_derive/04_03_relations.rs | 72 - .../clap/examples/tutorial_derive/04_04_custom.md | 57 - .../clap/examples/tutorial_derive/04_04_custom.rs | 93 - .../clap/examples/tutorial_derive/05_01_assert.rs | 21 - vendor/clap/examples/typed-derive.md | 84 - vendor/clap/examples/typed-derive.rs | 44 - vendor/clap/src/_cookbook/cargo_example.rs | 7 - vendor/clap/src/_cookbook/cargo_example_derive | 0 vendor/clap/src/_cookbook/cargo_example_derive.rs | 7 - vendor/clap/src/_cookbook/escaped_positional.rs | 7 - .../src/_cookbook/escaped_positional_derive.rs | 7 - vendor/clap/src/_cookbook/git.rs | 7 - vendor/clap/src/_cookbook/git_derive.rs | 7 - vendor/clap/src/_cookbook/mod.rs | 55 - vendor/clap/src/_cookbook/multicall_busybox.rs | 7 - vendor/clap/src/_cookbook/multicall_hostname.rs | 7 - vendor/clap/src/_cookbook/pacman.rs | 7 - vendor/clap/src/_cookbook/repl.rs | 5 - vendor/clap/src/_cookbook/typed_derive.rs | 7 - vendor/clap/src/_derive/_tutorial.rs | 205 - vendor/clap/src/_derive/mod.rs | 510 - vendor/clap/src/_faq.rs | 95 - vendor/clap/src/_features.rs | 27 - vendor/clap/src/_tutorial.rs | 204 - vendor/clap/src/bin/stdio-fixture.rs | 14 - vendor/clap/src/builder/action.rs | 325 - vendor/clap/src/builder/app_settings.rs | 864 - vendor/clap/src/builder/arg.rs | 5494 ------ vendor/clap/src/builder/arg_group.rs | 633 - vendor/clap/src/builder/arg_predicate.rs | 14 - vendor/clap/src/builder/arg_settings.rs | 456 - vendor/clap/src/builder/command.rs | 5189 ------ vendor/clap/src/builder/debug_asserts.rs | 851 - vendor/clap/src/builder/macros.rs | 180 - vendor/clap/src/builder/mod.rs | 61 - vendor/clap/src/builder/possible_value.rs | 259 - vendor/clap/src/builder/regex.rs | 88 - vendor/clap/src/builder/tests.rs | 56 - vendor/clap/src/builder/usage_parser.rs | 1277 -- vendor/clap/src/builder/value_hint.rs | 95 - vendor/clap/src/builder/value_parser.rs | 2089 --- vendor/clap/src/derive.rs | 577 - vendor/clap/src/error/context.rs | 55 - vendor/clap/src/error/kind.rs | 440 - vendor/clap/src/error/mod.rs | 1153 -- vendor/clap/src/lib.rs | 232 - vendor/clap/src/macros.rs | 1058 -- vendor/clap/src/mkeymap.rs | 193 - vendor/clap/src/output/fmt.rs | 158 - vendor/clap/src/output/help.rs | 1176 -- vendor/clap/src/output/mod.rs | 7 - vendor/clap/src/output/usage.rs | 449 - vendor/clap/src/parser/arg_matcher.rs | 280 - vendor/clap/src/parser/error.rs | 67 - vendor/clap/src/parser/features/mod.rs | 1 - vendor/clap/src/parser/features/suggestions.rs | 105 - vendor/clap/src/parser/matches/any_value.rs | 112 - vendor/clap/src/parser/matches/arg_matches.rs | 1896 --- vendor/clap/src/parser/matches/matched_arg.rs | 240 - vendor/clap/src/parser/matches/mod.rs | 17 - vendor/clap/src/parser/matches/value_source.rs | 11 - vendor/clap/src/parser/mod.rs | 27 - vendor/clap/src/parser/parser.rs | 1729 -- vendor/clap/src/parser/validator.rs | 692 - vendor/clap/src/util/color.rs | 62 - vendor/clap/src/util/fnv.rs | 46 - vendor/clap/src/util/graph.rs | 49 - vendor/clap/src/util/id.rs | 92 - vendor/clap/src/util/mod.rs | 40 - vendor/clap/src/util/str_to_bool.rs | 21 - vendor/clap_lex-0.2.2/.cargo-checksum.json | 1 + vendor/clap_lex-0.2.2/Cargo.toml | 89 + vendor/clap_lex-0.2.2/LICENSE-APACHE | 201 + vendor/clap_lex-0.2.2/LICENSE-MIT | 21 + vendor/clap_lex-0.2.2/README.md | 19 + vendor/clap_lex-0.2.2/src/lib.rs | 484 + vendor/clap_lex/.cargo-checksum.json | 1 - vendor/clap_lex/Cargo.toml | 89 - vendor/clap_lex/LICENSE-APACHE | 201 - vendor/clap_lex/LICENSE-MIT | 21 - vendor/clap_lex/README.md | 19 - vendor/clap_lex/src/lib.rs | 484 - vendor/compiler_builtins/.cargo-checksum.json | 2 +- vendor/compiler_builtins/Cargo.lock | 2 +- vendor/compiler_builtins/Cargo.toml | 3 +- vendor/compiler_builtins/LICENSE.txt | 91 + vendor/compiler_builtins/src/float/conv.rs | 6 +- vendor/compiler_builtins/src/float/div.rs | 6 +- .../src/int/specialized_div_rem/mod.rs | 5 +- vendor/compiler_builtins/src/macros.rs | 1 + vendor/compiler_builtins/src/math.rs | 7 +- vendor/compiletest_rs/.cargo-checksum.json | 2 +- vendor/compiletest_rs/Cargo.toml | 2 +- vendor/compiletest_rs/README.md | 4 +- vendor/compiletest_rs/src/runtest.rs | 47 +- vendor/crossbeam-epoch/.cargo-checksum.json | 2 +- vendor/crossbeam-epoch/CHANGELOG.md | 5 + vendor/crossbeam-epoch/Cargo.lock | 48 +- vendor/crossbeam-epoch/Cargo.toml | 7 +- vendor/crossbeam-epoch/no_atomic.rs | 6 + vendor/crossbeam-epoch/src/default.rs | 34 +- vendor/crossbeam-epoch/src/lib.rs | 2 +- vendor/crossbeam-epoch/src/sync/mod.rs | 3 + vendor/crossbeam-epoch/src/sync/once_lock.rs | 103 + vendor/crossbeam-utils/.cargo-checksum.json | 2 +- vendor/crossbeam-utils/CHANGELOG.md | 5 + vendor/crossbeam-utils/Cargo.toml | 8 +- vendor/crossbeam-utils/no_atomic.rs | 6 + vendor/crossbeam-utils/src/cache_padded.rs | 6 +- vendor/crossbeam-utils/src/sync/mod.rs | 2 + vendor/crossbeam-utils/src/sync/once_lock.rs | 103 + vendor/crossbeam-utils/src/sync/sharded_lock.rs | 24 +- vendor/crossbeam-utils/src/sync/wait_group.rs | 5 +- vendor/dashmap/.cargo-checksum.json | 2 +- vendor/dashmap/Cargo.toml | 13 +- vendor/dashmap/src/lib.rs | 59 +- vendor/dashmap/src/rayon/map.rs | 4 +- vendor/dashmap/src/rayon/read_only.rs | 96 + vendor/dashmap/src/read_only.rs | 2 +- vendor/dashmap/src/table.rs | 81 - vendor/form_urlencoded/.cargo-checksum.json | 2 +- vendor/form_urlencoded/Cargo.toml | 18 +- vendor/form_urlencoded/src/lib.rs | 6 +- vendor/home/.cargo-checksum.json | 2 +- vendor/home/Cargo.toml | 26 +- vendor/home/src/env.rs | 106 + vendor/home/src/lib.rs | 48 +- vendor/idna/.cargo-checksum.json | 2 +- vendor/idna/Cargo.toml | 23 +- vendor/idna/LICENSE-MIT | 2 +- vendor/idna/src/lib.rs | 3 +- vendor/idna/src/uts46.rs | 76 +- vendor/idna/tests/punycode.rs | 4 +- vendor/idna/tests/tests.rs | 12 +- vendor/idna/tests/uts46.rs | 13 +- vendor/itertools/.cargo-checksum.json | 2 +- vendor/itertools/CHANGELOG.md | 7 + vendor/itertools/Cargo.lock | 726 - vendor/itertools/Cargo.toml | 4 +- vendor/itertools/README.md | 2 +- vendor/itertools/benches/extra/zipslices.rs | 2 +- vendor/itertools/clippy.toml | 1 + vendor/itertools/src/adaptors/coalesce.rs | 4 +- vendor/itertools/src/adaptors/mod.rs | 14 +- vendor/itertools/src/adaptors/multi_product.rs | 4 +- .../itertools/src/combinations_with_replacement.rs | 4 +- vendor/itertools/src/concat_impl.rs | 3 +- vendor/itertools/src/duplicates_impl.rs | 1 - vendor/itertools/src/either_or_both.rs | 49 + vendor/itertools/src/exactly_one_err.rs | 4 +- vendor/itertools/src/extrema_set.rs | 48 + vendor/itertools/src/flatten_ok.rs | 33 +- vendor/itertools/src/free.rs | 26 +- vendor/itertools/src/groupbylazy.rs | 12 +- vendor/itertools/src/grouping_map.rs | 7 +- vendor/itertools/src/impl_macros.rs | 1 + vendor/itertools/src/intersperse.rs | 5 +- vendor/itertools/src/kmerge_impl.rs | 8 +- vendor/itertools/src/lazy_buffer.rs | 20 +- vendor/itertools/src/lib.rs | 230 +- vendor/itertools/src/merge_join.rs | 4 +- vendor/itertools/src/multipeek_impl.rs | 10 +- vendor/itertools/src/pad_tail.rs | 2 +- vendor/itertools/src/peeking_take_while.rs | 2 +- vendor/itertools/src/permutations.rs | 7 +- vendor/itertools/src/rciter_impl.rs | 1 - vendor/itertools/src/size_hint.rs | 16 +- vendor/itertools/src/tuple_impl.rs | 2 +- vendor/itertools/src/unique_impl.rs | 7 +- vendor/itertools/src/unziptuple.rs | 8 +- vendor/itertools/src/ziptuple.rs | 1 + vendor/itertools/tests/adaptors_no_collect.rs | 11 +- vendor/itertools/tests/quick.rs | 116 +- vendor/itertools/tests/specializations.rs | 4 +- vendor/itertools/tests/test_core.rs | 15 +- vendor/itertools/tests/test_std.rs | 80 +- vendor/itertools/tests/zip.rs | 8 +- vendor/itoa/.cargo-checksum.json | 2 +- vendor/itoa/Cargo.toml | 6 +- vendor/itoa/src/lib.rs | 8 +- vendor/itoa/src/udiv128.rs | 5 + vendor/libc/.cargo-checksum.json | 2 +- vendor/libc/Cargo.toml | 2 +- vendor/libc/src/fuchsia/mod.rs | 27 +- vendor/libc/src/unix/bsd/apple/mod.rs | 345 +- .../libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs | 11 + .../unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs | 8 + .../unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs | 13 + .../unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs | 13 + .../unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs | 13 + .../libc/src/unix/bsd/freebsdlike/freebsd/mod.rs | 80 +- vendor/libc/src/unix/bsd/freebsdlike/mod.rs | 13 + vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs | 37 + vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs | 16 + vendor/libc/src/unix/linux_like/android/mod.rs | 26 +- vendor/libc/src/unix/linux_like/emscripten/mod.rs | 4 +- .../src/unix/linux_like/linux/arch/generic/mod.rs | 7 + .../src/unix/linux_like/linux/gnu/b32/arm/mod.rs | 8 + .../src/unix/linux_like/linux/gnu/b32/mips/mod.rs | 8 + .../src/unix/linux_like/linux/gnu/b32/powerpc.rs | 8 + .../unix/linux_like/linux/gnu/b32/riscv32/mod.rs | 8 + .../src/unix/linux_like/linux/gnu/b32/sparc/mod.rs | 8 + .../src/unix/linux_like/linux/gnu/b32/x86/mod.rs | 8 + .../unix/linux_like/linux/gnu/b64/aarch64/mod.rs | 8 + .../unix/linux_like/linux/gnu/b64/mips64/mod.rs | 8 + .../unix/linux_like/linux/gnu/b64/powerpc64/mod.rs | 8 + .../unix/linux_like/linux/gnu/b64/riscv64/mod.rs | 8 + .../src/unix/linux_like/linux/gnu/b64/s390x.rs | 8 + .../unix/linux_like/linux/gnu/b64/sparc64/mod.rs | 8 + .../unix/linux_like/linux/gnu/b64/x86_64/mod.rs | 9 + .../linux_like/linux/gnu/b64/x86_64/not_x32.rs | 8 + .../unix/linux_like/linux/gnu/b64/x86_64/x32.rs | 8 + vendor/libc/src/unix/linux_like/linux/gnu/mod.rs | 22 + vendor/libc/src/unix/linux_like/linux/mod.rs | 314 +- .../src/unix/linux_like/linux/musl/b32/arm/mod.rs | 8 + .../src/unix/linux_like/linux/musl/b32/mips/mod.rs | 8 + .../libc/src/unix/linux_like/linux/musl/b32/mod.rs | 1 + .../src/unix/linux_like/linux/musl/b32/powerpc.rs | 8 + .../unix/linux_like/linux/musl/b32/riscv32/mod.rs | 1 + .../src/unix/linux_like/linux/musl/b32/x86/mod.rs | 8 + .../unix/linux_like/linux/musl/b64/aarch64/mod.rs | 9 + .../src/unix/linux_like/linux/musl/b64/mips64.rs | 9 + .../unix/linux_like/linux/musl/b64/powerpc64.rs | 9 + .../unix/linux_like/linux/musl/b64/riscv64/mod.rs | 1 + .../src/unix/linux_like/linux/musl/b64/s390x.rs | 9 + .../unix/linux_like/linux/musl/b64/x86_64/mod.rs | 9 + vendor/libc/src/unix/linux_like/linux/musl/mod.rs | 3 + .../src/unix/linux_like/linux/uclibc/arm/mod.rs | 1 + .../src/unix/linux_like/linux/uclibc/x86_64/mod.rs | 1 + vendor/libc/src/unix/linux_like/mod.rs | 2 + vendor/libc/src/unix/newlib/mod.rs | 2 +- vendor/libc/src/unix/solarish/illumos.rs | 5 + vendor/libc/src/unix/solarish/mod.rs | 16 +- vendor/libc/src/unix/solarish/solaris.rs | 11 +- vendor/libc/src/unix/solarish/x86_64.rs | 31 + vendor/lock_api/.cargo-checksum.json | 2 +- vendor/lock_api/Cargo.toml | 2 +- vendor/lock_api/src/mutex.rs | 29 +- vendor/lock_api/src/remutex.rs | 8 +- vendor/lock_api/src/rwlock.rs | 10 +- vendor/matches/.cargo-checksum.json | 1 - vendor/matches/Cargo.toml | 24 - vendor/matches/LICENSE | 25 - vendor/matches/lib.rs | 128 - vendor/matches/tests/macro_use_one.rs | 11 - vendor/matches/tests/use_star.rs | 10 - vendor/miniz_oxide/.cargo-checksum.json | 2 +- vendor/miniz_oxide/Cargo.toml | 27 +- vendor/miniz_oxide/src/inflate/mod.rs | 12 +- vendor/once_cell/.cargo-checksum.json | 2 +- vendor/once_cell/CHANGELOG.md | 12 + vendor/once_cell/Cargo.lock | 62 +- vendor/once_cell/Cargo.toml | 6 +- vendor/once_cell/examples/lazy_static.rs | 2 +- vendor/once_cell/src/lib.rs | 80 +- vendor/once_cell/tests/it.rs | 35 + vendor/percent-encoding/.cargo-checksum.json | 2 +- vendor/percent-encoding/Cargo.toml | 21 +- vendor/percent-encoding/LICENSE-MIT | 2 +- vendor/percent-encoding/lib.rs | 442 - vendor/percent-encoding/src/lib.rs | 468 + vendor/proc-macro2/.cargo-checksum.json | 2 +- vendor/proc-macro2/Cargo.toml | 2 +- vendor/proc-macro2/build.rs | 5 +- vendor/proc-macro2/src/fallback.rs | 28 +- vendor/proc-macro2/src/lib.rs | 25 +- vendor/proc-macro2/src/parse.rs | 13 +- vendor/proc-macro2/src/wrapper.rs | 16 + vendor/proc-macro2/tests/test.rs | 13 + vendor/rowan/.cargo-checksum.json | 2 +- vendor/rowan/Cargo.lock | 10 +- vendor/rowan/Cargo.toml | 3 +- vendor/rowan/src/cursor.rs | 2 +- vendor/rustc_tools_util/.cargo-checksum.json | 1 + vendor/rustc_tools_util/Cargo.toml | 32 + vendor/rustc_tools_util/LICENSE-APACHE | 201 + vendor/rustc_tools_util/LICENSE-MIT | 27 + vendor/rustc_tools_util/README.md | 62 + vendor/rustc_tools_util/src/lib.rs | 162 + vendor/semver/.cargo-checksum.json | 2 +- vendor/semver/Cargo.toml | 2 +- vendor/semver/src/backport.rs | 9 + vendor/semver/src/identifier.rs | 8 +- vendor/semver/src/lib.rs | 2 +- vendor/serde/.cargo-checksum.json | 2 +- vendor/serde/Cargo.toml | 5 +- vendor/serde/src/de/ignored_any.rs | 2 +- vendor/serde/src/de/impls.rs | 8 +- vendor/serde/src/de/mod.rs | 10 +- vendor/serde/src/de/value.rs | 37 +- vendor/serde/src/lib.rs | 17 +- vendor/serde/src/private/de.rs | 11 + vendor/serde/src/private/ser.rs | 6 +- vendor/serde/src/ser/impls.rs | 15 +- vendor/serde_derive/.cargo-checksum.json | 2 +- vendor/serde_derive/Cargo.toml | 3 +- vendor/serde_derive/src/lib.rs | 2 +- vendor/serde_json/.cargo-checksum.json | 2 +- vendor/serde_json/Cargo.toml | 2 +- vendor/serde_json/src/lib.rs | 2 +- vendor/serde_json/src/number.rs | 13 +- vendor/serde_json/src/value/ser.rs | 10 +- vendor/serde_json/tests/test.rs | 6 +- vendor/smallvec/.cargo-checksum.json | 2 +- vendor/smallvec/Cargo.toml | 31 +- vendor/smallvec/debug_metadata/README.md | 111 + vendor/smallvec/debug_metadata/smallvec.natvis | 35 + vendor/smallvec/scripts/run_miri.sh | 3 + vendor/smallvec/src/lib.rs | 7 + vendor/smallvec/tests/debugger_visualizer.rs | 68 + vendor/syn/.cargo-checksum.json | 2 +- vendor/syn/Cargo.toml | 4 +- vendor/syn/benches/file.rs | 2 +- vendor/syn/benches/rust.rs | 11 +- vendor/syn/src/buffer.rs | 215 +- vendor/syn/src/expr.rs | 21 +- vendor/syn/src/gen/clone.rs | 2 +- vendor/syn/src/gen/debug.rs | 10 +- vendor/syn/src/gen/eq.rs | 6 +- vendor/syn/src/gen/fold.rs | 6 +- vendor/syn/src/gen/hash.rs | 6 +- vendor/syn/src/gen/visit.rs | 6 +- vendor/syn/src/gen/visit_mut.rs | 6 +- vendor/syn/src/item.rs | 14 +- vendor/syn/src/lib.rs | 11 +- vendor/syn/src/lit.rs | 2 +- vendor/syn/src/parse_macro_input.rs | 4 +- vendor/syn/src/pat.rs | 35 +- vendor/syn/src/path.rs | 46 +- vendor/syn/src/stmt.rs | 6 +- vendor/syn/src/ty.rs | 53 +- vendor/syn/tests/.gitignore | 1 - vendor/syn/tests/common/eq.rs | 64 +- vendor/syn/tests/debug/gen.rs | 12 +- vendor/syn/tests/regression/issue1108.rs | 2 +- vendor/syn/tests/repo/mod.rs | 77 +- vendor/syn/tests/test_parse_stream.rs | 8 +- vendor/syn/tests/test_precedence.rs | 19 +- vendor/syn/tests/test_size.rs | 8 +- vendor/thiserror-impl/.cargo-checksum.json | 2 +- vendor/thiserror-impl/Cargo.toml | 2 +- vendor/thiserror-impl/src/expand.rs | 18 +- vendor/thiserror/.cargo-checksum.json | 2 +- vendor/thiserror/Cargo.toml | 6 +- vendor/thiserror/README.md | 30 +- vendor/thiserror/build.rs | 66 + vendor/thiserror/src/aserror.rs | 9 +- vendor/thiserror/src/lib.rs | 39 +- vendor/thiserror/src/provide.rs | 15 + vendor/thiserror/tests/test_backtrace.rs | 46 + vendor/thiserror/tests/test_deprecated.rs | 10 + .../tests/ui/source-enum-not-error.stderr | 6 +- .../tests/ui/source-struct-not-error.stderr | 4 +- vendor/tracing-attributes/.cargo-checksum.json | 2 +- vendor/tracing-attributes/CHANGELOG.md | 21 + vendor/tracing-attributes/Cargo.toml | 18 +- vendor/tracing-attributes/README.md | 4 +- vendor/tracing-attributes/src/expand.rs | 118 +- vendor/tracing-attributes/src/lib.rs | 60 +- vendor/tracing-attributes/tests/async_fn.rs | 13 + vendor/tracing-attributes/tests/instrument.rs | 9 + vendor/tracing-attributes/tests/ui.rs | 7 + .../tests/ui/async_instrument.rs | 46 + .../tests/ui/async_instrument.stderr | 98 + vendor/tracing-core/.cargo-checksum.json | 2 +- vendor/tracing-core/CHANGELOG.md | 18 + vendor/tracing-core/Cargo.toml | 2 +- vendor/tracing-core/README.md | 26 +- vendor/tracing-core/src/callsite.rs | 1 + vendor/tracing-core/src/dispatcher.rs | 113 +- vendor/tracing-core/src/subscriber.rs | 27 +- .../tracing-subscriber-0.3.3/.cargo-checksum.json | 1 + vendor/tracing-subscriber-0.3.3/CHANGELOG.md | 902 + vendor/tracing-subscriber-0.3.3/Cargo.toml | 150 + vendor/tracing-subscriber-0.3.3/LICENSE | 25 + vendor/tracing-subscriber-0.3.3/README.md | 61 + vendor/tracing-subscriber-0.3.3/benches/enter.rs | 64 + vendor/tracing-subscriber-0.3.3/benches/filter.rs | 308 + .../tracing-subscriber-0.3.3/benches/filter_log.rs | 315 + vendor/tracing-subscriber-0.3.3/benches/fmt.rs | 331 + .../benches/support/mod.rs | 49 + vendor/tracing-subscriber-0.3.3/src/field/debug.rs | 111 + .../src/field/delimited.rs | 184 + .../tracing-subscriber-0.3.3/src/field/display.rs | 117 + vendor/tracing-subscriber-0.3.3/src/field/mod.rs | 366 + .../src/filter/directive.rs | 424 + .../src/filter/env/directive.rs | 846 + .../src/filter/env/field.rs | 416 + .../tracing-subscriber-0.3.3/src/filter/env/mod.rs | 738 + .../src/filter/filter_fn.rs | 749 + .../src/filter/layer_filters.rs | 830 + .../tracing-subscriber-0.3.3/src/filter/level.rs | 27 + vendor/tracing-subscriber-0.3.3/src/filter/mod.rs | 66 + .../tracing-subscriber-0.3.3/src/filter/targets.rs | 681 + .../tracing-subscriber-0.3.3/src/fmt/fmt_layer.rs | 1205 ++ .../src/fmt/format/json.rs | 750 + .../tracing-subscriber-0.3.3/src/fmt/format/mod.rs | 1798 ++ .../src/fmt/format/pretty.rs | 415 + vendor/tracing-subscriber-0.3.3/src/fmt/mod.rs | 1275 ++ .../src/fmt/time/datetime.rs | 410 + .../tracing-subscriber-0.3.3/src/fmt/time/mod.rs | 134 + .../src/fmt/time/time_crate.rs | 276 + vendor/tracing-subscriber-0.3.3/src/fmt/writer.rs | 1464 ++ .../tracing-subscriber-0.3.3/src/layer/context.rs | 434 + .../tracing-subscriber-0.3.3/src/layer/layered.rs | 471 + vendor/tracing-subscriber-0.3.3/src/layer/mod.rs | 1285 ++ vendor/tracing-subscriber-0.3.3/src/layer/tests.rs | 308 + vendor/tracing-subscriber-0.3.3/src/lib.rs | 218 + vendor/tracing-subscriber-0.3.3/src/macros.rs | 28 + vendor/tracing-subscriber-0.3.3/src/prelude.rs | 19 + .../src/registry/extensions.rs | 274 + .../tracing-subscriber-0.3.3/src/registry/mod.rs | 604 + .../src/registry/sharded.rs | 904 + .../tracing-subscriber-0.3.3/src/registry/stack.rs | 77 + vendor/tracing-subscriber-0.3.3/src/reload.rs | 237 + vendor/tracing-subscriber-0.3.3/src/sync.rs | 57 + vendor/tracing-subscriber-0.3.3/src/util.rs | 153 + ...cached_layer_filters_dont_break_other_layers.rs | 123 + .../tests/duplicate_spans.rs | 48 + .../tracing-subscriber-0.3.3/tests/field_filter.rs | 115 + vendor/tracing-subscriber-0.3.3/tests/filter.rs | 187 + .../tracing-subscriber-0.3.3/tests/filter_log.rs | 63 + .../tests/fmt_max_level_hint.rs | 10 + ...hinted_layer_filters_dont_break_other_layers.rs | 131 + .../tests/layer_filter_interests_are_cached.rs | 69 + .../tests/layer_filters/boxed.rs | 42 + .../tests/layer_filters/downcast_raw.rs | 68 + .../tests/layer_filters/filter_scopes.rs | 131 + .../tests/layer_filters/main.rs | 188 + .../tests/layer_filters/targets.rs | 59 + .../tests/layer_filters/trees.rs | 146 + .../multiple_layer_filter_interests_cached.rs | 131 + .../tests/registry_max_level_hint.rs | 11 + .../tests/registry_with_subscriber.rs | 25 + vendor/tracing-subscriber-0.3.3/tests/reload.rs | 81 + .../tests/same_len_filters.rs | 81 + vendor/tracing-subscriber-0.3.3/tests/support.rs | 412 + ...hinted_layer_filters_dont_break_other_layers.rs | 123 + vendor/tracing-subscriber-0.3.3/tests/utils.rs | 39 + vendor/tracing-subscriber/.cargo-checksum.json | 1 - vendor/tracing-subscriber/CHANGELOG.md | 1225 -- vendor/tracing-subscriber/Cargo.toml | 232 - vendor/tracing-subscriber/LICENSE | 25 - vendor/tracing-subscriber/README.md | 61 - vendor/tracing-subscriber/benches/enter.rs | 64 - vendor/tracing-subscriber/benches/filter.rs | 308 - vendor/tracing-subscriber/benches/filter_log.rs | 315 - vendor/tracing-subscriber/benches/fmt.rs | 331 - vendor/tracing-subscriber/benches/support/mod.rs | 49 - vendor/tracing-subscriber/src/field/debug.rs | 111 - vendor/tracing-subscriber/src/field/delimited.rs | 184 - vendor/tracing-subscriber/src/field/display.rs | 117 - vendor/tracing-subscriber/src/field/mod.rs | 366 - vendor/tracing-subscriber/src/filter/directive.rs | 456 - .../tracing-subscriber/src/filter/env/builder.rs | 324 - .../tracing-subscriber/src/filter/env/directive.rs | 860 - vendor/tracing-subscriber/src/filter/env/field.rs | 626 - vendor/tracing-subscriber/src/filter/env/mod.rs | 991 -- vendor/tracing-subscriber/src/filter/filter_fn.rs | 749 - .../src/filter/layer_filters/combinator.rs | 469 - .../src/filter/layer_filters/mod.rs | 1135 -- vendor/tracing-subscriber/src/filter/level.rs | 27 - vendor/tracing-subscriber/src/filter/mod.rs | 66 - vendor/tracing-subscriber/src/filter/targets.rs | 710 - vendor/tracing-subscriber/src/fmt/fmt_layer.rs | 1368 -- vendor/tracing-subscriber/src/fmt/format/json.rs | 885 - vendor/tracing-subscriber/src/fmt/format/mod.rs | 2161 --- vendor/tracing-subscriber/src/fmt/format/pretty.rs | 511 - vendor/tracing-subscriber/src/fmt/mod.rs | 1324 -- vendor/tracing-subscriber/src/fmt/time/datetime.rs | 410 - vendor/tracing-subscriber/src/fmt/time/mod.rs | 138 - .../tracing-subscriber/src/fmt/time/time_crate.rs | 470 - vendor/tracing-subscriber/src/fmt/writer.rs | 1464 -- vendor/tracing-subscriber/src/layer/context.rs | 434 - vendor/tracing-subscriber/src/layer/layered.rs | 520 - vendor/tracing-subscriber/src/layer/mod.rs | 1798 -- vendor/tracing-subscriber/src/layer/tests.rs | 308 - vendor/tracing-subscriber/src/lib.rs | 252 - vendor/tracing-subscriber/src/macros.rs | 28 - vendor/tracing-subscriber/src/prelude.rs | 19 - .../tracing-subscriber/src/registry/extensions.rs | 274 - vendor/tracing-subscriber/src/registry/mod.rs | 600 - vendor/tracing-subscriber/src/registry/sharded.rs | 901 - vendor/tracing-subscriber/src/registry/stack.rs | 77 - vendor/tracing-subscriber/src/reload.rs | 360 - vendor/tracing-subscriber/src/sync.rs | 57 - vendor/tracing-subscriber/src/util.rs | 153 - ...cached_layer_filters_dont_break_other_layers.rs | 123 - vendor/tracing-subscriber/tests/duplicate_spans.rs | 47 - vendor/tracing-subscriber/tests/env_filter/main.rs | 547 - .../tests/env_filter/per_layer.rs | 305 - vendor/tracing-subscriber/tests/event_enabling.rs | 81 - vendor/tracing-subscriber/tests/field_filter.rs | 115 - vendor/tracing-subscriber/tests/filter_log.rs | 63 - .../tracing-subscriber/tests/fmt_max_level_hint.rs | 10 - ...hinted_layer_filters_dont_break_other_layers.rs | 131 - .../tests/layer_filter_interests_are_cached.rs | 69 - .../tests/layer_filters/boxed.rs | 42 - .../tests/layer_filters/combinators.rs | 42 - .../tests/layer_filters/downcast_raw.rs | 68 - .../tests/layer_filters/filter_scopes.rs | 131 - .../tracing-subscriber/tests/layer_filters/main.rs | 189 - .../tests/layer_filters/targets.rs | 59 - .../tests/layer_filters/trees.rs | 146 - .../tracing-subscriber/tests/layer_filters/vec.rs | 120 - .../multiple_layer_filter_interests_cached.rs | 131 - vendor/tracing-subscriber/tests/option.rs | 41 - .../tests/registry_max_level_hint.rs | 11 - .../tests/registry_with_subscriber.rs | 25 - vendor/tracing-subscriber/tests/reload.rs | 155 - .../tracing-subscriber/tests/same_len_filters.rs | 81 - vendor/tracing-subscriber/tests/support.rs | 407 - ...hinted_layer_filters_dont_break_other_layers.rs | 123 - vendor/tracing-subscriber/tests/utils.rs | 39 - vendor/tracing-subscriber/tests/vec.rs | 19 - .../vec_subscriber_filter_interests_cached.rs | 117 - vendor/tracing/.cargo-checksum.json | 2 +- vendor/tracing/CHANGELOG.md | 52 + vendor/tracing/Cargo.toml | 6 +- vendor/tracing/README.md | 4 +- vendor/tracing/src/dispatcher.rs | 2 +- vendor/tracing/src/lib.rs | 10 +- vendor/tracing/src/macros.rs | 38 +- vendor/unicode-ident/.cargo-checksum.json | 2 +- vendor/unicode-ident/Cargo.toml | 18 +- vendor/unicode-ident/LICENSE-UNICODE | 46 + vendor/unicode-ident/README.md | 30 +- vendor/unicode-ident/src/tables.rs | 111 +- vendor/unicode-ident/tests/fst/xid_continue.fst | Bin 70255 -> 72750 bytes vendor/unicode-ident/tests/fst/xid_start.fst | Bin 62642 -> 64999 bytes vendor/unicode-ident/tests/static_size.rs | 8 +- vendor/unicode-ident/tests/trie/trie.rs | 222 +- vendor/unicode-normalization/.cargo-checksum.json | 2 +- vendor/unicode-normalization/Cargo.toml | 2 +- vendor/unicode-normalization/README.md | 2 +- vendor/unicode-normalization/scripts/unicode.py | 2 +- vendor/unicode-normalization/src/tables.rs | 16705 ++++++++++--------- vendor/unicode-script/.cargo-checksum.json | 2 +- vendor/unicode-script/Cargo.toml | 36 +- vendor/unicode-script/LICENSE-APACHE | 201 + vendor/unicode-script/LICENSE-MIT | 27 + vendor/unicode-script/README.md | 4 +- vendor/unicode-script/scripts/unicode.py | 4 +- vendor/unicode-script/src/lib.rs | 10 +- vendor/unicode-script/src/tables.rs | 2275 +-- vendor/unicode-security/.cargo-checksum.json | 2 +- vendor/unicode-security/Cargo.toml | 39 +- vendor/unicode-security/README.md | 4 +- vendor/unicode-security/scripts/unicode.py | 6 +- vendor/unicode-security/src/restriction_level.rs | 2 +- vendor/unicode-security/src/tables.rs | 2118 +-- vendor/unicode-segmentation/.cargo-checksum.json | 2 +- vendor/unicode-segmentation/Cargo.toml | 29 +- vendor/unicode-segmentation/scripts/unicode.py | 2 +- vendor/unicode-segmentation/src/tables.rs | 2372 +-- vendor/unicode-segmentation/src/testdata.rs | 6 +- vendor/unicode-width/.cargo-checksum.json | 2 +- vendor/unicode-width/Cargo.toml | 30 +- vendor/unicode-width/scripts/unicode.py | 748 +- vendor/unicode-width/src/tables.rs | 775 +- vendor/unicode-width/src/tests.rs | 20 +- vendor/unicode-xid/.cargo-checksum.json | 2 +- vendor/unicode-xid/Cargo.toml | 2 +- vendor/unicode-xid/README.md | 9 + vendor/unicode-xid/src/tables.rs | 45 +- vendor/url/.cargo-checksum.json | 2 +- vendor/url/Cargo.toml | 63 +- vendor/url/LICENSE-MIT | 2 +- vendor/url/README.md | 14 + vendor/url/src/host.rs | 86 +- vendor/url/src/lib.rs | 82 +- vendor/url/src/origin.rs | 3 +- vendor/url/src/parser.rs | 37 +- vendor/url/src/quirks.rs | 59 +- vendor/url/tests/data.rs | 79 +- vendor/url/tests/debugger_visualizer.rs | 102 + vendor/url/tests/unit.rs | 54 +- vendor/url/tests/urltestdata.json | 3661 ++-- vendor/xflags-macros/.cargo-checksum.json | 2 +- vendor/xflags-macros/Cargo.toml | 6 +- vendor/xflags-macros/src/ast.rs | 13 + vendor/xflags-macros/src/emit.rs | 350 +- vendor/xflags-macros/src/lib.rs | 26 +- vendor/xflags-macros/src/parse.rs | 166 +- vendor/xflags-macros/src/update.rs | 3 +- vendor/xflags-macros/tests/data/help.rs | 26 + vendor/xflags-macros/tests/data/repeated_pos.rs | 8 + vendor/xflags-macros/tests/data/smoke.rs | 14 + vendor/xflags-macros/tests/data/subcommands.rs | 19 + vendor/xflags-macros/tests/it/help.rs | 84 +- vendor/xflags-macros/tests/it/main.rs | 36 +- vendor/xflags-macros/tests/it/repeated_pos.rs | 64 +- vendor/xflags-macros/tests/it/smoke.rs | 61 +- vendor/xflags-macros/tests/it/src/help.rs | 25 - vendor/xflags-macros/tests/it/src/repeated_pos.rs | 9 - vendor/xflags-macros/tests/it/src/smoke.rs | 15 - vendor/xflags-macros/tests/it/src/subcommands.rs | 20 - vendor/xflags-macros/tests/it/subcommands.rs | 174 +- vendor/xflags/.cargo-checksum.json | 2 +- vendor/xflags/Cargo.lock | 6 +- vendor/xflags/Cargo.toml | 9 +- vendor/xflags/LICENSE-APACHE | 201 - vendor/xflags/LICENSE-MIT | 23 - vendor/xflags/README.md | 49 - vendor/xflags/examples/hello-generated.rs | 13 +- vendor/xflags/examples/hello.rs | 3 +- vendor/xflags/examples/immediate-mode.rs | 16 + vendor/xflags/examples/longer.rs | 7 +- vendor/xflags/examples/non-utf8.rs | 3 +- vendor/xflags/src/lib.rs | 172 +- vendor/xflags/src/rt.rs | 14 +- 871 files changed, 81808 insertions(+), 81306 deletions(-) create mode 100644 vendor/clap-3.2.20/.cargo-checksum.json create mode 100644 vendor/clap-3.2.20/Cargo.lock create mode 100644 vendor/clap-3.2.20/Cargo.toml create mode 100644 vendor/clap-3.2.20/LICENSE-APACHE create mode 100644 vendor/clap-3.2.20/LICENSE-MIT create mode 100644 vendor/clap-3.2.20/README.md create mode 100644 vendor/clap-3.2.20/examples/cargo-example-derive.md create mode 100644 vendor/clap-3.2.20/examples/cargo-example-derive.rs create mode 100644 vendor/clap-3.2.20/examples/cargo-example.md create mode 100644 vendor/clap-3.2.20/examples/cargo-example.rs create mode 100644 vendor/clap-3.2.20/examples/demo.md create mode 100644 vendor/clap-3.2.20/examples/demo.rs create mode 100644 vendor/clap-3.2.20/examples/derive_ref/augment_args.rs create mode 100644 vendor/clap-3.2.20/examples/derive_ref/augment_subcommands.rs create mode 100644 vendor/clap-3.2.20/examples/derive_ref/custom-bool.md create mode 100644 vendor/clap-3.2.20/examples/derive_ref/custom-bool.rs create mode 100644 vendor/clap-3.2.20/examples/derive_ref/flatten_hand_args.rs create mode 100644 vendor/clap-3.2.20/examples/derive_ref/hand_subcommand.rs create mode 100644 vendor/clap-3.2.20/examples/derive_ref/interop_tests.md create mode 100644 vendor/clap-3.2.20/examples/escaped-positional-derive.md create mode 100644 vendor/clap-3.2.20/examples/escaped-positional-derive.rs create mode 100644 vendor/clap-3.2.20/examples/escaped-positional.md create mode 100644 vendor/clap-3.2.20/examples/escaped-positional.rs create mode 100644 vendor/clap-3.2.20/examples/git-derive.md create mode 100644 vendor/clap-3.2.20/examples/git-derive.rs create mode 100644 vendor/clap-3.2.20/examples/git.md create mode 100644 vendor/clap-3.2.20/examples/git.rs create mode 100644 vendor/clap-3.2.20/examples/multicall-busybox.md create mode 100644 vendor/clap-3.2.20/examples/multicall-busybox.rs create mode 100644 vendor/clap-3.2.20/examples/multicall-hostname.md create mode 100644 vendor/clap-3.2.20/examples/multicall-hostname.rs create mode 100644 vendor/clap-3.2.20/examples/pacman.md create mode 100644 vendor/clap-3.2.20/examples/pacman.rs create mode 100644 vendor/clap-3.2.20/examples/repl.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/01_quick.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/01_quick.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/02_apps.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/02_apps.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/02_crate.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/02_crate.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_builder/05_01_assert.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/01_quick.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/01_quick.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/02_apps.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/02_apps.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/02_crate.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/02_crate.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands_alt.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.md create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.rs create mode 100644 vendor/clap-3.2.20/examples/tutorial_derive/05_01_assert.rs create mode 100644 vendor/clap-3.2.20/examples/typed-derive.md create mode 100644 vendor/clap-3.2.20/examples/typed-derive.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/cargo_example.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/cargo_example_derive create mode 100644 vendor/clap-3.2.20/src/_cookbook/cargo_example_derive.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/escaped_positional.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/escaped_positional_derive.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/git.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/git_derive.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/mod.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/multicall_busybox.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/multicall_hostname.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/pacman.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/repl.rs create mode 100644 vendor/clap-3.2.20/src/_cookbook/typed_derive.rs create mode 100644 vendor/clap-3.2.20/src/_derive/_tutorial.rs create mode 100644 vendor/clap-3.2.20/src/_derive/mod.rs create mode 100644 vendor/clap-3.2.20/src/_faq.rs create mode 100644 vendor/clap-3.2.20/src/_features.rs create mode 100644 vendor/clap-3.2.20/src/_tutorial.rs create mode 100644 vendor/clap-3.2.20/src/bin/stdio-fixture.rs create mode 100644 vendor/clap-3.2.20/src/builder/action.rs create mode 100644 vendor/clap-3.2.20/src/builder/app_settings.rs create mode 100644 vendor/clap-3.2.20/src/builder/arg.rs create mode 100644 vendor/clap-3.2.20/src/builder/arg_group.rs create mode 100644 vendor/clap-3.2.20/src/builder/arg_predicate.rs create mode 100644 vendor/clap-3.2.20/src/builder/arg_settings.rs create mode 100644 vendor/clap-3.2.20/src/builder/command.rs create mode 100644 vendor/clap-3.2.20/src/builder/debug_asserts.rs create mode 100644 vendor/clap-3.2.20/src/builder/macros.rs create mode 100644 vendor/clap-3.2.20/src/builder/mod.rs create mode 100644 vendor/clap-3.2.20/src/builder/possible_value.rs create mode 100644 vendor/clap-3.2.20/src/builder/regex.rs create mode 100644 vendor/clap-3.2.20/src/builder/tests.rs create mode 100644 vendor/clap-3.2.20/src/builder/usage_parser.rs create mode 100644 vendor/clap-3.2.20/src/builder/value_hint.rs create mode 100644 vendor/clap-3.2.20/src/builder/value_parser.rs create mode 100644 vendor/clap-3.2.20/src/derive.rs create mode 100644 vendor/clap-3.2.20/src/error/context.rs create mode 100644 vendor/clap-3.2.20/src/error/kind.rs create mode 100644 vendor/clap-3.2.20/src/error/mod.rs create mode 100644 vendor/clap-3.2.20/src/lib.rs create mode 100644 vendor/clap-3.2.20/src/macros.rs create mode 100644 vendor/clap-3.2.20/src/mkeymap.rs create mode 100644 vendor/clap-3.2.20/src/output/fmt.rs create mode 100644 vendor/clap-3.2.20/src/output/help.rs create mode 100644 vendor/clap-3.2.20/src/output/mod.rs create mode 100644 vendor/clap-3.2.20/src/output/usage.rs create mode 100644 vendor/clap-3.2.20/src/parser/arg_matcher.rs create mode 100644 vendor/clap-3.2.20/src/parser/error.rs create mode 100644 vendor/clap-3.2.20/src/parser/features/mod.rs create mode 100644 vendor/clap-3.2.20/src/parser/features/suggestions.rs create mode 100644 vendor/clap-3.2.20/src/parser/matches/any_value.rs create mode 100644 vendor/clap-3.2.20/src/parser/matches/arg_matches.rs create mode 100644 vendor/clap-3.2.20/src/parser/matches/matched_arg.rs create mode 100644 vendor/clap-3.2.20/src/parser/matches/mod.rs create mode 100644 vendor/clap-3.2.20/src/parser/matches/value_source.rs create mode 100644 vendor/clap-3.2.20/src/parser/mod.rs create mode 100644 vendor/clap-3.2.20/src/parser/parser.rs create mode 100644 vendor/clap-3.2.20/src/parser/validator.rs create mode 100644 vendor/clap-3.2.20/src/util/color.rs create mode 100644 vendor/clap-3.2.20/src/util/fnv.rs create mode 100644 vendor/clap-3.2.20/src/util/graph.rs create mode 100644 vendor/clap-3.2.20/src/util/id.rs create mode 100644 vendor/clap-3.2.20/src/util/mod.rs create mode 100644 vendor/clap-3.2.20/src/util/str_to_bool.rs delete mode 100644 vendor/clap/.cargo-checksum.json delete mode 100644 vendor/clap/Cargo.lock delete mode 100644 vendor/clap/Cargo.toml delete mode 100644 vendor/clap/LICENSE-APACHE delete mode 100644 vendor/clap/LICENSE-MIT delete mode 100644 vendor/clap/README.md delete mode 100644 vendor/clap/examples/cargo-example-derive.md delete mode 100644 vendor/clap/examples/cargo-example-derive.rs delete mode 100644 vendor/clap/examples/cargo-example.md delete mode 100644 vendor/clap/examples/cargo-example.rs delete mode 100644 vendor/clap/examples/demo.md delete mode 100644 vendor/clap/examples/demo.rs delete mode 100644 vendor/clap/examples/derive_ref/augment_args.rs delete mode 100644 vendor/clap/examples/derive_ref/augment_subcommands.rs delete mode 100644 vendor/clap/examples/derive_ref/custom-bool.md delete mode 100644 vendor/clap/examples/derive_ref/custom-bool.rs delete mode 100644 vendor/clap/examples/derive_ref/flatten_hand_args.rs delete mode 100644 vendor/clap/examples/derive_ref/hand_subcommand.rs delete mode 100644 vendor/clap/examples/derive_ref/interop_tests.md delete mode 100644 vendor/clap/examples/escaped-positional-derive.md delete mode 100644 vendor/clap/examples/escaped-positional-derive.rs delete mode 100644 vendor/clap/examples/escaped-positional.md delete mode 100644 vendor/clap/examples/escaped-positional.rs delete mode 100644 vendor/clap/examples/git-derive.md delete mode 100644 vendor/clap/examples/git-derive.rs delete mode 100644 vendor/clap/examples/git.md delete mode 100644 vendor/clap/examples/git.rs delete mode 100644 vendor/clap/examples/multicall-busybox.md delete mode 100644 vendor/clap/examples/multicall-busybox.rs delete mode 100644 vendor/clap/examples/multicall-hostname.md delete mode 100644 vendor/clap/examples/multicall-hostname.rs delete mode 100644 vendor/clap/examples/pacman.md delete mode 100644 vendor/clap/examples/pacman.rs delete mode 100644 vendor/clap/examples/repl.rs delete mode 100644 vendor/clap/examples/tutorial_builder/01_quick.md delete mode 100644 vendor/clap/examples/tutorial_builder/01_quick.rs delete mode 100644 vendor/clap/examples/tutorial_builder/02_app_settings.md delete mode 100644 vendor/clap/examples/tutorial_builder/02_app_settings.rs delete mode 100644 vendor/clap/examples/tutorial_builder/02_apps.md delete mode 100644 vendor/clap/examples/tutorial_builder/02_apps.rs delete mode 100644 vendor/clap/examples/tutorial_builder/02_crate.md delete mode 100644 vendor/clap/examples/tutorial_builder/02_crate.rs delete mode 100644 vendor/clap/examples/tutorial_builder/03_01_flag_bool.md delete mode 100644 vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs delete mode 100644 vendor/clap/examples/tutorial_builder/03_01_flag_count.md delete mode 100644 vendor/clap/examples/tutorial_builder/03_01_flag_count.rs delete mode 100644 vendor/clap/examples/tutorial_builder/03_02_option.md delete mode 100644 vendor/clap/examples/tutorial_builder/03_02_option.rs delete mode 100644 vendor/clap/examples/tutorial_builder/03_03_positional.md delete mode 100644 vendor/clap/examples/tutorial_builder/03_03_positional.rs delete mode 100644 vendor/clap/examples/tutorial_builder/03_04_subcommands.md delete mode 100644 vendor/clap/examples/tutorial_builder/03_04_subcommands.rs delete mode 100644 vendor/clap/examples/tutorial_builder/03_05_default_values.md delete mode 100644 vendor/clap/examples/tutorial_builder/03_05_default_values.rs delete mode 100644 vendor/clap/examples/tutorial_builder/04_01_enum.md delete mode 100644 vendor/clap/examples/tutorial_builder/04_01_enum.rs delete mode 100644 vendor/clap/examples/tutorial_builder/04_01_possible.md delete mode 100644 vendor/clap/examples/tutorial_builder/04_01_possible.rs delete mode 100644 vendor/clap/examples/tutorial_builder/04_02_parse.md delete mode 100644 vendor/clap/examples/tutorial_builder/04_02_parse.rs delete mode 100644 vendor/clap/examples/tutorial_builder/04_02_validate.md delete mode 100644 vendor/clap/examples/tutorial_builder/04_02_validate.rs delete mode 100644 vendor/clap/examples/tutorial_builder/04_03_relations.md delete mode 100644 vendor/clap/examples/tutorial_builder/04_03_relations.rs delete mode 100644 vendor/clap/examples/tutorial_builder/04_04_custom.md delete mode 100644 vendor/clap/examples/tutorial_builder/04_04_custom.rs delete mode 100644 vendor/clap/examples/tutorial_builder/05_01_assert.rs delete mode 100644 vendor/clap/examples/tutorial_derive/01_quick.md delete mode 100644 vendor/clap/examples/tutorial_derive/01_quick.rs delete mode 100644 vendor/clap/examples/tutorial_derive/02_app_settings.md delete mode 100644 vendor/clap/examples/tutorial_derive/02_app_settings.rs delete mode 100644 vendor/clap/examples/tutorial_derive/02_apps.md delete mode 100644 vendor/clap/examples/tutorial_derive/02_apps.rs delete mode 100644 vendor/clap/examples/tutorial_derive/02_crate.md delete mode 100644 vendor/clap/examples/tutorial_derive/02_crate.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_01_flag_bool.md delete mode 100644 vendor/clap/examples/tutorial_derive/03_01_flag_bool.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_01_flag_count.md delete mode 100644 vendor/clap/examples/tutorial_derive/03_01_flag_count.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_02_option.md delete mode 100644 vendor/clap/examples/tutorial_derive/03_02_option.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_03_positional.md delete mode 100644 vendor/clap/examples/tutorial_derive/03_03_positional.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_04_subcommands.md delete mode 100644 vendor/clap/examples/tutorial_derive/03_04_subcommands.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_04_subcommands_alt.rs delete mode 100644 vendor/clap/examples/tutorial_derive/03_05_default_values.md delete mode 100644 vendor/clap/examples/tutorial_derive/03_05_default_values.rs delete mode 100644 vendor/clap/examples/tutorial_derive/04_01_enum.md delete mode 100644 vendor/clap/examples/tutorial_derive/04_01_enum.rs delete mode 100644 vendor/clap/examples/tutorial_derive/04_02_parse.md delete mode 100644 vendor/clap/examples/tutorial_derive/04_02_parse.rs delete mode 100644 vendor/clap/examples/tutorial_derive/04_02_validate.md delete mode 100644 vendor/clap/examples/tutorial_derive/04_02_validate.rs delete mode 100644 vendor/clap/examples/tutorial_derive/04_03_relations.md delete mode 100644 vendor/clap/examples/tutorial_derive/04_03_relations.rs delete mode 100644 vendor/clap/examples/tutorial_derive/04_04_custom.md delete mode 100644 vendor/clap/examples/tutorial_derive/04_04_custom.rs delete mode 100644 vendor/clap/examples/tutorial_derive/05_01_assert.rs delete mode 100644 vendor/clap/examples/typed-derive.md delete mode 100644 vendor/clap/examples/typed-derive.rs delete mode 100644 vendor/clap/src/_cookbook/cargo_example.rs delete mode 100644 vendor/clap/src/_cookbook/cargo_example_derive delete mode 100644 vendor/clap/src/_cookbook/cargo_example_derive.rs delete mode 100644 vendor/clap/src/_cookbook/escaped_positional.rs delete mode 100644 vendor/clap/src/_cookbook/escaped_positional_derive.rs delete mode 100644 vendor/clap/src/_cookbook/git.rs delete mode 100644 vendor/clap/src/_cookbook/git_derive.rs delete mode 100644 vendor/clap/src/_cookbook/mod.rs delete mode 100644 vendor/clap/src/_cookbook/multicall_busybox.rs delete mode 100644 vendor/clap/src/_cookbook/multicall_hostname.rs delete mode 100644 vendor/clap/src/_cookbook/pacman.rs delete mode 100644 vendor/clap/src/_cookbook/repl.rs delete mode 100644 vendor/clap/src/_cookbook/typed_derive.rs delete mode 100644 vendor/clap/src/_derive/_tutorial.rs delete mode 100644 vendor/clap/src/_derive/mod.rs delete mode 100644 vendor/clap/src/_faq.rs delete mode 100644 vendor/clap/src/_features.rs delete mode 100644 vendor/clap/src/_tutorial.rs delete mode 100644 vendor/clap/src/bin/stdio-fixture.rs delete mode 100644 vendor/clap/src/builder/action.rs delete mode 100644 vendor/clap/src/builder/app_settings.rs delete mode 100644 vendor/clap/src/builder/arg.rs delete mode 100644 vendor/clap/src/builder/arg_group.rs delete mode 100644 vendor/clap/src/builder/arg_predicate.rs delete mode 100644 vendor/clap/src/builder/arg_settings.rs delete mode 100644 vendor/clap/src/builder/command.rs delete mode 100644 vendor/clap/src/builder/debug_asserts.rs delete mode 100644 vendor/clap/src/builder/macros.rs delete mode 100644 vendor/clap/src/builder/mod.rs delete mode 100644 vendor/clap/src/builder/possible_value.rs delete mode 100644 vendor/clap/src/builder/regex.rs delete mode 100644 vendor/clap/src/builder/tests.rs delete mode 100644 vendor/clap/src/builder/usage_parser.rs delete mode 100644 vendor/clap/src/builder/value_hint.rs delete mode 100644 vendor/clap/src/builder/value_parser.rs delete mode 100644 vendor/clap/src/derive.rs delete mode 100644 vendor/clap/src/error/context.rs delete mode 100644 vendor/clap/src/error/kind.rs delete mode 100644 vendor/clap/src/error/mod.rs delete mode 100644 vendor/clap/src/lib.rs delete mode 100644 vendor/clap/src/macros.rs delete mode 100644 vendor/clap/src/mkeymap.rs delete mode 100644 vendor/clap/src/output/fmt.rs delete mode 100644 vendor/clap/src/output/help.rs delete mode 100644 vendor/clap/src/output/mod.rs delete mode 100644 vendor/clap/src/output/usage.rs delete mode 100644 vendor/clap/src/parser/arg_matcher.rs delete mode 100644 vendor/clap/src/parser/error.rs delete mode 100644 vendor/clap/src/parser/features/mod.rs delete mode 100644 vendor/clap/src/parser/features/suggestions.rs delete mode 100644 vendor/clap/src/parser/matches/any_value.rs delete mode 100644 vendor/clap/src/parser/matches/arg_matches.rs delete mode 100644 vendor/clap/src/parser/matches/matched_arg.rs delete mode 100644 vendor/clap/src/parser/matches/mod.rs delete mode 100644 vendor/clap/src/parser/matches/value_source.rs delete mode 100644 vendor/clap/src/parser/mod.rs delete mode 100644 vendor/clap/src/parser/parser.rs delete mode 100644 vendor/clap/src/parser/validator.rs delete mode 100644 vendor/clap/src/util/color.rs delete mode 100644 vendor/clap/src/util/fnv.rs delete mode 100644 vendor/clap/src/util/graph.rs delete mode 100644 vendor/clap/src/util/id.rs delete mode 100644 vendor/clap/src/util/mod.rs delete mode 100644 vendor/clap/src/util/str_to_bool.rs create mode 100644 vendor/clap_lex-0.2.2/.cargo-checksum.json create mode 100644 vendor/clap_lex-0.2.2/Cargo.toml create mode 100644 vendor/clap_lex-0.2.2/LICENSE-APACHE create mode 100644 vendor/clap_lex-0.2.2/LICENSE-MIT create mode 100644 vendor/clap_lex-0.2.2/README.md create mode 100644 vendor/clap_lex-0.2.2/src/lib.rs delete mode 100644 vendor/clap_lex/.cargo-checksum.json delete mode 100644 vendor/clap_lex/Cargo.toml delete mode 100644 vendor/clap_lex/LICENSE-APACHE delete mode 100644 vendor/clap_lex/LICENSE-MIT delete mode 100644 vendor/clap_lex/README.md delete mode 100644 vendor/clap_lex/src/lib.rs create mode 100644 vendor/compiler_builtins/LICENSE.txt create mode 100644 vendor/crossbeam-epoch/src/sync/once_lock.rs create mode 100644 vendor/crossbeam-utils/src/sync/once_lock.rs create mode 100644 vendor/dashmap/src/rayon/read_only.rs delete mode 100644 vendor/dashmap/src/table.rs create mode 100644 vendor/home/src/env.rs delete mode 100644 vendor/itertools/Cargo.lock create mode 100644 vendor/itertools/clippy.toml create mode 100644 vendor/itertools/src/extrema_set.rs delete mode 100644 vendor/matches/.cargo-checksum.json delete mode 100644 vendor/matches/Cargo.toml delete mode 100644 vendor/matches/LICENSE delete mode 100644 vendor/matches/lib.rs delete mode 100644 vendor/matches/tests/macro_use_one.rs delete mode 100644 vendor/matches/tests/use_star.rs delete mode 100644 vendor/percent-encoding/lib.rs create mode 100644 vendor/percent-encoding/src/lib.rs create mode 100644 vendor/rustc_tools_util/.cargo-checksum.json create mode 100644 vendor/rustc_tools_util/Cargo.toml create mode 100644 vendor/rustc_tools_util/LICENSE-APACHE create mode 100644 vendor/rustc_tools_util/LICENSE-MIT create mode 100644 vendor/rustc_tools_util/README.md create mode 100644 vendor/rustc_tools_util/src/lib.rs create mode 100644 vendor/smallvec/debug_metadata/README.md create mode 100644 vendor/smallvec/debug_metadata/smallvec.natvis create mode 100644 vendor/smallvec/tests/debugger_visualizer.rs delete mode 100644 vendor/syn/tests/.gitignore create mode 100644 vendor/thiserror/build.rs create mode 100644 vendor/thiserror/src/provide.rs create mode 100644 vendor/thiserror/tests/test_deprecated.rs create mode 100644 vendor/tracing-attributes/tests/ui.rs create mode 100644 vendor/tracing-attributes/tests/ui/async_instrument.rs create mode 100644 vendor/tracing-attributes/tests/ui/async_instrument.stderr create mode 100644 vendor/tracing-subscriber-0.3.3/.cargo-checksum.json create mode 100644 vendor/tracing-subscriber-0.3.3/CHANGELOG.md create mode 100644 vendor/tracing-subscriber-0.3.3/Cargo.toml create mode 100644 vendor/tracing-subscriber-0.3.3/LICENSE create mode 100644 vendor/tracing-subscriber-0.3.3/README.md create mode 100644 vendor/tracing-subscriber-0.3.3/benches/enter.rs create mode 100644 vendor/tracing-subscriber-0.3.3/benches/filter.rs create mode 100644 vendor/tracing-subscriber-0.3.3/benches/filter_log.rs create mode 100644 vendor/tracing-subscriber-0.3.3/benches/fmt.rs create mode 100644 vendor/tracing-subscriber-0.3.3/benches/support/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/field/debug.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/field/delimited.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/field/display.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/field/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/directive.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/env/directive.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/env/field.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/env/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/filter_fn.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/layer_filters.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/level.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/filter/targets.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/fmt_layer.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/format/json.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/format/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/format/pretty.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/time/datetime.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/time/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/time/time_crate.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/fmt/writer.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/layer/context.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/layer/layered.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/layer/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/layer/tests.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/lib.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/macros.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/prelude.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/registry/extensions.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/registry/mod.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/registry/sharded.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/registry/stack.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/reload.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/sync.rs create mode 100644 vendor/tracing-subscriber-0.3.3/src/util.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/cached_layer_filters_dont_break_other_layers.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/duplicate_spans.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/field_filter.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/filter.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/filter_log.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/fmt_max_level_hint.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/hinted_layer_filters_dont_break_other_layers.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filter_interests_are_cached.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filters/boxed.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filters/downcast_raw.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filters/filter_scopes.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filters/main.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filters/targets.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/layer_filters/trees.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/multiple_layer_filter_interests_cached.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/registry_max_level_hint.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/registry_with_subscriber.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/reload.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/same_len_filters.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/support.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/unhinted_layer_filters_dont_break_other_layers.rs create mode 100644 vendor/tracing-subscriber-0.3.3/tests/utils.rs delete mode 100644 vendor/tracing-subscriber/.cargo-checksum.json delete mode 100644 vendor/tracing-subscriber/CHANGELOG.md delete mode 100644 vendor/tracing-subscriber/Cargo.toml delete mode 100644 vendor/tracing-subscriber/LICENSE delete mode 100644 vendor/tracing-subscriber/README.md delete mode 100644 vendor/tracing-subscriber/benches/enter.rs delete mode 100644 vendor/tracing-subscriber/benches/filter.rs delete mode 100644 vendor/tracing-subscriber/benches/filter_log.rs delete mode 100644 vendor/tracing-subscriber/benches/fmt.rs delete mode 100644 vendor/tracing-subscriber/benches/support/mod.rs delete mode 100644 vendor/tracing-subscriber/src/field/debug.rs delete mode 100644 vendor/tracing-subscriber/src/field/delimited.rs delete mode 100644 vendor/tracing-subscriber/src/field/display.rs delete mode 100644 vendor/tracing-subscriber/src/field/mod.rs delete mode 100644 vendor/tracing-subscriber/src/filter/directive.rs delete mode 100644 vendor/tracing-subscriber/src/filter/env/builder.rs delete mode 100644 vendor/tracing-subscriber/src/filter/env/directive.rs delete mode 100644 vendor/tracing-subscriber/src/filter/env/field.rs delete mode 100644 vendor/tracing-subscriber/src/filter/env/mod.rs delete mode 100644 vendor/tracing-subscriber/src/filter/filter_fn.rs delete mode 100644 vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs delete mode 100644 vendor/tracing-subscriber/src/filter/layer_filters/mod.rs delete mode 100644 vendor/tracing-subscriber/src/filter/level.rs delete mode 100644 vendor/tracing-subscriber/src/filter/mod.rs delete mode 100644 vendor/tracing-subscriber/src/filter/targets.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/fmt_layer.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/format/json.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/format/mod.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/format/pretty.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/mod.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/time/datetime.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/time/mod.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/time/time_crate.rs delete mode 100644 vendor/tracing-subscriber/src/fmt/writer.rs delete mode 100644 vendor/tracing-subscriber/src/layer/context.rs delete mode 100644 vendor/tracing-subscriber/src/layer/layered.rs delete mode 100644 vendor/tracing-subscriber/src/layer/mod.rs delete mode 100644 vendor/tracing-subscriber/src/layer/tests.rs delete mode 100644 vendor/tracing-subscriber/src/lib.rs delete mode 100644 vendor/tracing-subscriber/src/macros.rs delete mode 100644 vendor/tracing-subscriber/src/prelude.rs delete mode 100644 vendor/tracing-subscriber/src/registry/extensions.rs delete mode 100644 vendor/tracing-subscriber/src/registry/mod.rs delete mode 100644 vendor/tracing-subscriber/src/registry/sharded.rs delete mode 100644 vendor/tracing-subscriber/src/registry/stack.rs delete mode 100644 vendor/tracing-subscriber/src/reload.rs delete mode 100644 vendor/tracing-subscriber/src/sync.rs delete mode 100644 vendor/tracing-subscriber/src/util.rs delete mode 100644 vendor/tracing-subscriber/tests/cached_layer_filters_dont_break_other_layers.rs delete mode 100644 vendor/tracing-subscriber/tests/duplicate_spans.rs delete mode 100644 vendor/tracing-subscriber/tests/env_filter/main.rs delete mode 100644 vendor/tracing-subscriber/tests/env_filter/per_layer.rs delete mode 100644 vendor/tracing-subscriber/tests/event_enabling.rs delete mode 100644 vendor/tracing-subscriber/tests/field_filter.rs delete mode 100644 vendor/tracing-subscriber/tests/filter_log.rs delete mode 100644 vendor/tracing-subscriber/tests/fmt_max_level_hint.rs delete mode 100644 vendor/tracing-subscriber/tests/hinted_layer_filters_dont_break_other_layers.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filter_interests_are_cached.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/boxed.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/combinators.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/downcast_raw.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/filter_scopes.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/main.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/targets.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/trees.rs delete mode 100644 vendor/tracing-subscriber/tests/layer_filters/vec.rs delete mode 100644 vendor/tracing-subscriber/tests/multiple_layer_filter_interests_cached.rs delete mode 100644 vendor/tracing-subscriber/tests/option.rs delete mode 100644 vendor/tracing-subscriber/tests/registry_max_level_hint.rs delete mode 100644 vendor/tracing-subscriber/tests/registry_with_subscriber.rs delete mode 100644 vendor/tracing-subscriber/tests/reload.rs delete mode 100644 vendor/tracing-subscriber/tests/same_len_filters.rs delete mode 100644 vendor/tracing-subscriber/tests/support.rs delete mode 100644 vendor/tracing-subscriber/tests/unhinted_layer_filters_dont_break_other_layers.rs delete mode 100644 vendor/tracing-subscriber/tests/utils.rs delete mode 100644 vendor/tracing-subscriber/tests/vec.rs delete mode 100644 vendor/tracing-subscriber/tests/vec_subscriber_filter_interests_cached.rs create mode 100644 vendor/unicode-ident/LICENSE-UNICODE create mode 100644 vendor/unicode-script/LICENSE-APACHE create mode 100644 vendor/unicode-script/LICENSE-MIT create mode 100644 vendor/url/README.md create mode 100644 vendor/url/tests/debugger_visualizer.rs create mode 100644 vendor/xflags-macros/tests/data/help.rs create mode 100644 vendor/xflags-macros/tests/data/repeated_pos.rs create mode 100644 vendor/xflags-macros/tests/data/smoke.rs create mode 100644 vendor/xflags-macros/tests/data/subcommands.rs delete mode 100644 vendor/xflags-macros/tests/it/src/help.rs delete mode 100644 vendor/xflags-macros/tests/it/src/repeated_pos.rs delete mode 100644 vendor/xflags-macros/tests/it/src/smoke.rs delete mode 100644 vendor/xflags-macros/tests/it/src/subcommands.rs delete mode 100644 vendor/xflags/LICENSE-APACHE delete mode 100644 vendor/xflags/LICENSE-MIT delete mode 100644 vendor/xflags/README.md create mode 100644 vendor/xflags/examples/immediate-mode.rs (limited to 'vendor') diff --git a/vendor/clap-3.2.20/.cargo-checksum.json b/vendor/clap-3.2.20/.cargo-checksum.json new file mode 100644 index 000000000..22fa24875 --- /dev/null +++ b/vendor/clap-3.2.20/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"60560d6b2bec73734ebea64f8b916cbe9361e672157119801ba0e2f89334453c","Cargo.toml":"5def59eada2aa1a035cb39b38da4ba02baec2dd9271e4ef16731a8ef06c4d58f","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"0d687e1f07b58fe68bda74668ff6326125e5e5efa184cce755cd84ac535b7058","README.md":"ee049ee3ccab683cd3fa7c980db71c22ed8577378433cad5a93c1bc2a9dbe20f","examples/cargo-example-derive.md":"8305e66dd56619ec3a1d116951c893965cc8435574f5bf8baea923492357c626","examples/cargo-example-derive.rs":"a94003c9fadd1a11c35616ea4e5132c768bad08650e207848e1de56bffd86c8f","examples/cargo-example.md":"b7e51be8f05538ae39ce232ef12c873af81ab5abb5740c079d09b7cdd27a3b71","examples/cargo-example.rs":"be19a1ccb9d91882d76e7553f692ef89fa2a7acbbc1500232ce9fb60b6e8a85b","examples/demo.md":"9db305e9ff333f5e783dcc3142683280816d7bc111a57e9dcc4127f07ca44055","examples/demo.rs":"8a18ab15a235b84efd82017e51a891ed2df5f0154adbfce2806dcac089296b64","examples/derive_ref/augment_args.rs":"93fa1e122328a5d12ca4f921d17902dff6ec47b69fb2140124e2a00809ec4a1a","examples/derive_ref/augment_subcommands.rs":"5535f8ca1893101acb5eba8edc311497431ff9aa26f62f1d9743bdc147bef7a4","examples/derive_ref/custom-bool.md":"d92e441199c7584d4b888c45124366cc4802ec8ea67cdcbb3423ffaa3c5268ac","examples/derive_ref/custom-bool.rs":"f88e9c68d2447a24bc98e05124fea17836155f32cff30a2b8a03ad254383247c","examples/derive_ref/flatten_hand_args.rs":"abdb4e55b0cb71e5c4d14fe20ae0930df6888b2dca01225a02d3c6828bcbc791","examples/derive_ref/hand_subcommand.rs":"1a5464b9c5791361930b5591adeb6fcf6f14b83abdfa6443d2c80bcf0c097b3e","examples/derive_ref/interop_tests.md":"3a357e82cfc155f71e0348be33f78295aa77839c3e3a5b7c1783cbd1259e6a61","examples/escaped-positional-derive.md":"64329a454ad399cfde7cae37c2419fb68f1dfcdf2b7d809e113bab69c5f9b947","examples/escaped-positional-derive.rs":"68b0b474509d0d0b19a2ad756c15a18a9d3b30278390ddf1b7bc11b40fe5f937","examples/escaped-positional.md":"a8259da128ad7ad1f898527bb9e3c1c55541fdc2a59a8599fcddbe9cf58a3563","examples/escaped-positional.rs":"ca33f37267df8de835eeb5817e906a957e96c4ee9bd95b97abee3af25639f3c2","examples/git-derive.md":"280909b56757f102cad3a3274a92c884a0cec4e698c0f8718d2edee73fbbd810","examples/git-derive.rs":"2e8310364f2622b1b11c916643dda7392ec4a4fd585f30d537672d2fed48ea6e","examples/git.md":"31c172433b05ce581179aaba10d610de5cf097b0da894f1330a0437ef332feab","examples/git.rs":"9da386531604fc2afbd375685e213200ad10e34100ec92b4bfa6fb5730283aa1","examples/multicall-busybox.md":"0e07a2f79f94daf4586db85bf207b4bd8f0653b59858d6b4f0b66956a5b2178f","examples/multicall-busybox.rs":"709f71a82295a539d0a239371d35d1eeb517eaa3bb0a4db406bb7e5d3541a4a5","examples/multicall-hostname.md":"b547e42135269ab1e8be8dea4da6a4e99dfaa006a320fa319198d5934e1e97ab","examples/multicall-hostname.rs":"cc58a924dd2e57281f36e30481a1cbc8186952adbf149f9e1e13f9c673614fd9","examples/pacman.md":"c91e1582caf8a2cdeca208c856d1ede3f3ff26948b288a98ef69ea695f12f555","examples/pacman.rs":"f249824b950e1c34fae37afe04389143a037452a1f699c215172ac20e0285984","examples/repl.rs":"d50c1da634c237b26989994b1efa6fd1a087874a82d1fc8c1863be4ea8deaa8c","examples/tutorial_builder/01_quick.md":"80878c8630e0ecf7bb172c2645c2c17480ca5a37e5f4f481ab99e88d3a37da8e","examples/tutorial_builder/01_quick.rs":"c19b165fce9468fb3c9d3d9354a2b9829ceea7ffba6b7134d4941a6e986429a9","examples/tutorial_builder/02_app_settings.md":"f0f7b48afa7a97c9270f9d63a0e9e0f3117733ee0201639eae2199a4aca4944e","examples/tutorial_builder/02_app_settings.rs":"dd770d131726c3f37e202c9b10c969cc4eba90249c54a05594535cea6efe2749","examples/tutorial_builder/02_apps.md":"815a9197925d403b1d93969ace87e80e32667333fa83f2c86abcbdfa17cf0d7e","examples/tutorial_builder/02_apps.rs":"a7016469d10259ae0025fb6ad5b9d3c732cf082869348005d4774d2bb0722d2d","examples/tutorial_builder/02_crate.md":"086581912b34d305bb7cf3c5a35238c151bd366fac4c0923057883253731c250","examples/tutorial_builder/02_crate.rs":"2742c6a3f1946b89b4f1146893e126d68e1cf55ad4130fb94105091900421273","examples/tutorial_builder/03_01_flag_bool.md":"068378b1e76ce624dd0153dfaa9a7ae2d1a84205b1e169f5f1a16bebd50715cf","examples/tutorial_builder/03_01_flag_bool.rs":"d49b30b527faa6a383b334e572d546fab5c4b298a5549842073ab42a33a05c94","examples/tutorial_builder/03_01_flag_count.md":"8d62fbef076eac962a1d0082afa4916de22277aee973d693de33e9fd73b16669","examples/tutorial_builder/03_01_flag_count.rs":"2bfaac3aa9bcbbf37e18e74a40d966391e208d44b45a1e9c4ab61d22fd14dd40","examples/tutorial_builder/03_02_option.md":"585793524138da00c25b9fdd883b25eb8addfaf8742365d84cde63169a9289a7","examples/tutorial_builder/03_02_option.rs":"ce43934605e0438f1e8706e5e970cfcd930f76c4ebee02450ffc63de520994bd","examples/tutorial_builder/03_03_positional.md":"46fe5085841342243efd9614e80db7db3c52ae5af7c6cdd402b569d310e63fe9","examples/tutorial_builder/03_03_positional.rs":"fc7538d0fe8501c56070f0f22be699f128890636aa4ff8478cd6c7beeea279da","examples/tutorial_builder/03_04_subcommands.md":"fc5a92c5290b3cc119a6421779cdd8f4791465a1d3f50f4f29ccb08f3063a6f5","examples/tutorial_builder/03_04_subcommands.rs":"a309a332004edbed6dc14b64b1ba6cc0cd42871f3c5b8da7daab772764839c68","examples/tutorial_builder/03_05_default_values.md":"431800610a29d9a5587b74b30d709e67af5a0b8980900de20e5876fb9491144c","examples/tutorial_builder/03_05_default_values.rs":"b277be9cfe5d87958f9cf2e8a178bb007b070723528bedc8b81163aedb3a2880","examples/tutorial_builder/04_01_enum.md":"d1310efc5c8acb5ca9c86b57deebbcbd8766869284d2e8ea51e32b3eeac38439","examples/tutorial_builder/04_01_enum.rs":"596aa44bc401674a4ccf091b81b2df79b911dbb01d61fd167fd270d1e21a3609","examples/tutorial_builder/04_01_possible.md":"308cd6530b3c389bf2a82b2b66ad33025be230d84d94835273af35a90eb6a753","examples/tutorial_builder/04_01_possible.rs":"3d781b26d257061b55a957744c2dbd99c1d2346c151230fb18fe5f576d19585c","examples/tutorial_builder/04_02_parse.md":"ea14a355913fd7a8af5aac4be2bdecfda72c039b62ccadfb91ff8d39a447955e","examples/tutorial_builder/04_02_parse.rs":"a65f596341e65f41d555b38a6f5e22a5e03aac6faa4e8b3e3c85fa0e0935a2d7","examples/tutorial_builder/04_02_validate.md":"7536f4fb1a11ab94e54b6b98b7364c77912b7600803aeda5988c5b29f3f037c8","examples/tutorial_builder/04_02_validate.rs":"af6d9f748c6956aaa1006ce96834e0d013a9dbfb6d0acc63df5eb63caac56eef","examples/tutorial_builder/04_03_relations.md":"ffc6b8a2d606856fbb6cce677c5280e08eaffbe6a4c8e40cd68ce35959370ed7","examples/tutorial_builder/04_03_relations.rs":"a2dbb6d77587f64775ef57c4bb3869a2760e5c124e2870898bbf1191ef349b99","examples/tutorial_builder/04_04_custom.md":"d562fd072b5d91e8ea145771a2b6eb0284d3d21bfac707ba48ee00e92d76ad2d","examples/tutorial_builder/04_04_custom.rs":"ea0879629da2dab2d2e7fd25bdde53386d863a3e2d468e7ea306a6f8240a5522","examples/tutorial_builder/05_01_assert.rs":"69fc5a3d330be1f90055f886d65684204d7f0585459f362cf3c43b5caf4bbd7b","examples/tutorial_derive/01_quick.md":"1416029b09409468ba6b39ae5f91c41547f7f389c2534961f867ab17260638da","examples/tutorial_derive/01_quick.rs":"e17262c915199c4507d8950d5eafb73f3047e09b6dee2abbfe9f82ebf1b7ddd5","examples/tutorial_derive/02_app_settings.md":"3f4a81ebc7b674482768763bab70acf9bc31f68cc3ecb118c6f5493feaff3d42","examples/tutorial_derive/02_app_settings.rs":"7e81f4c1640b0bfbd87aedd3eda79ae7c47c669dee79b643b35e54c1dc076ee8","examples/tutorial_derive/02_apps.md":"27d22d45e438f60b346d34508a75783871e0fe9b1ae41ec759e56118a10feff7","examples/tutorial_derive/02_apps.rs":"e8cd02b5983b2203f1585b96858fade4cedfb124e366171d6b21fcb3f05b514e","examples/tutorial_derive/02_crate.md":"eb396e17db1dd68eb7689bcd806b63dbfe01ad48dfc12c285f00c42e1d4b8c1f","examples/tutorial_derive/02_crate.rs":"0b12a0790d23cee1e5d275893f428cc0af36d5532c2af00806e64c18ef9d309c","examples/tutorial_derive/03_01_flag_bool.md":"f6dd5ab050f0f1ac5924949a4ba45f248b2d4b1bd77210d78b9d8e9b3395d111","examples/tutorial_derive/03_01_flag_bool.rs":"07c31218d0332d7437d80e19c7e3c7be711bf0f56bee3ffb1c4d6f7f253b9304","examples/tutorial_derive/03_01_flag_count.md":"74d5c8a79581ceb7e6a11ec20ae59fa8c7f42591e10464aad50bbdd3d06916fc","examples/tutorial_derive/03_01_flag_count.rs":"945be42994845145b9c579b3834f8c6375f239293ded84fba35754bbe9fdcf9b","examples/tutorial_derive/03_02_option.md":"034b65008d05c1598fe3c1918f23d654d7a14cb610dd636a3c649d9d7a3b1559","examples/tutorial_derive/03_02_option.rs":"48be4cf49b498173200ad86d5d3cd64ce9381f86fdaaab70f05fc471f64a2185","examples/tutorial_derive/03_03_positional.md":"14f6b36eee218a38733b534e7b621f68a6f799bd96682a82980cba9f6e99a40e","examples/tutorial_derive/03_03_positional.rs":"f368ab1465ee4d84b84d175b97af6f64ce0676bec2482adef3ce966d2d8de26a","examples/tutorial_derive/03_04_subcommands.md":"3e1870fb10c78a01b63903060b1164f3f4d0e51c052e449abe11e2d06c252811","examples/tutorial_derive/03_04_subcommands.rs":"b25c8aec8f3816923b1154be91caafe0c2d2841fc1af5f0ef048f03d1273879e","examples/tutorial_derive/03_04_subcommands_alt.rs":"7ba6e81c2af6085b7e2721254500b34ee3e8622e20790b3c6f2786e165151b70","examples/tutorial_derive/03_05_default_values.md":"9ac52230ba7d9c214dcb64922cbf161970947d9650e8e7ea8d0ee949eba99c0e","examples/tutorial_derive/03_05_default_values.rs":"0ba14153a3c72a2435ac3688b990171a1670eb3f2f7cef21886732e489fad435","examples/tutorial_derive/04_01_enum.md":"ee57dc12a88a560d70f344629ac79cc497f96e967e97b4c643467747c8075172","examples/tutorial_derive/04_01_enum.rs":"d30abd8570357be26871c06939dee8173d34408250b6bdc3b1e76f1cbc06f888","examples/tutorial_derive/04_02_parse.md":"f191e6c77e6b133f78bd1123cec2b09c8dfe8bb17198d6348e26adade7465daf","examples/tutorial_derive/04_02_parse.rs":"fbb23ef2d98d3cb401cec9dd29d5818e4c189cc9f54fe961a2fbd08632a9634c","examples/tutorial_derive/04_02_validate.md":"c88670017d06261d454818ff18f21a06275f35d564e637c5346ce3b7fca8a02b","examples/tutorial_derive/04_02_validate.rs":"87d9c465f912b69e5839ea87404a221a39421404012c1a7fd6e327b03ceb12f0","examples/tutorial_derive/04_03_relations.md":"5657bbeee193f21a312db682cfa216f1001a94ace024c56a959985feb2e29069","examples/tutorial_derive/04_03_relations.rs":"eb8e737733261d3d1b7f4def7a05c37ba7c1c010357c7de33ee42c8adfdf6dc2","examples/tutorial_derive/04_04_custom.md":"9627d0025c5c063682387d8e00b3fb097114d1431c1ce8808038be34f781576a","examples/tutorial_derive/04_04_custom.rs":"0e745c6dab0881c62190e82e01409b70cf3286dd0983db4a612f1be88fdd1a8d","examples/tutorial_derive/05_01_assert.rs":"653450ff2e528f29b6b31d979fd7da094ea8e74b8b61a4657935c9ac2efbc28e","examples/typed-derive.md":"c22bb8da2e294f1d3725624e0c442713e5f263b10a2ee76a22ffa07f89af735a","examples/typed-derive.rs":"1c88bb1c8cec4e2e7a452552fa52675d96ffd6f201f5384b4e98d0a70fce1e4c","src/_cookbook/cargo_example.rs":"fe7594a5233e9106a159aa1f5d5f0cde0d844356f630d55c78b8ef322327d4e5","src/_cookbook/cargo_example_derive":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/_cookbook/cargo_example_derive.rs":"badf3e931ef5d5b7f5addc4912aca057ba83ee6302c43d7eeecd1661673fd407","src/_cookbook/escaped_positional.rs":"2789d8fea126355805b29e76b52c6cea4982565014087a46e0d48e4ddfbed7ab","src/_cookbook/escaped_positional_derive.rs":"802d0b672f4ed48152235d4a26a64c97fa921b361177bdd3a1a33cbac96f665d","src/_cookbook/git.rs":"372977252a22fc776e3acaa4629e964114ccd6a49b8ef334d2b6646f12e8b5ee","src/_cookbook/git_derive.rs":"4ab7c0197efda06607ca60c2a85ea743aed3494f5fe9e408d935ea0500a345fc","src/_cookbook/mod.rs":"34c53c6273512976676a82dded921f8d99e0312dd3e823ae1549606754625827","src/_cookbook/multicall_busybox.rs":"56176b4fa15e7a39c433706971d4e68aaf26ddc2a5790078b6dbe722ee13efee","src/_cookbook/multicall_hostname.rs":"907f8decf81ea4d4cbf81639ea4cd2f925eda64d4831454a7656369b65522780","src/_cookbook/pacman.rs":"863125b2d3d7931a9e4541c8ab1242b8bfcb421d8b5c604ea681efd805f68da7","src/_cookbook/repl.rs":"1393209b2cc5c203296d57c5a065b764b4318be7855e48baf16de851e250cf90","src/_cookbook/typed_derive.rs":"3d28e78cd0b068b4fcb32a7fea6244de176f2fe75dfcb59e99c33b66a7ae4864","src/_derive/_tutorial.rs":"237d316ad5f9838dc011283e454afce24d47bf2e9c5038ba5402bafeb2959090","src/_derive/mod.rs":"7f1f6b59332044681324f0753dfb51641e52f46dee74a21b8c94a413bc06be02","src/_faq.rs":"06d10de865ae34305fa973db9b00dc31f54e0f63f8fe039805aa371c36a796b9","src/_features.rs":"bbcbf1b256136d20f89e4f8a16ff37b04f07dfee0d2d4f2b013f445467628032","src/_tutorial.rs":"e7c7359b6b6c86cf6e18f4bdc3c90ce440b82bf07ce304ca2e127fb2a04cbf9f","src/bin/stdio-fixture.rs":"e8f10afbfe1857bcf986d2f55be0ca19a50c905d9f650c6e1fd42dbacf219b04","src/builder/action.rs":"beab4d8dca6337dfd64f387ee3198a88a6dcb71ec94f5bbbfe6bb4c0175ab9ee","src/builder/app_settings.rs":"17b094a5c044b2387467706bade1b19b5703bf99fc5081ac9508f410f871a1f2","src/builder/arg.rs":"e7120b60bf72d2572fc1f325b377a32da9ece4d7ac00b4a580a0f6a42c08ea8a","src/builder/arg_group.rs":"263d9c79e03015fe4e2fab4616fc73089be60fb2ec17aa2a06f3d6a24740432c","src/builder/arg_predicate.rs":"8c9fd14780cd42465f32f2e8927b97c06e686d09b5927ba3cd5bbd792af7a13d","src/builder/arg_settings.rs":"b7966dfea529a1be1164ca2d76494b1712cb2f73b024d2a23307dcd473933887","src/builder/command.rs":"57f0076465feb3cf6a0a16610b345fae8dbde8d248e4ef94111a27051c40789b","src/builder/debug_asserts.rs":"d1d5adc82cb8269445b2ef197f1e566f61e7f13d6a24afaad928e45e95aed170","src/builder/macros.rs":"904e42e72c49107ae324f45d5df24fbff13b9c7d4589f1a4ae38594add704434","src/builder/mod.rs":"205367cb5ba5d5ba7894091535ce3a5dd23b35fd436e003196d89523e7705566","src/builder/possible_value.rs":"62268b9da9eec8f4d1904ebfbd3a288fb78cfa71c357efadced28f0378bcfb93","src/builder/regex.rs":"b18891310186ecdcca9bb611833b7188cc80fe72e9fef27b63fa076b880a1acb","src/builder/tests.rs":"995c7d6be608b94c6f392f1356eba0cb8adb9ca661ffeebf7ebe6e8ad01a868c","src/builder/usage_parser.rs":"91d1af89196116aac2c0fb021f42f43f954aa3252df264e19a02a0cf5911d16b","src/builder/value_hint.rs":"0dd974d495c313430898d28b79991a70983c9aa44e88fa9aa1776d3308935438","src/builder/value_parser.rs":"64bb7f4808bdf65f30cb434198038a06db556e5ca045d900da392cc1a3186896","src/derive.rs":"11eaddc27a06229322a6bbce4458cb1424e6a5805c79166cba342c2905093b51","src/error/context.rs":"1dc561c7877d7f9b90f04bb7915744f0b3cc4ac2aa928ae100b2825a97077142","src/error/kind.rs":"3b4f9dfe5be5843cec8380c8f8965dcb9d0beee0aaa02cadf8dcffd400626ede","src/error/mod.rs":"e5b60fee401975d95c460c2567d09e17972eaae336154a8b90d9c806083f63fa","src/lib.rs":"4a197eab3f447c58a266af4f9a787af5c98b18f4612f33d9189cce52f4f9de18","src/macros.rs":"72585e32051a6872bbb29e39f7e9f9a88334a03f39ec3c768984db2f38211001","src/mkeymap.rs":"3565a5bae5d6cdcf8ba41a24eb602c510a14e150c4a6d3085ad72a35778e9c5f","src/output/fmt.rs":"efb741b5854500d946c6c09763ece1badc2b9cd3efa616cb58012039836c2b7f","src/output/help.rs":"ebdd123d6b70279c25af4b08432b547498834853adf99821ff6c6cd65dd87d4e","src/output/mod.rs":"3a61f89a4568e95114a3ab839da8f3c4c92de2a228549308f5d1be076a474917","src/output/usage.rs":"1921d2fa362f111b3f9613fc98eb5e24686483fe112b337855da7eb17b643f71","src/parser/arg_matcher.rs":"0c9ae639ed241e8ff1f62cd9e5eab2de9e5db1be0e86f58d5d94619d6dad05fd","src/parser/error.rs":"51e8fbd7cc73bba78cca50417e9b4fb25e11eefc60ff4b957940176bdb995e5c","src/parser/features/mod.rs":"6ed075e97af56bff22f22ed1ee83ff6479360e05f9d3661a3145f822c242b694","src/parser/features/suggestions.rs":"79127956b2f1adb9d658925e2779ebebfe9ddea434408762fefb60afdb545f47","src/parser/matches/any_value.rs":"7b6e711fe205e8808394c562dd6a260b56ce350cf9298a308ba9727ab012b664","src/parser/matches/arg_matches.rs":"666e3640b5347aba5806fc15b5caa599b171e684ee15d933ddc7f8185a0d2032","src/parser/matches/matched_arg.rs":"fb12eb2afaf631bb60aa8c4e42b0f510a877d35a9eaa07a7afd253280c27c251","src/parser/matches/mod.rs":"1467aa752cb1c79d30e4aeaaa55e10a0bb9dcf6f3980496234251431c79c49e6","src/parser/matches/value_source.rs":"e6a477ae36f2f7155960239a97b7d142eef4eb227c41c9eefea147289547d713","src/parser/mod.rs":"358f46d3b7f43dec2563d4c35bd2536fab2491f28e300a9bcdeaf6ca0513ce12","src/parser/parser.rs":"9e338dfd60aa8bfbcfbbda15c73d4722767a4d2e7b8f8ed3a07c296ddd98762c","src/parser/validator.rs":"30066cb41ab23800231fb6b028cbce57d118570859659ebc67affbe5226f31f9","src/util/color.rs":"63df5e1cda1001b4c536dc0b04e09dd85dae6d317e34e660abbe3c71e17eaa29","src/util/fnv.rs":"82492d91d990f38b62de8b3c3e67f1fad55919117b1f448aa28acf6d21919fd7","src/util/graph.rs":"f35396b6e2a427377dcbbca69b1b98737d89684a3834cfda98cbf8cc70ff9c2f","src/util/id.rs":"fc498c65887385d92a51359a2f72556c2e508ee49b8cac4b3f827512795d690d","src/util/mod.rs":"8d328a15ef06989d0ce5e65cf3b7ec79c083984b25c0b31ba177bdb22df28a10","src/util/str_to_bool.rs":"1ce90b4939a884eeefc73392722bdfcf906e3070c4398e1557c586c10c684cd0"},"package":"23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"} \ No newline at end of file diff --git a/vendor/clap-3.2.20/Cargo.lock b/vendor/clap-3.2.20/Cargo.lock new file mode 100644 index 000000000..57d007104 --- /dev/null +++ b/vendor/clap-3.2.20/Cargo.lock @@ -0,0 +1,746 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "3.2.20" +dependencies = [ + "atty", + "backtrace", + "bitflags", + "clap_derive", + "clap_lex", + "humantime", + "indexmap", + "once_cell", + "regex", + "rustversion", + "shlex", + "snapbox", + "static_assertions", + "strsim", + "termcolor", + "terminal_size", + "textwrap", + "trybuild", + "trycmd", + "unicase", + "yaml-rust", +] + +[[package]] +name = "clap_derive" +version = "3.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "combine" +version = "4.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concolor" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "015267563b1df20adccdd00cb05257b1dfbea70a04928e9cf88ffb850c1a40af" +dependencies = [ + "atty", + "bitflags", + "concolor-query", +] + +[[package]] +name = "concolor-query" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449" + +[[package]] +name = "crossbeam-channel" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "once_cell", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "either" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" + +[[package]] +name = "escargot" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" +dependencies = [ + "log", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "os_pipe" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c92f2b54f081d635c77e7120862d48db8e91f7f21cef23ab1b4fe9971c59f55" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustversion" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "similar" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" + +[[package]] +name = "snapbox" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "767a1d5da232b6959cd1bd5c9e8db8a7cce09c3038e89deedb49a549a2aefd93" +dependencies = [ + "concolor", + "normalize-line-endings", + "os_pipe", + "similar", + "snapbox-macros", + "wait-timeout", + "yansi", +] + +[[package]] +name = "snapbox-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +dependencies = [ + "terminal_size", + "unicode-width", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f" +dependencies = [ + "combine", + "indexmap", + "itertools", + "serde", +] + +[[package]] +name = "trybuild" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "764b9e244b482a9b81bde596aa37aa6f1347bf8007adab25e59f901b32b4e0a0" +dependencies = [ + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", + "toml", +] + +[[package]] +name = "trycmd" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4185126cc904642173a54c185083f410c86d1202ada6761aacf7c40829f13" +dependencies = [ + "escargot", + "glob", + "humantime", + "humantime-serde", + "rayon", + "serde", + "shlex", + "snapbox", + "toml_edit", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-ident" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/vendor/clap-3.2.20/Cargo.toml b/vendor/clap-3.2.20/Cargo.toml new file mode 100644 index 000000000..197454c07 --- /dev/null +++ b/vendor/clap-3.2.20/Cargo.toml @@ -0,0 +1,471 @@ +# 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 = "2021" +rust-version = "1.56.1" +name = "clap" +version = "3.2.20" +include = [ + "build.rs", + "src/**/*", + "Cargo.toml", + "LICENSE*", + "README.md", + "benches/**/*", + "examples/**/*", +] +description = "A simple to use, efficient, and full-featured Command Line Argument Parser" +readme = "README.md" +keywords = [ + "argument", + "cli", + "arg", + "parser", + "parse", +] +categories = ["command-line-interface"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/clap-rs/clap" +resolver = "2" + +[package.metadata.docs.rs] +features = ["unstable-doc"] +rustdoc-args = [ + "--cfg", + "docsrs", +] +cargo-args = [ + "-Zunstable-options", + "-Zrustdoc-scrape-examples=examples", +] + +[package.metadata.playground] +features = ["unstable-doc"] + +[package.metadata.release] +shared-version = true +tag-name = "v{{version}}" + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "Unreleased" +replace = "{{version}}" +min = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = '\.\.\.HEAD' +replace = "...{{tag_name}}" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "ReleaseDate" +replace = "{{date}}" +min = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "" +replace = """ + +## [Unreleased] - ReleaseDate +""" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "" +replace = """ + +[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD""" +exactly = 1 + +[profile.bench] +lto = true +codegen-units = 1 + +[profile.test] +opt-level = 1 + +[lib] +bench = false + +[[example]] +name = "demo" +required-features = ["derive"] + +[[example]] +name = "cargo-example" +required-features = ["cargo"] + +[[example]] +name = "cargo-example-derive" +required-features = ["derive"] + +[[example]] +name = "escaped-positional" +required-features = ["cargo"] + +[[example]] +name = "escaped-positional-derive" +required-features = ["derive"] + +[[example]] +name = "git-derive" +required-features = ["derive"] + +[[example]] +name = "typed-derive" +required-features = ["derive"] + +[[example]] +name = "busybox" +path = "examples/multicall-busybox.rs" + +[[example]] +name = "hostname" +path = "examples/multicall-hostname.rs" + +[[example]] +name = "repl" +path = "examples/repl.rs" + +[[example]] +name = "01_quick" +path = "examples/tutorial_builder/01_quick.rs" +required-features = ["cargo"] + +[[example]] +name = "02_apps" +path = "examples/tutorial_builder/02_apps.rs" + +[[example]] +name = "02_crate" +path = "examples/tutorial_builder/02_crate.rs" +required-features = ["cargo"] + +[[example]] +name = "02_app_settings" +path = "examples/tutorial_builder/02_app_settings.rs" +required-features = ["cargo"] + +[[example]] +name = "03_01_flag_bool" +path = "examples/tutorial_builder/03_01_flag_bool.rs" +required-features = ["cargo"] + +[[example]] +name = "03_01_flag_count" +path = "examples/tutorial_builder/03_01_flag_count.rs" +required-features = ["cargo"] + +[[example]] +name = "03_02_option" +path = "examples/tutorial_builder/03_02_option.rs" +required-features = ["cargo"] + +[[example]] +name = "03_03_positional" +path = "examples/tutorial_builder/03_03_positional.rs" +required-features = ["cargo"] + +[[example]] +name = "03_04_subcommands" +path = "examples/tutorial_builder/03_04_subcommands.rs" +required-features = ["cargo"] + +[[example]] +name = "03_05_default_values" +path = "examples/tutorial_builder/03_05_default_values.rs" +required-features = ["cargo"] + +[[example]] +name = "04_01_possible" +path = "examples/tutorial_builder/04_01_possible.rs" +required-features = ["cargo"] + +[[example]] +name = "04_01_enum" +path = "examples/tutorial_builder/04_01_enum.rs" +required-features = ["cargo"] + +[[example]] +name = "04_02_parse" +path = "examples/tutorial_builder/04_02_parse.rs" +required-features = ["cargo"] + +[[example]] +name = "04_02_validate" +path = "examples/tutorial_builder/04_02_validate.rs" +required-features = ["cargo"] + +[[example]] +name = "04_03_relations" +path = "examples/tutorial_builder/04_03_relations.rs" +required-features = ["cargo"] + +[[example]] +name = "04_04_custom" +path = "examples/tutorial_builder/04_04_custom.rs" +required-features = ["cargo"] + +[[example]] +name = "05_01_assert" +path = "examples/tutorial_builder/05_01_assert.rs" +test = true +required-features = ["cargo"] + +[[example]] +name = "01_quick_derive" +path = "examples/tutorial_derive/01_quick.rs" +required-features = ["derive"] + +[[example]] +name = "02_apps_derive" +path = "examples/tutorial_derive/02_apps.rs" +required-features = ["derive"] + +[[example]] +name = "02_crate_derive" +path = "examples/tutorial_derive/02_crate.rs" +required-features = ["derive"] + +[[example]] +name = "02_app_settings_derive" +path = "examples/tutorial_derive/02_app_settings.rs" +required-features = ["derive"] + +[[example]] +name = "03_01_flag_bool_derive" +path = "examples/tutorial_derive/03_01_flag_bool.rs" +required-features = ["derive"] + +[[example]] +name = "03_01_flag_count_derive" +path = "examples/tutorial_derive/03_01_flag_count.rs" +required-features = ["derive"] + +[[example]] +name = "03_02_option_derive" +path = "examples/tutorial_derive/03_02_option.rs" +required-features = ["derive"] + +[[example]] +name = "03_03_positional_derive" +path = "examples/tutorial_derive/03_03_positional.rs" +required-features = ["derive"] + +[[example]] +name = "03_04_subcommands_derive" +path = "examples/tutorial_derive/03_04_subcommands.rs" +required-features = ["derive"] + +[[example]] +name = "03_04_subcommands_alt_derive" +path = "examples/tutorial_derive/03_04_subcommands_alt.rs" +required-features = ["derive"] + +[[example]] +name = "03_05_default_values_derive" +path = "examples/tutorial_derive/03_05_default_values.rs" +required-features = ["derive"] + +[[example]] +name = "04_01_enum_derive" +path = "examples/tutorial_derive/04_01_enum.rs" +required-features = ["derive"] + +[[example]] +name = "04_02_parse_derive" +path = "examples/tutorial_derive/04_02_parse.rs" +required-features = ["derive"] + +[[example]] +name = "04_02_validate_derive" +path = "examples/tutorial_derive/04_02_validate.rs" +required-features = ["derive"] + +[[example]] +name = "04_03_relations_derive" +path = "examples/tutorial_derive/04_03_relations.rs" +required-features = ["derive"] + +[[example]] +name = "04_04_custom_derive" +path = "examples/tutorial_derive/04_04_custom.rs" +required-features = ["derive"] + +[[example]] +name = "05_01_assert_derive" +path = "examples/tutorial_derive/05_01_assert.rs" +test = true +required-features = ["derive"] + +[[example]] +name = "custom-bool" +path = "examples/derive_ref/custom-bool.rs" +required-features = ["derive"] + +[[example]] +name = "interop_augment_args" +path = "examples/derive_ref/augment_args.rs" +required-features = ["derive"] + +[[example]] +name = "interop_augment_subcommands" +path = "examples/derive_ref/augment_subcommands.rs" +required-features = ["derive"] + +[[example]] +name = "interop_hand_subcommand" +path = "examples/derive_ref/hand_subcommand.rs" +required-features = ["derive"] + +[[example]] +name = "interop_flatten_hand_args" +path = "examples/derive_ref/flatten_hand_args.rs" +required-features = ["derive"] + +[dependencies.atty] +version = "0.2" +optional = true + +[dependencies.backtrace] +version = "0.3" +optional = true + +[dependencies.bitflags] +version = "1.2" + +[dependencies.clap_derive] +version = "=3.2.18" +optional = true + +[dependencies.clap_lex] +version = "0.2.2" + +[dependencies.indexmap] +version = "1.0" + +[dependencies.once_cell] +version = "1.12.0" +optional = true + +[dependencies.regex] +version = "1.0" +optional = true + +[dependencies.strsim] +version = "0.10" +optional = true + +[dependencies.termcolor] +version = "1.1.1" +optional = true + +[dependencies.terminal_size] +version = "0.1.12" +optional = true + +[dependencies.textwrap] +version = "0.15.0" +features = [] +default-features = false + +[dependencies.unicase] +version = "2.6" +optional = true + +[dependencies.yaml-rust] +version = "0.4.1" +optional = true + +[dev-dependencies.humantime] +version = "2" + +[dev-dependencies.regex] +version = "1.0" + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.shlex] +version = "1.1.0" + +[dev-dependencies.snapbox] +version = "0.2.9" + +[dev-dependencies.static_assertions] +version = "1.1.0" + +[dev-dependencies.trybuild] +version = "1.0.18" + +[dev-dependencies.trycmd] +version = "0.13" +features = [ + "color-auto", + "diff", + "examples", +] +default-features = false + +[features] +cargo = ["once_cell"] +color = [ + "atty", + "termcolor", +] +debug = [ + "clap_derive/debug", + "backtrace", +] +default = [ + "std", + "color", + "suggestions", +] +deprecated = ["clap_derive/deprecated"] +derive = [ + "clap_derive", + "once_cell", +] +env = [] +std = ["indexmap/std"] +suggestions = ["strsim"] +unicode = [ + "textwrap/unicode-width", + "unicase", +] +unstable-doc = [ + "derive", + "cargo", + "wrap_help", + "yaml", + "env", + "unicode", + "regex", + "unstable-replace", + "unstable-grouped", +] +unstable-grouped = [] +unstable-replace = [] +unstable-v4 = [ + "clap_derive/unstable-v4", + "deprecated", +] +wrap_help = [ + "terminal_size", + "textwrap/terminal_size", +] +yaml = ["yaml-rust"] diff --git a/vendor/clap-3.2.20/LICENSE-APACHE b/vendor/clap-3.2.20/LICENSE-APACHE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/clap-3.2.20/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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 [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/clap-3.2.20/LICENSE-MIT b/vendor/clap-3.2.20/LICENSE-MIT new file mode 100644 index 000000000..7b05b8453 --- /dev/null +++ b/vendor/clap-3.2.20/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2022 Kevin B. Knapp and Clap 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. diff --git a/vendor/clap-3.2.20/README.md b/vendor/clap-3.2.20/README.md new file mode 100644 index 000000000..eea6ba6f0 --- /dev/null +++ b/vendor/clap-3.2.20/README.md @@ -0,0 +1,43 @@ +# clap + +> **Command Line Argument Parser for Rust** + +[![Crates.io](https://img.shields.io/crates/v/clap?style=flat-square)](https://crates.io/crates/clap) +[![Crates.io](https://img.shields.io/crates/d/clap?style=flat-square)](https://crates.io/crates/clap) +[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](LICENSE-APACHE) +[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE-MIT) +[![Build Status](https://img.shields.io/github/workflow/status/clap-rs/clap/CI/staging?style=flat-square)](https://github.com/clap-rs/clap/actions/workflows/ci.yml?query=branch%3Astaging) +[![Coverage Status](https://img.shields.io/coveralls/github/clap-rs/clap/master?style=flat-square)](https://coveralls.io/github/clap-rs/clap?branch=master) +[![Contributors](https://img.shields.io/github/contributors/clap-rs/clap?style=flat-square)](https://github.com/clap-rs/clap/graphs/contributors) + +Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). + +## About + +Create your command-line parser, with all of the bells and whistles, declaratively or procedurally. + +For more details, see: +- [docs.rs](https://docs.rs/clap/latest/clap/) +- [examples](examples/) + +## Sponsors + + +### Gold + +[![](https://opencollective.com/clap/tiers/gold.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) + + +### Silver + +[![](https://opencollective.com/clap/tiers/silver.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) + + +### Bronze + +[![](https://opencollective.com/clap/tiers/bronze.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) + + +### Backer + +[![](https://opencollective.com/clap/tiers/backer.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) diff --git a/vendor/clap-3.2.20/examples/cargo-example-derive.md b/vendor/clap-3.2.20/examples/cargo-example-derive.md new file mode 100644 index 000000000..2c7a11b88 --- /dev/null +++ b/vendor/clap-3.2.20/examples/cargo-example-derive.md @@ -0,0 +1,43 @@ +For more on creating a custom subcommand, see [the cargo +book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands). +The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in +mimicking cargo's interface. + +The help looks like: +```console +$ cargo-example-derive --help +cargo + +USAGE: + cargo + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + example-derive A simple to use, efficient, and full-featured Command Line Argument Parser + help Print this message or the help of the given subcommand(s) + +$ cargo-example-derive example-derive --help +cargo-example-derive [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + cargo example-derive [OPTIONS] + +OPTIONS: + -h, --help Print help information + --manifest-path + -V, --version Print version information + +``` + +Then to directly invoke the command, run: +```console +$ cargo-example-derive example-derive +None + +$ cargo-example-derive example-derive --manifest-path Cargo.toml +Some("Cargo.toml") + +``` diff --git a/vendor/clap-3.2.20/examples/cargo-example-derive.rs b/vendor/clap-3.2.20/examples/cargo-example-derive.rs new file mode 100644 index 000000000..f0aad29c7 --- /dev/null +++ b/vendor/clap-3.2.20/examples/cargo-example-derive.rs @@ -0,0 +1,20 @@ +use clap::Parser; + +#[derive(Parser)] // requires `derive` feature +#[clap(name = "cargo")] +#[clap(bin_name = "cargo")] +enum Cargo { + ExampleDerive(ExampleDerive), +} + +#[derive(clap::Args)] +#[clap(author, version, about, long_about = None)] +struct ExampleDerive { + #[clap(long, value_parser)] + manifest_path: Option, +} + +fn main() { + let Cargo::ExampleDerive(args) = Cargo::parse(); + println!("{:?}", args.manifest_path); +} diff --git a/vendor/clap-3.2.20/examples/cargo-example.md b/vendor/clap-3.2.20/examples/cargo-example.md new file mode 100644 index 000000000..6fb6a3c4d --- /dev/null +++ b/vendor/clap-3.2.20/examples/cargo-example.md @@ -0,0 +1,43 @@ +For more on creating a custom subcommand, see [the cargo +book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands). +The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in +mimicking cargo's interface. + +The help looks like: +```console +$ cargo-example --help +cargo + +USAGE: + cargo + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + example A simple to use, efficient, and full-featured Command Line Argument Parser + help Print this message or the help of the given subcommand(s) + +$ cargo-example example --help +cargo-example [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + cargo example [OPTIONS] + +OPTIONS: + -h, --help Print help information + --manifest-path + -V, --version Print version information + +``` + +Then to directly invoke the command, run: +```console +$ cargo-example example +None + +$ cargo-example example --manifest-path Cargo.toml +Some("Cargo.toml") + +``` diff --git a/vendor/clap-3.2.20/examples/cargo-example.rs b/vendor/clap-3.2.20/examples/cargo-example.rs new file mode 100644 index 000000000..d9a909f4f --- /dev/null +++ b/vendor/clap-3.2.20/examples/cargo-example.rs @@ -0,0 +1,19 @@ +fn main() { + let cmd = clap::Command::new("cargo") + .bin_name("cargo") + .subcommand_required(true) + .subcommand( + clap::command!("example").arg( + clap::arg!(--"manifest-path" ) + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)), + ), + ); + let matches = cmd.get_matches(); + let matches = match matches.subcommand() { + Some(("example", matches)) => matches, + _ => unreachable!("clap should ensure we don't get here"), + }; + let manifest_path = matches.get_one::("manifest-path"); + println!("{:?}", manifest_path); +} diff --git a/vendor/clap-3.2.20/examples/demo.md b/vendor/clap-3.2.20/examples/demo.md new file mode 100644 index 000000000..93ee49c37 --- /dev/null +++ b/vendor/clap-3.2.20/examples/demo.md @@ -0,0 +1,19 @@ +```console +$ demo --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + demo[EXE] [OPTIONS] --name + +OPTIONS: + -c, --count Number of times to greet [default: 1] + -h, --help Print help information + -n, --name Name of the person to greet + -V, --version Print version information + +$ demo --name Me +Hello Me! + +``` +*(version number and `.exe` extension on windows replaced by placeholders)* diff --git a/vendor/clap-3.2.20/examples/demo.rs b/vendor/clap-3.2.20/examples/demo.rs new file mode 100644 index 000000000..a7cecfb0c --- /dev/null +++ b/vendor/clap-3.2.20/examples/demo.rs @@ -0,0 +1,22 @@ +use clap::Parser; + +/// Simple program to greet a person +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + /// Name of the person to greet + #[clap(short, long, value_parser)] + name: String, + + /// Number of times to greet + #[clap(short, long, value_parser, default_value_t = 1)] + count: u8, +} + +fn main() { + let args = Args::parse(); + + for _ in 0..args.count { + println!("Hello {}!", args.name) + } +} diff --git a/vendor/clap-3.2.20/examples/derive_ref/augment_args.rs b/vendor/clap-3.2.20/examples/derive_ref/augment_args.rs new file mode 100644 index 000000000..310556914 --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/augment_args.rs @@ -0,0 +1,27 @@ +use clap::{arg, Args, Command, FromArgMatches as _}; + +#[derive(Args, Debug)] +struct DerivedArgs { + #[clap(short, long, action)] + derived: bool, +} + +fn main() { + let cli = Command::new("CLI").arg(arg!(-b - -built).action(clap::ArgAction::SetTrue)); + // Augment built args with derived args + let cli = DerivedArgs::augment_args(cli); + + let matches = cli.get_matches(); + println!("Value of built: {:?}", matches.get_flag("built")); + println!( + "Value of derived via ArgMatches: {:?}", + matches.get_flag("derived") + ); + + // Since DerivedArgs implements FromArgMatches, we can extract it from the unstructured ArgMatches. + // This is the main benefit of using derived arguments. + let derived_matches = DerivedArgs::from_arg_matches(&matches) + .map_err(|err| err.exit()) + .unwrap(); + println!("Value of derived: {:#?}", derived_matches); +} diff --git a/vendor/clap-3.2.20/examples/derive_ref/augment_subcommands.rs b/vendor/clap-3.2.20/examples/derive_ref/augment_subcommands.rs new file mode 100644 index 000000000..199da98b4 --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/augment_subcommands.rs @@ -0,0 +1,21 @@ +use clap::{Command, FromArgMatches as _, Parser, Subcommand as _}; + +#[derive(Parser, Debug)] +enum Subcommands { + Derived { + #[clap(short, long, action)] + derived_flag: bool, + }, +} + +fn main() { + let cli = Command::new("Built CLI"); + // Augment with derived subcommands + let cli = Subcommands::augment_subcommands(cli); + + let matches = cli.get_matches(); + let derived_subcommands = Subcommands::from_arg_matches(&matches) + .map_err(|err| err.exit()) + .unwrap(); + println!("Derived subcommands: {:#?}", derived_subcommands); +} diff --git a/vendor/clap-3.2.20/examples/derive_ref/custom-bool.md b/vendor/clap-3.2.20/examples/derive_ref/custom-bool.md new file mode 100644 index 000000000..619f9ba8e --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/custom-bool.md @@ -0,0 +1,47 @@ +*Jump to [source](custom-bool.rs)* + +Example of overriding the magic `bool` behavior + +```console +$ custom-bool --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + custom-bool[EXE] [OPTIONS] --foo + +ARGS: + [possible values: true, false] + +OPTIONS: + --bar [default: false] + --foo [possible values: true, false] + -h, --help Print help information + -V, --version Print version information + +$ custom-bool +? failed +error: The following required arguments were not provided: + --foo + + +USAGE: + custom-bool[EXE] [OPTIONS] --foo + +For more information try --help + +$ custom-bool --foo true false +[examples/derive_ref/custom-bool.rs:31] opt = Opt { + foo: true, + bar: false, + boom: false, +} + +$ custom-bool --foo true --bar true false +[examples/derive_ref/custom-bool.rs:31] opt = Opt { + foo: true, + bar: true, + boom: false, +} + +``` diff --git a/vendor/clap-3.2.20/examples/derive_ref/custom-bool.rs b/vendor/clap-3.2.20/examples/derive_ref/custom-bool.rs new file mode 100644 index 000000000..d3c321e72 --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/custom-bool.rs @@ -0,0 +1,32 @@ +use clap::Parser; + +#[derive(Parser, Debug, PartialEq)] +#[clap(author, version, about, long_about = None)] +struct Opt { + // Default parser for `Set` is FromStr::from_str. + // `impl FromStr for bool` parses `true` or `false` so this + // works as expected. + #[clap(long, action = clap::ArgAction::Set)] + foo: bool, + + // Of course, this could be done with an explicit parser function. + #[clap(long, action = clap::ArgAction::Set, value_parser = true_or_false, default_value_t)] + bar: bool, + + // `bool` can be positional only with explicit `action` annotation + #[clap(action = clap::ArgAction::Set)] + boom: bool, +} + +fn true_or_false(s: &str) -> Result { + match s { + "true" => Ok(true), + "false" => Ok(false), + _ => Err("expected `true` or `false`"), + } +} + +fn main() { + let opt = Opt::parse(); + dbg!(opt); +} diff --git a/vendor/clap-3.2.20/examples/derive_ref/flatten_hand_args.rs b/vendor/clap-3.2.20/examples/derive_ref/flatten_hand_args.rs new file mode 100644 index 000000000..c10e0b29f --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/flatten_hand_args.rs @@ -0,0 +1,81 @@ +use clap::error::Error; +use clap::{Arg, ArgAction, ArgMatches, Args, Command, FromArgMatches, Parser}; + +#[derive(Debug)] +struct CliArgs { + foo: bool, + bar: bool, + quuz: Option, +} + +impl FromArgMatches for CliArgs { + fn from_arg_matches(matches: &ArgMatches) -> Result { + let mut matches = matches.clone(); + Self::from_arg_matches_mut(&mut matches) + } + fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { + Ok(Self { + foo: matches.get_flag("foo"), + bar: matches.get_flag("bar"), + quuz: matches.remove_one::("quuz"), + }) + } + fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { + let mut matches = matches.clone(); + self.update_from_arg_matches_mut(&mut matches) + } + fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { + self.foo |= matches.get_flag("foo"); + self.bar |= matches.get_flag("bar"); + if let Some(quuz) = matches.remove_one::("quuz") { + self.quuz = Some(quuz); + } + Ok(()) + } +} + +impl Args for CliArgs { + fn augment_args(cmd: Command<'_>) -> Command<'_> { + cmd.arg( + Arg::new("foo") + .short('f') + .long("foo") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("bar") + .short('b') + .long("bar") + .action(ArgAction::SetTrue), + ) + .arg(Arg::new("quuz").short('q').long("quuz").takes_value(true)) + } + fn augment_args_for_update(cmd: Command<'_>) -> Command<'_> { + cmd.arg( + Arg::new("foo") + .short('f') + .long("foo") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("bar") + .short('b') + .long("bar") + .action(ArgAction::SetTrue), + ) + .arg(Arg::new("quuz").short('q').long("quuz").takes_value(true)) + } +} + +#[derive(Parser, Debug)] +struct Cli { + #[clap(short, long, action)] + top_level: bool, + #[clap(flatten)] + more_args: CliArgs, +} + +fn main() { + let args = Cli::parse(); + println!("{:#?}", args); +} diff --git a/vendor/clap-3.2.20/examples/derive_ref/hand_subcommand.rs b/vendor/clap-3.2.20/examples/derive_ref/hand_subcommand.rs new file mode 100644 index 000000000..e9423bdc0 --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/hand_subcommand.rs @@ -0,0 +1,81 @@ +use clap::error::{Error, ErrorKind}; +use clap::{ArgMatches, Args as _, Command, FromArgMatches, Parser, Subcommand}; + +#[derive(Parser, Debug)] +struct AddArgs { + #[clap(value_parser)] + name: Vec, +} +#[derive(Parser, Debug)] +struct RemoveArgs { + #[clap(short, long, action)] + force: bool, + #[clap(value_parser)] + name: Vec, +} + +#[derive(Debug)] +enum CliSub { + Add(AddArgs), + Remove(RemoveArgs), +} + +impl FromArgMatches for CliSub { + fn from_arg_matches(matches: &ArgMatches) -> Result { + match matches.subcommand() { + Some(("add", args)) => Ok(Self::Add(AddArgs::from_arg_matches(args)?)), + Some(("remove", args)) => Ok(Self::Remove(RemoveArgs::from_arg_matches(args)?)), + Some((_, _)) => Err(Error::raw( + ErrorKind::UnrecognizedSubcommand, + "Valid subcommands are `add` and `remove`", + )), + None => Err(Error::raw( + ErrorKind::MissingSubcommand, + "Valid subcommands are `add` and `remove`", + )), + } + } + fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { + match matches.subcommand() { + Some(("add", args)) => *self = Self::Add(AddArgs::from_arg_matches(args)?), + Some(("remove", args)) => *self = Self::Remove(RemoveArgs::from_arg_matches(args)?), + Some((_, _)) => { + return Err(Error::raw( + ErrorKind::UnrecognizedSubcommand, + "Valid subcommands are `add` and `remove`", + )) + } + None => (), + }; + Ok(()) + } +} + +impl Subcommand for CliSub { + fn augment_subcommands(cmd: Command<'_>) -> Command<'_> { + cmd.subcommand(AddArgs::augment_args(Command::new("add"))) + .subcommand(RemoveArgs::augment_args(Command::new("remove"))) + .subcommand_required(true) + } + fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_> { + cmd.subcommand(AddArgs::augment_args(Command::new("add"))) + .subcommand(RemoveArgs::augment_args(Command::new("remove"))) + .subcommand_required(true) + } + fn has_subcommand(name: &str) -> bool { + matches!(name, "add" | "remove") + } +} + +#[derive(Parser, Debug)] +struct Cli { + #[clap(short, long, action)] + top_level: bool, + #[clap(subcommand)] + subcommand: CliSub, +} + +fn main() { + let args = Cli::parse(); + println!("{:#?}", args); +} diff --git a/vendor/clap-3.2.20/examples/derive_ref/interop_tests.md b/vendor/clap-3.2.20/examples/derive_ref/interop_tests.md new file mode 100644 index 000000000..746fe1878 --- /dev/null +++ b/vendor/clap-3.2.20/examples/derive_ref/interop_tests.md @@ -0,0 +1,256 @@ +Following are tests for the interop examples in this directory. + +## Augment Args + +```console +$ interop_augment_args +Value of built: false +Value of derived via ArgMatches: false +Value of derived: DerivedArgs { + derived: false, +} + +``` + +```console +$ interop_augment_args -b --derived +Value of built: true +Value of derived via ArgMatches: true +Value of derived: DerivedArgs { + derived: true, +} + +``` + +```console +$ interop_augment_args -d --built +Value of built: true +Value of derived via ArgMatches: true +Value of derived: DerivedArgs { + derived: true, +} + +``` + +```console +$ interop_augment_args --unknown +? failed +error: Found argument '--unknown' which wasn't expected, or isn't valid in this context + + If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` + +USAGE: + interop_augment_args[EXE] [OPTIONS] + +For more information try --help + +``` + +## Augment Subcommands + +```console +$ interop_augment_subcommands +? failed +error: A subcommand is required but one was not provided. +``` + +```console +$ interop_augment_subcommands derived +Derived subcommands: Derived { + derived_flag: false, +} + +``` + +```console +$ interop_augment_subcommands derived --derived-flag +Derived subcommands: Derived { + derived_flag: true, +} + +``` + +```console +$ interop_augment_subcommands derived --unknown +? failed +error: Found argument '--unknown' which wasn't expected, or isn't valid in this context + + If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` + +USAGE: + interop_augment_subcommands[EXE] derived [OPTIONS] + +For more information try --help + +``` + +```console +$ interop_augment_subcommands unknown +? failed +error: Found argument 'unknown' which wasn't expected, or isn't valid in this context + +USAGE: + interop_augment_subcommands[EXE] [SUBCOMMAND] + +For more information try --help + +``` + +## Hand-Implemented Subcommand + +```console +$ interop_hand_subcommand +? failed +error: 'interop_hand_subcommand[EXE]' requires a subcommand but one was not provided + +USAGE: + interop_hand_subcommand[EXE] [OPTIONS] + +For more information try --help + +``` + +```console +$ interop_hand_subcommand add +Cli { + top_level: false, + subcommand: Add( + AddArgs { + name: [], + }, + ), +} + +``` + +```console +$ interop_hand_subcommand add a b c +Cli { + top_level: false, + subcommand: Add( + AddArgs { + name: [ + "a", + "b", + "c", + ], + }, + ), +} + +``` + +```console +$ interop_hand_subcommand add --unknown +? failed +error: Found argument '--unknown' which wasn't expected, or isn't valid in this context + + If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` + +USAGE: + interop_hand_subcommand[EXE] add [NAME]... + +For more information try --help + +``` + +```console +$ interop_hand_subcommand remove +Cli { + top_level: false, + subcommand: Remove( + RemoveArgs { + force: false, + name: [], + }, + ), +} + +``` + +```console +$ interop_hand_subcommand remove --force a b c +Cli { + top_level: false, + subcommand: Remove( + RemoveArgs { + force: true, + name: [ + "a", + "b", + "c", + ], + }, + ), +} + +``` + +```console +$ interop_hand_subcommand unknown +? failed +error: Found argument 'unknown' which wasn't expected, or isn't valid in this context + +USAGE: + interop_hand_subcommand[EXE] [OPTIONS] + +For more information try --help + +``` + +## Flatten Hand-Implemented Args + +```console +$ interop_flatten_hand_args +Cli { + top_level: false, + more_args: CliArgs { + foo: false, + bar: false, + quuz: None, + }, +} + +``` + +```console +$ interop_flatten_hand_args -f --bar +Cli { + top_level: false, + more_args: CliArgs { + foo: true, + bar: true, + quuz: None, + }, +} + +``` + +```console +$ interop_flatten_hand_args --quuz abc +Cli { + top_level: false, + more_args: CliArgs { + foo: false, + bar: false, + quuz: Some( + "abc", + ), + }, +} + +``` + +```console +$ interop_flatten_hand_args --unknown +? failed +error: Found argument '--unknown' which wasn't expected, or isn't valid in this context + + If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` + +USAGE: + interop_flatten_hand_args[EXE] [OPTIONS] + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/escaped-positional-derive.md b/vendor/clap-3.2.20/examples/escaped-positional-derive.md new file mode 100644 index 000000000..fa39a2c03 --- /dev/null +++ b/vendor/clap-3.2.20/examples/escaped-positional-derive.md @@ -0,0 +1,63 @@ +**This requires enabling the [`derive` feature flag][crate::_features].** + +You can use `--` to escape further arguments. + +Let's see what this looks like in the help: +```console +$ escaped-positional-derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + escaped-positional-derive[EXE] [OPTIONS] [-- ...] + +ARGS: + ... + +OPTIONS: + -f + -h, --help Print help information + -p + -V, --version Print version information + +``` + +Here is a baseline without any arguments: +```console +$ escaped-positional-derive +-f used: false +-p's value: None +'slops' values: [] + +``` + +Notice that we can't pass positional arguments before `--`: +```console +$ escaped-positional-derive foo bar +? failed +error: Found argument 'foo' which wasn't expected, or isn't valid in this context + +USAGE: + escaped-positional-derive[EXE] [OPTIONS] [-- ...] + +For more information try --help + +``` + +But you can after: +```console +$ escaped-positional-derive -f -p=bob -- sloppy slop slop +-f used: true +-p's value: Some("bob") +'slops' values: ["sloppy", "slop", "slop"] + +``` + +As mentioned, the parser will directly pass everything through: +```console +$ escaped-positional-derive -- -f -p=bob sloppy slop slop +-f used: false +-p's value: None +'slops' values: ["-f", "-p=bob", "sloppy", "slop", "slop"] + +``` diff --git a/vendor/clap-3.2.20/examples/escaped-positional-derive.rs b/vendor/clap-3.2.20/examples/escaped-positional-derive.rs new file mode 100644 index 000000000..fd8fde4ed --- /dev/null +++ b/vendor/clap-3.2.20/examples/escaped-positional-derive.rs @@ -0,0 +1,25 @@ +use clap::Parser; + +#[derive(Parser)] // requires `derive` feature +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short = 'f', action)] + eff: bool, + + #[clap(short = 'p', value_name = "PEAR", value_parser)] + pea: Option, + + #[clap(last = true, value_parser)] + slop: Vec, +} + +fn main() { + let args = Cli::parse(); + + // This is what will happen with `myprog -f -p=bob -- sloppy slop slop`... + println!("-f used: {:?}", args.eff); // -f used: true + println!("-p's value: {:?}", args.pea); // -p's value: Some("bob") + println!("'slops' values: {:?}", args.slop); // 'slops' values: Some(["sloppy", "slop", "slop"]) + + // Continued program logic goes here... +} diff --git a/vendor/clap-3.2.20/examples/escaped-positional.md b/vendor/clap-3.2.20/examples/escaped-positional.md new file mode 100644 index 000000000..987b26139 --- /dev/null +++ b/vendor/clap-3.2.20/examples/escaped-positional.md @@ -0,0 +1,63 @@ +**This requires enabling the [`cargo` feature flag][crate::_features].** + +You can use `--` to escape further arguments. + +Let's see what this looks like in the help: +```console +$ escaped-positional --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + escaped-positional[EXE] [OPTIONS] [-- ...] + +ARGS: + ... + +OPTIONS: + -f + -h, --help Print help information + -p + -V, --version Print version information + +``` + +Here is a baseline without any arguments: +```console +$ escaped-positional +-f used: false +-p's value: None +'slops' values: [] + +``` + +Notice that we can't pass positional arguments before `--`: +```console +$ escaped-positional foo bar +? failed +error: Found argument 'foo' which wasn't expected, or isn't valid in this context + +USAGE: + escaped-positional[EXE] [OPTIONS] [-- ...] + +For more information try --help + +``` + +But you can after: +```console +$ escaped-positional -f -p=bob -- sloppy slop slop +-f used: true +-p's value: Some("bob") +'slops' values: ["sloppy", "slop", "slop"] + +``` + +As mentioned, the parser will directly pass everything through: +```console +$ escaped-positional -- -f -p=bob sloppy slop slop +-f used: false +-p's value: None +'slops' values: ["-f", "-p=bob", "sloppy", "slop", "slop"] + +``` diff --git a/vendor/clap-3.2.20/examples/escaped-positional.rs b/vendor/clap-3.2.20/examples/escaped-positional.rs new file mode 100644 index 000000000..fdcb930fb --- /dev/null +++ b/vendor/clap-3.2.20/examples/escaped-positional.rs @@ -0,0 +1,36 @@ +use clap::{arg, command, value_parser, ArgAction}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg(arg!(eff: -f).action(ArgAction::SetTrue)) + .arg( + arg!(pea: -p ) + .required(false) + .value_parser(value_parser!(String)), + ) + .arg( + // Indicates that `slop` is only accessible after `--`. + arg!(slop: [SLOP]) + .multiple_values(true) + .last(true) + .value_parser(value_parser!(String)), + ) + .get_matches(); + + // This is what will happen with `myprog -f -p=bob -- sloppy slop slop`... + + // -f used: true + println!("-f used: {:?}", matches.get_flag("eff")); + // -p's value: Some("bob") + println!("-p's value: {:?}", matches.get_one::("pea")); + // 'slops' values: Some(["sloppy", "slop", "slop"]) + println!( + "'slops' values: {:?}", + matches + .get_many::("slop") + .map(|vals| vals.collect::>()) + .unwrap_or_default() + ); + + // Continued program logic goes here... +} diff --git a/vendor/clap-3.2.20/examples/git-derive.md b/vendor/clap-3.2.20/examples/git-derive.md new file mode 100644 index 000000000..aa1ca6d9d --- /dev/null +++ b/vendor/clap-3.2.20/examples/git-derive.md @@ -0,0 +1,138 @@ +**This requires enabling the [`derive` feature flag][crate::_features].** + +Git is an example of several common subcommand patterns. + +Help: +```console +$ git-derive +? failed +git +A fictional versioning CLI + +USAGE: + git-derive[EXE] + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + add adds things + clone Clones repos + help Print this message or the help of the given subcommand(s) + push pushes things + stash + +$ git-derive help +git +A fictional versioning CLI + +USAGE: + git-derive[EXE] + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + add adds things + clone Clones repos + help Print this message or the help of the given subcommand(s) + push pushes things + stash + +$ git-derive help add +git-derive[EXE]-add +adds things + +USAGE: + git-derive[EXE] add ... + +ARGS: + ... Stuff to add + +OPTIONS: + -h, --help Print help information + +``` + +A basic argument: +```console +$ git-derive add +? failed +git-derive[EXE]-add +adds things + +USAGE: + git-derive[EXE] add ... + +ARGS: + ... Stuff to add + +OPTIONS: + -h, --help Print help information + +$ git-derive add Cargo.toml Cargo.lock +Adding ["Cargo.toml", "Cargo.lock"] + +``` + +Default subcommand: +```console +$ git-derive stash -h +git-derive[EXE]-stash + +USAGE: + git-derive[EXE] stash [OPTIONS] + git-derive[EXE] stash + +OPTIONS: + -h, --help Print help information + -m, --message + +SUBCOMMANDS: + apply + help Print this message or the help of the given subcommand(s) + pop + push + +$ git-derive stash push -h +git-derive[EXE]-stash-push + +USAGE: + git-derive[EXE] stash push [OPTIONS] + +OPTIONS: + -h, --help Print help information + -m, --message + +$ git-derive stash pop -h +git-derive[EXE]-stash-pop + +USAGE: + git-derive[EXE] stash pop [STASH] + +ARGS: + + +OPTIONS: + -h, --help Print help information + +$ git-derive stash -m "Prototype" +Pushing StashPush { message: Some("Prototype") } + +$ git-derive stash pop +Popping None + +$ git-derive stash push -m "Prototype" +Pushing StashPush { message: Some("Prototype") } + +$ git-derive stash pop +Popping None + +``` + +External subcommands: +```console +$ git-derive custom-tool arg1 --foo bar +Calling out to "custom-tool" with ["arg1", "--foo", "bar"] + +``` diff --git a/vendor/clap-3.2.20/examples/git-derive.rs b/vendor/clap-3.2.20/examples/git-derive.rs new file mode 100644 index 000000000..ac500ddad --- /dev/null +++ b/vendor/clap-3.2.20/examples/git-derive.rs @@ -0,0 +1,105 @@ +use std::ffi::OsString; +use std::path::PathBuf; + +use clap::{Args, Parser, Subcommand}; + +/// A fictional versioning CLI +#[derive(Debug, Parser)] // requires `derive` feature +#[clap(name = "git")] +#[clap(about = "A fictional versioning CLI", long_about = None)] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Debug, Subcommand)] +enum Commands { + /// Clones repos + #[clap(arg_required_else_help = true)] + Clone { + /// The remote to clone + #[clap(value_parser)] + remote: String, + }, + /// pushes things + #[clap(arg_required_else_help = true)] + Push { + /// The remote to target + #[clap(value_parser)] + remote: String, + }, + /// adds things + #[clap(arg_required_else_help = true)] + Add { + /// Stuff to add + #[clap(required = true, value_parser)] + path: Vec, + }, + Stash(Stash), + #[clap(external_subcommand)] + External(Vec), +} + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true)] +struct Stash { + #[clap(subcommand)] + command: Option, + + #[clap(flatten)] + push: StashPush, +} + +#[derive(Debug, Subcommand)] +enum StashCommands { + Push(StashPush), + Pop { + #[clap(value_parser)] + stash: Option, + }, + Apply { + #[clap(value_parser)] + stash: Option, + }, +} + +#[derive(Debug, Args)] +struct StashPush { + #[clap(short, long, value_parser)] + message: Option, +} + +fn main() { + let args = Cli::parse(); + + match args.command { + Commands::Clone { remote } => { + println!("Cloning {}", remote); + } + Commands::Push { remote } => { + println!("Pushing to {}", remote); + } + Commands::Add { path } => { + println!("Adding {:?}", path); + } + Commands::Stash(stash) => { + let stash_cmd = stash.command.unwrap_or(StashCommands::Push(stash.push)); + match stash_cmd { + StashCommands::Push(push) => { + println!("Pushing {:?}", push); + } + StashCommands::Pop { stash } => { + println!("Popping {:?}", stash); + } + StashCommands::Apply { stash } => { + println!("Applying {:?}", stash); + } + } + } + Commands::External(args) => { + println!("Calling out to {:?} with {:?}", &args[0], &args[1..]); + } + } + + // Continued program logic goes here... +} diff --git a/vendor/clap-3.2.20/examples/git.md b/vendor/clap-3.2.20/examples/git.md new file mode 100644 index 000000000..9e413415a --- /dev/null +++ b/vendor/clap-3.2.20/examples/git.md @@ -0,0 +1,136 @@ +Git is an example of several common subcommand patterns. + +Help: +```console +$ git +? failed +git +A fictional versioning CLI + +USAGE: + git[EXE] + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + add adds things + clone Clones repos + help Print this message or the help of the given subcommand(s) + push pushes things + stash + +$ git help +git +A fictional versioning CLI + +USAGE: + git[EXE] + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + add adds things + clone Clones repos + help Print this message or the help of the given subcommand(s) + push pushes things + stash + +$ git help add +git[EXE]-add +adds things + +USAGE: + git[EXE] add ... + +ARGS: + ... Stuff to add + +OPTIONS: + -h, --help Print help information + +``` + +A basic argument: +```console +$ git add +? failed +git[EXE]-add +adds things + +USAGE: + git[EXE] add ... + +ARGS: + ... Stuff to add + +OPTIONS: + -h, --help Print help information + +$ git add Cargo.toml Cargo.lock +Adding ["Cargo.toml", "Cargo.lock"] + +``` + +Default subcommand: +```console +$ git stash -h +git[EXE]-stash + +USAGE: + git[EXE] stash [OPTIONS] + git[EXE] stash + +OPTIONS: + -h, --help Print help information + -m, --message + +SUBCOMMANDS: + apply + help Print this message or the help of the given subcommand(s) + pop + push + +$ git stash push -h +git[EXE]-stash-push + +USAGE: + git[EXE] stash push [OPTIONS] + +OPTIONS: + -h, --help Print help information + -m, --message + +$ git stash pop -h +git[EXE]-stash-pop + +USAGE: + git[EXE] stash pop [STASH] + +ARGS: + + +OPTIONS: + -h, --help Print help information + +$ git stash -m "Prototype" +Pushing Some("Prototype") + +$ git stash pop +Popping None + +$ git stash push -m "Prototype" +Pushing Some("Prototype") + +$ git stash pop +Popping None + +``` + +External subcommands: +```console +$ git custom-tool arg1 --foo bar +Calling out to "custom-tool" with ["arg1", "--foo", "bar"] + +``` diff --git a/vendor/clap-3.2.20/examples/git.rs b/vendor/clap-3.2.20/examples/git.rs new file mode 100644 index 000000000..e56f427a6 --- /dev/null +++ b/vendor/clap-3.2.20/examples/git.rs @@ -0,0 +1,101 @@ +use std::ffi::OsString; +use std::path::PathBuf; + +use clap::{arg, Command}; + +fn cli() -> Command<'static> { + Command::new("git") + .about("A fictional versioning CLI") + .subcommand_required(true) + .arg_required_else_help(true) + .allow_external_subcommands(true) + .allow_invalid_utf8_for_external_subcommands(true) + .subcommand( + Command::new("clone") + .about("Clones repos") + .arg(arg!( "The remote to clone")) + .arg_required_else_help(true), + ) + .subcommand( + Command::new("push") + .about("pushes things") + .arg(arg!( "The remote to target")) + .arg_required_else_help(true), + ) + .subcommand( + Command::new("add") + .about("adds things") + .arg_required_else_help(true) + .arg(arg!( ... "Stuff to add").value_parser(clap::value_parser!(PathBuf))), + ) + .subcommand( + Command::new("stash") + .args_conflicts_with_subcommands(true) + .args(push_args()) + .subcommand(Command::new("push").args(push_args())) + .subcommand(Command::new("pop").arg(arg!([STASH]))) + .subcommand(Command::new("apply").arg(arg!([STASH]))), + ) +} + +fn push_args() -> Vec> { + vec![arg!(-m --message ).required(false)] +} + +fn main() { + let matches = cli().get_matches(); + + match matches.subcommand() { + Some(("clone", sub_matches)) => { + println!( + "Cloning {}", + sub_matches.get_one::("REMOTE").expect("required") + ); + } + Some(("push", sub_matches)) => { + println!( + "Pushing to {}", + sub_matches.get_one::("REMOTE").expect("required") + ); + } + Some(("add", sub_matches)) => { + let paths = sub_matches + .get_many::("PATH") + .into_iter() + .flatten() + .collect::>(); + println!("Adding {:?}", paths); + } + Some(("stash", sub_matches)) => { + let stash_command = sub_matches.subcommand().unwrap_or(("push", sub_matches)); + match stash_command { + ("apply", sub_matches) => { + let stash = sub_matches.get_one::("STASH"); + println!("Applying {:?}", stash); + } + ("pop", sub_matches) => { + let stash = sub_matches.get_one::("STASH"); + println!("Popping {:?}", stash); + } + ("push", sub_matches) => { + let message = sub_matches.get_one::("message"); + println!("Pushing {:?}", message); + } + (name, _) => { + unreachable!("Unsupported subcommand `{}`", name) + } + } + } + Some((ext, sub_matches)) => { + let args = sub_matches + .get_many::("") + .into_iter() + .flatten() + .collect::>(); + println!("Calling out to {:?} with {:?}", ext, args); + } + _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!() + } + + // Continued program logic goes here... +} diff --git a/vendor/clap-3.2.20/examples/multicall-busybox.md b/vendor/clap-3.2.20/examples/multicall-busybox.md new file mode 100644 index 000000000..5ca2cad5b --- /dev/null +++ b/vendor/clap-3.2.20/examples/multicall-busybox.md @@ -0,0 +1,42 @@ +See the documentation for [`Command::multicall`][crate::App::multicall] for rationale. + +This example omits every command except true and false, +which are the most trivial to implement, +```console +$ busybox true +? 0 + +$ busybox false +? 1 + +``` +*Note: without the links setup, we can't demonstrate the multicall behavior* + +But includes the `--install` option as an example of why it can be useful +for the main program to take arguments that aren't applet subcommands. +```console +$ busybox --install +? failed +... + +``` + +Though users must pass something: +```console +$ busybox +? failed +busybox + +USAGE: + busybox [OPTIONS] [APPLET] + +OPTIONS: + -h, --help Print help information + --install Install hardlinks for all subcommands in path + +APPLETS: + false does nothing unsuccessfully + help Print this message or the help of the given subcommand(s) + true does nothing successfully + +``` diff --git a/vendor/clap-3.2.20/examples/multicall-busybox.rs b/vendor/clap-3.2.20/examples/multicall-busybox.rs new file mode 100644 index 000000000..2e7f976c1 --- /dev/null +++ b/vendor/clap-3.2.20/examples/multicall-busybox.rs @@ -0,0 +1,48 @@ +use std::path::PathBuf; +use std::process::exit; + +use clap::{value_parser, Arg, Command}; + +fn applet_commands() -> [Command<'static>; 2] { + [ + Command::new("true").about("does nothing successfully"), + Command::new("false").about("does nothing unsuccessfully"), + ] +} + +fn main() { + let cmd = Command::new(env!("CARGO_CRATE_NAME")) + .multicall(true) + .subcommand( + Command::new("busybox") + .arg_required_else_help(true) + .subcommand_value_name("APPLET") + .subcommand_help_heading("APPLETS") + .arg( + Arg::new("install") + .long("install") + .help("Install hardlinks for all subcommands in path") + .exclusive(true) + .takes_value(true) + .default_missing_value("/usr/local/bin") + .value_parser(value_parser!(PathBuf)) + .use_value_delimiter(false), + ) + .subcommands(applet_commands()), + ) + .subcommands(applet_commands()); + + let matches = cmd.get_matches(); + let mut subcommand = matches.subcommand(); + if let Some(("busybox", cmd)) = subcommand { + if cmd.contains_id("install") { + unimplemented!("Make hardlinks to the executable here"); + } + subcommand = cmd.subcommand(); + } + match subcommand { + Some(("false", _)) => exit(1), + Some(("true", _)) => exit(0), + _ => unreachable!("parser should ensure only valid subcommand names are used"), + } +} diff --git a/vendor/clap-3.2.20/examples/multicall-hostname.md b/vendor/clap-3.2.20/examples/multicall-hostname.md new file mode 100644 index 000000000..d22b85fba --- /dev/null +++ b/vendor/clap-3.2.20/examples/multicall-hostname.md @@ -0,0 +1,10 @@ +See the documentation for [`Command::multicall`][crate::App::multicall] for rationale. + +This example omits the implementation of displaying address config + +```console +$ hostname +www + +``` +*Note: without the links setup, we can't demonstrate the multicall behavior* diff --git a/vendor/clap-3.2.20/examples/multicall-hostname.rs b/vendor/clap-3.2.20/examples/multicall-hostname.rs new file mode 100644 index 000000000..b57680a5c --- /dev/null +++ b/vendor/clap-3.2.20/examples/multicall-hostname.rs @@ -0,0 +1,17 @@ +use clap::Command; + +fn main() { + let cmd = Command::new(env!("CARGO_CRATE_NAME")) + .multicall(true) + .arg_required_else_help(true) + .subcommand_value_name("APPLET") + .subcommand_help_heading("APPLETS") + .subcommand(Command::new("hostname").about("show hostname part of FQDN")) + .subcommand(Command::new("dnsdomainname").about("show domain name part of FQDN")); + + match cmd.get_matches().subcommand_name() { + Some("hostname") => println!("www"), + Some("dnsdomainname") => println!("example.com"), + _ => unreachable!("parser should ensure only valid subcommand names are used"), + } +} diff --git a/vendor/clap-3.2.20/examples/pacman.md b/vendor/clap-3.2.20/examples/pacman.md new file mode 100644 index 000000000..b8ddd09d9 --- /dev/null +++ b/vendor/clap-3.2.20/examples/pacman.md @@ -0,0 +1,85 @@ +[`pacman`](https://wiki.archlinux.org/index.php/pacman) defines subcommands via flags. + +Here, `-S` is a short flag subcommand: +```console +$ pacman -S package +Installing package... + +``` + +Here `--sync` is a long flag subcommand: +```console +$ pacman --sync package +Installing package... + +``` + +Now the short flag subcommand (`-S`) with a long flag: +```console +$ pacman -S --search name +Searching for name... + +``` + +And the various forms of short flags that work: +```console +$ pacman -S -s name +Searching for name... + +$ pacman -Ss name +Searching for name... + +``` +*(users can "stack" short subcommands with short flags or with other short flag subcommands)* + +In the help, this looks like: +```console +$ pacman -h +pacman 5.2.1 +Pacman Development Team +package manager utility + +USAGE: + pacman[EXE] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + help Print this message or the help of the given subcommand(s) + query -Q --query Query the package database. + sync -S --sync Synchronize packages. + +$ pacman -S -h +pacman[EXE]-sync +Synchronize packages. + +USAGE: + pacman[EXE] {sync|--sync|-S} [OPTIONS] [--] [package]... + +ARGS: + ... packages + +OPTIONS: + -h, --help Print help information + -i, --info view package information + -s, --search ... search remote repositories for matching strings + +``` + +And errors: +```console +$ pacman -S -s foo -i bar +? failed +error: The argument '--search ...' cannot be used with '--info' + +USAGE: + pacman[EXE] {sync|--sync|-S} --search ... ... + +For more information try --help + +``` + +**NOTE:** Keep in mind that subcommands, flags, and long flags are *case sensitive*: `-Q` and `-q` are different flags/subcommands. For example, you can have both `-Q` subcommand and `-q` flag, and they will be properly disambiguated. +Let's make a quick program to illustrate. diff --git a/vendor/clap-3.2.20/examples/pacman.rs b/vendor/clap-3.2.20/examples/pacman.rs new file mode 100644 index 000000000..aee7cd892 --- /dev/null +++ b/vendor/clap-3.2.20/examples/pacman.rs @@ -0,0 +1,111 @@ +use clap::{Arg, ArgAction, Command}; + +fn main() { + let matches = Command::new("pacman") + .about("package manager utility") + .version("5.2.1") + .subcommand_required(true) + .arg_required_else_help(true) + .author("Pacman Development Team") + // Query subcommand + // + // Only a few of its arguments are implemented below. + .subcommand( + Command::new("query") + .short_flag('Q') + .long_flag("query") + .about("Query the package database.") + .arg( + Arg::new("search") + .short('s') + .long("search") + .help("search locally installed packages for matching strings") + .conflicts_with("info") + .takes_value(true) + .multiple_values(true), + ) + .arg( + Arg::new("info") + .long("info") + .short('i') + .conflicts_with("search") + .help("view package information") + .takes_value(true) + .multiple_values(true), + ), + ) + // Sync subcommand + // + // Only a few of its arguments are implemented below. + .subcommand( + Command::new("sync") + .short_flag('S') + .long_flag("sync") + .about("Synchronize packages.") + .arg( + Arg::new("search") + .short('s') + .long("search") + .conflicts_with("info") + .takes_value(true) + .multiple_values(true) + .help("search remote repositories for matching strings"), + ) + .arg( + Arg::new("info") + .long("info") + .conflicts_with("search") + .short('i') + .action(ArgAction::SetTrue) + .help("view package information"), + ) + .arg( + Arg::new("package") + .help("packages") + .required_unless_present("search") + .takes_value(true) + .multiple_values(true), + ), + ) + .get_matches(); + + match matches.subcommand() { + Some(("sync", sync_matches)) => { + if sync_matches.contains_id("search") { + let packages: Vec<_> = sync_matches + .get_many::("search") + .expect("contains_id") + .map(|s| s.as_str()) + .collect(); + let values = packages.join(", "); + println!("Searching for {}...", values); + return; + } + + let packages: Vec<_> = sync_matches + .get_many::("package") + .expect("is present") + .map(|s| s.as_str()) + .collect(); + let values = packages.join(", "); + + if sync_matches.get_flag("info") { + println!("Retrieving info for {}...", values); + } else { + println!("Installing {}...", values); + } + } + Some(("query", query_matches)) => { + if let Some(packages) = query_matches.get_many::("info") { + let comma_sep = packages.map(|s| s.as_str()).collect::>().join(", "); + println!("Retrieving info for {}...", comma_sep); + } else if let Some(queries) = query_matches.get_many::("search") { + let comma_sep = queries.map(|s| s.as_str()).collect::>().join(", "); + println!("Searching Locally for {}...", comma_sep); + } else { + println!("Displaying all locally installed packages..."); + } + } + _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable + } +} diff --git a/vendor/clap-3.2.20/examples/repl.rs b/vendor/clap-3.2.20/examples/repl.rs new file mode 100644 index 000000000..c509adee6 --- /dev/null +++ b/vendor/clap-3.2.20/examples/repl.rs @@ -0,0 +1,92 @@ +use std::io::Write; + +use clap::Command; + +fn main() -> Result<(), String> { + loop { + let line = readline()?; + let line = line.trim(); + if line.is_empty() { + continue; + } + + match respond(line) { + Ok(quit) => { + if quit { + break; + } + } + Err(err) => { + write!(std::io::stdout(), "{}", err).map_err(|e| e.to_string())?; + std::io::stdout().flush().map_err(|e| e.to_string())?; + } + } + } + + Ok(()) +} + +fn respond(line: &str) -> Result { + let args = shlex::split(line).ok_or("error: Invalid quoting")?; + let matches = cli() + .try_get_matches_from(&args) + .map_err(|e| e.to_string())?; + match matches.subcommand() { + Some(("ping", _matches)) => { + write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?; + std::io::stdout().flush().map_err(|e| e.to_string())?; + } + Some(("quit", _matches)) => { + write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?; + std::io::stdout().flush().map_err(|e| e.to_string())?; + return Ok(true); + } + Some((name, _matches)) => unimplemented!("{}", name), + None => unreachable!("subcommand required"), + } + + Ok(false) +} + +fn cli() -> Command<'static> { + // strip out usage + const PARSER_TEMPLATE: &str = "\ + {all-args} + "; + // strip out name/version + const APPLET_TEMPLATE: &str = "\ + {about-with-newline}\n\ + {usage-heading}\n {usage}\n\ + \n\ + {all-args}{after-help}\ + "; + + Command::new("repl") + .multicall(true) + .arg_required_else_help(true) + .subcommand_required(true) + .subcommand_value_name("APPLET") + .subcommand_help_heading("APPLETS") + .help_template(PARSER_TEMPLATE) + .subcommand( + Command::new("ping") + .about("Get a response") + .help_template(APPLET_TEMPLATE), + ) + .subcommand( + Command::new("quit") + .alias("exit") + .about("Quit the REPL") + .help_template(APPLET_TEMPLATE), + ) +} + +fn readline() -> Result { + write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?; + std::io::stdout().flush().map_err(|e| e.to_string())?; + let mut buffer = String::new(); + std::io::stdin() + .read_line(&mut buffer) + .map_err(|e| e.to_string())?; + Ok(buffer) +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/01_quick.md b/vendor/clap-3.2.20/examples/tutorial_builder/01_quick.md new file mode 100644 index 000000000..4a9e3fca1 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/01_quick.md @@ -0,0 +1,37 @@ +```console +$ 01_quick --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 01_quick[EXE] [OPTIONS] [name] [SUBCOMMAND] + +ARGS: + Optional name to operate on + +OPTIONS: + -c, --config Sets a custom config file + -d, --debug Turn debugging information on + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + help Print this message or the help of the given subcommand(s) + test does testing things + +``` + +By default, the program does nothing: +```console +$ 01_quick +Debug mode is off + +``` + +But you can mix and match the various features +```console +$ 01_quick -dd test +Debug mode is on +Not printing testing lists... + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/01_quick.rs b/vendor/clap-3.2.20/examples/tutorial_builder/01_quick.rs new file mode 100644 index 000000000..393d6aeae --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/01_quick.rs @@ -0,0 +1,63 @@ +use std::path::PathBuf; + +use clap::{arg, command, value_parser, ArgAction, Command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg(arg!([name] "Optional name to operate on")) + .arg( + arg!( + -c --config "Sets a custom config file" + ) + // We don't have syntax yet for optional options, so manually calling `required` + .required(false) + .value_parser(value_parser!(PathBuf)), + ) + .arg( + arg!( + -d --debug "Turn debugging information on" + ) + .action(ArgAction::Count), + ) + .subcommand( + Command::new("test") + .about("does testing things") + .arg(arg!(-l --list "lists test values").action(ArgAction::SetTrue)), + ) + .get_matches(); + + // You can check the value provided by positional arguments, or option arguments + if let Some(name) = matches.get_one::("name") { + println!("Value for name: {}", name); + } + + if let Some(config_path) = matches.get_one::("config") { + println!("Value for config: {}", config_path.display()); + } + + // You can see how many times a particular flag or argument occurred + // Note, only flags can have multiple occurrences + match matches + .get_one::("debug") + .expect("Count's are defaulted") + { + 0 => println!("Debug mode is off"), + 1 => println!("Debug mode is kind of on"), + 2 => println!("Debug mode is on"), + _ => println!("Don't be crazy"), + } + + // You can check for the existence of subcommands, and if found use their + // matches just as you would the top level cmd + if let Some(matches) = matches.subcommand_matches("test") { + // "$ myapp test" was run + if *matches.get_one::("list").expect("defaulted by clap") { + // "$ myapp test -l" was run + println!("Printing testing lists..."); + } else { + println!("Not printing testing lists..."); + } + } + + // Continued program logic goes here... +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.md b/vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.md new file mode 100644 index 000000000..247843bcf --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.md @@ -0,0 +1,19 @@ +```console +$ 02_app_settings --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 02_app_settings[EXE] --two --one + +OPTIONS: + --two + --one + -h, --help Print help information + -V, --version Print version information + +$ 02_app_settings --one -1 --one -3 --two 10 +two: "10" +one: "-3" + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.rs b/vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.rs new file mode 100644 index 000000000..5f374d7f0 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/02_app_settings.rs @@ -0,0 +1,19 @@ +use clap::{arg, command, AppSettings, ArgAction}; + +fn main() { + let matches = command!() // requires `cargo` feature + .global_setting(AppSettings::DeriveDisplayOrder) + .allow_negative_numbers(true) + .arg(arg!(--two ).action(ArgAction::Set)) + .arg(arg!(--one ).action(ArgAction::Set)) + .get_matches(); + + println!( + "two: {:?}", + matches.get_one::("two").expect("required") + ); + println!( + "one: {:?}", + matches.get_one::("one").expect("required") + ); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/02_apps.md b/vendor/clap-3.2.20/examples/tutorial_builder/02_apps.md new file mode 100644 index 000000000..8504b5f52 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/02_apps.md @@ -0,0 +1,19 @@ +```console +$ 02_apps --help +MyApp 1.0 +Kevin K. +Does awesome things + +USAGE: + 02_apps[EXE] --two --one + +OPTIONS: + -h, --help Print help information + --one + --two + -V, --version Print version information + +$ 02_apps --version +MyApp 1.0 + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/02_apps.rs b/vendor/clap-3.2.20/examples/tutorial_builder/02_apps.rs new file mode 100644 index 000000000..db9da18f9 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/02_apps.rs @@ -0,0 +1,20 @@ +use clap::{arg, Command}; + +fn main() { + let matches = Command::new("MyApp") + .version("1.0") + .author("Kevin K. ") + .about("Does awesome things") + .arg(arg!(--two )) + .arg(arg!(--one )) + .get_matches(); + + println!( + "two: {:?}", + matches.get_one::("two").expect("required") + ); + println!( + "one: {:?}", + matches.get_one::("one").expect("required") + ); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/02_crate.md b/vendor/clap-3.2.20/examples/tutorial_builder/02_crate.md new file mode 100644 index 000000000..f76e0d608 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/02_crate.md @@ -0,0 +1,18 @@ +```console +$ 02_crate --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 02_crate[EXE] --two --one + +OPTIONS: + -h, --help Print help information + --one + --two + -V, --version Print version information + +$ 02_crate --version +clap [..] + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/02_crate.rs b/vendor/clap-3.2.20/examples/tutorial_builder/02_crate.rs new file mode 100644 index 000000000..8a1722fd3 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/02_crate.rs @@ -0,0 +1,18 @@ +use clap::{arg, command}; + +fn main() { + // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml` + let matches = command!() + .arg(arg!(--two )) + .arg(arg!(--one )) + .get_matches(); + + println!( + "two: {:?}", + matches.get_one::("two").expect("required") + ); + println!( + "one: {:?}", + matches.get_one::("one").expect("required") + ); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.md b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.md new file mode 100644 index 000000000..b0ee2a126 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.md @@ -0,0 +1,23 @@ +```console +$ 03_01_flag_bool --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_01_flag_bool[EXE] [OPTIONS] + +OPTIONS: + -h, --help Print help information + -v, --verbose + -V, --version Print version information + +$ 03_01_flag_bool +verbose: false + +$ 03_01_flag_bool --verbose +verbose: true + +$ 03_01_flag_bool --verbose --verbose +verbose: true + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.rs b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.rs new file mode 100644 index 000000000..03f2f1756 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_bool.rs @@ -0,0 +1,14 @@ +use clap::{command, Arg, ArgAction}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg( + Arg::new("verbose") + .short('v') + .long("verbose") + .action(ArgAction::SetTrue), + ) + .get_matches(); + + println!("verbose: {:?}", matches.get_flag("verbose")); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.md b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.md new file mode 100644 index 000000000..ca4bcd6eb --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.md @@ -0,0 +1,23 @@ +```console +$ 03_01_flag_count --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_01_flag_count[EXE] [OPTIONS] + +OPTIONS: + -h, --help Print help information + -v, --verbose + -V, --version Print version information + +$ 03_01_flag_count +verbose: 0 + +$ 03_01_flag_count --verbose +verbose: 1 + +$ 03_01_flag_count --verbose --verbose +verbose: 2 + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.rs b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.rs new file mode 100644 index 000000000..7f23649d6 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_01_flag_count.rs @@ -0,0 +1,9 @@ +use clap::{arg, command, ArgAction}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg(arg!(-v - -verbose).action(ArgAction::Count)) + .get_matches(); + + println!("verbose: {:?}", matches.get_count("verbose")); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.md b/vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.md new file mode 100644 index 000000000..6198bcc73 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.md @@ -0,0 +1,32 @@ +```console +$ 03_02_option --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_02_option[EXE] [OPTIONS] + +OPTIONS: + -h, --help Print help information + -n, --name + -V, --version Print version information + +$ 03_02_option +name: None + +$ 03_02_option --name bob +name: Some("bob") + +$ 03_02_option --name=bob +name: Some("bob") + +$ 03_02_option -n bob +name: Some("bob") + +$ 03_02_option -n=bob +name: Some("bob") + +$ 03_02_option -nbob +name: Some("bob") + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.rs b/vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.rs new file mode 100644 index 000000000..188244566 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_02_option.rs @@ -0,0 +1,9 @@ +use clap::{arg, command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg(arg!(-n --name ).required(false)) + .get_matches(); + + println!("name: {:?}", matches.get_one::("name")); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.md b/vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.md new file mode 100644 index 000000000..a3d7b8cf3 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.md @@ -0,0 +1,22 @@ +```console +$ 03_03_positional --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_03_positional[EXE] [NAME] + +ARGS: + + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 03_03_positional +NAME: None + +$ 03_03_positional bob +NAME: Some("bob") + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.rs b/vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.rs new file mode 100644 index 000000000..0c3a5f037 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_03_positional.rs @@ -0,0 +1,9 @@ +use clap::{arg, command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg(arg!([NAME])) + .get_matches(); + + println!("NAME: {:?}", matches.get_one::("NAME")); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.md b/vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.md new file mode 100644 index 000000000..8f9efa911 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.md @@ -0,0 +1,64 @@ +```console +$ 03_04_subcommands help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_04_subcommands[EXE] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + add Adds files to myapp + help Print this message or the help of the given subcommand(s) + +$ 03_04_subcommands help add +03_04_subcommands[EXE]-add [..] +Adds files to myapp + +USAGE: + 03_04_subcommands[EXE] add [NAME] + +ARGS: + + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 03_04_subcommands add bob +'myapp add' was used, name is: Some("bob") + +``` + +Because we set [`Command::arg_required_else_help`][crate::Command::arg_required_else_help]: +```console +$ 03_04_subcommands +? failed +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_04_subcommands[EXE] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + add Adds files to myapp + help Print this message or the help of the given subcommand(s) + +``` + +Because we set [`Command::propagate_version`][crate::Command::propagate_version]: +```console +$ 03_04_subcommands --version +clap [..] + +$ 03_04_subcommands add --version +03_04_subcommands[EXE]-add [..] + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.rs b/vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.rs new file mode 100644 index 000000000..fbe23809e --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_04_subcommands.rs @@ -0,0 +1,22 @@ +use clap::{arg, command, Command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .propagate_version(true) + .subcommand_required(true) + .arg_required_else_help(true) + .subcommand( + Command::new("add") + .about("Adds files to myapp") + .arg(arg!([NAME])), + ) + .get_matches(); + + match matches.subcommand() { + Some(("add", sub_matches)) => println!( + "'myapp add' was used, name is: {:?}", + sub_matches.get_one::("NAME") + ), + _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"), + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.md b/vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.md new file mode 100644 index 000000000..7b6c0307d --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.md @@ -0,0 +1,22 @@ +```console +$ 03_05_default_values --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_05_default_values[EXE] [NAME] + +ARGS: + [default: alice] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 03_05_default_values +NAME: "alice" + +$ 03_05_default_values bob +NAME: "bob" + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.rs b/vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.rs new file mode 100644 index 000000000..cb3e3831f --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/03_05_default_values.rs @@ -0,0 +1,14 @@ +use clap::{arg, command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg(arg!([NAME]).default_value("alice")) + .get_matches(); + + println!( + "NAME: {:?}", + matches + .get_one::("NAME") + .expect("default ensures there is always a value") + ); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.md b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.md new file mode 100644 index 000000000..282b1e613 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.md @@ -0,0 +1,29 @@ +```console +$ 04_01_enum --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_01_enum[EXE] + +ARGS: + What mode to run the program in [possible values: fast, slow] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_01_enum fast +Hare + +$ 04_01_enum slow +Tortoise + +$ 04_01_enum medium +? failed +error: "medium" isn't a valid value for '' + [possible values: fast, slow] + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.rs b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.rs new file mode 100644 index 000000000..e8cf70f5c --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_enum.rs @@ -0,0 +1,66 @@ +use clap::{arg, builder::PossibleValue, command, value_parser, ValueEnum}; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +enum Mode { + Fast, + Slow, +} + +// Can also be derived] with feature flag `derive` +impl ValueEnum for Mode { + fn value_variants<'a>() -> &'a [Self] { + &[Mode::Fast, Mode::Slow] + } + + fn to_possible_value<'a>(&self) -> Option> { + Some(match self { + Mode::Fast => PossibleValue::new("fast"), + Mode::Slow => PossibleValue::new("slow"), + }) + } +} + +impl std::fmt::Display for Mode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.to_possible_value() + .expect("no values are skipped") + .get_name() + .fmt(f) + } +} + +impl std::str::FromStr for Mode { + type Err = String; + + fn from_str(s: &str) -> Result { + for variant in Self::value_variants() { + if variant.to_possible_value().unwrap().matches(s, false) { + return Ok(*variant); + } + } + Err(format!("Invalid variant: {}", s)) + } +} + +fn main() { + let matches = command!() // requires `cargo` feature + .arg( + arg!() + .help("What mode to run the program in") + .value_parser(value_parser!(Mode)), + ) + .get_matches(); + + // Note, it's safe to call unwrap() because the arg is required + match matches + .get_one::("MODE") + .expect("'MODE' is required and parsing will fail if its missing") + { + Mode::Fast => { + println!("Hare"); + } + Mode::Slow => { + println!("Tortoise"); + } + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.md b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.md new file mode 100644 index 000000000..2909bfb17 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.md @@ -0,0 +1,29 @@ +```console +$ 04_01_possible --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_01_possible[EXE] + +ARGS: + What mode to run the program in [possible values: fast, slow] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_01_possible fast +Hare + +$ 04_01_possible slow +Tortoise + +$ 04_01_possible medium +? failed +error: "medium" isn't a valid value for '' + [possible values: fast, slow] + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.rs b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.rs new file mode 100644 index 000000000..3da7aca74 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_01_possible.rs @@ -0,0 +1,26 @@ +use clap::{arg, command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg( + arg!() + .help("What mode to run the program in") + .value_parser(["fast", "slow"]), + ) + .get_matches(); + + // Note, it's safe to call unwrap() because the arg is required + match matches + .get_one::("MODE") + .expect("'MODE' is required and parsing will fail if its missing") + .as_str() + { + "fast" => { + println!("Hare"); + } + "slow" => { + println!("Tortoise"); + } + _ => unreachable!(), + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.md b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.md new file mode 100644 index 000000000..605bf4b59 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.md @@ -0,0 +1,31 @@ +```console +$ 04_02_parse --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_02_parse[EXE] + +ARGS: + Network port to use + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_02_parse 22 +PORT = 22 + +$ 04_02_parse foobar +? failed +error: Invalid value "foobar" for '': invalid digit found in string + +For more information try --help + +$ 04_02_parse_derive 0 +? failed +error: Invalid value "0" for '': 0 is not in 1..=65535 + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.rs b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.rs new file mode 100644 index 000000000..13f41a18e --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_parse.rs @@ -0,0 +1,17 @@ +use clap::{arg, command, value_parser}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg( + arg!() + .help("Network port to use") + .value_parser(value_parser!(u16).range(1..)), + ) + .get_matches(); + + // Note, it's safe to call unwrap() because the arg is required + let port: u16 = *matches + .get_one::("PORT") + .expect("'PORT' is required and parsing will fail if its missing"); + println!("PORT = {}", port); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.md b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.md new file mode 100644 index 000000000..a317a8eb7 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.md @@ -0,0 +1,31 @@ +```console +$ 04_02_validate --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_02_validate[EXE] + +ARGS: + Network port to use + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_02_validate 22 +PORT = 22 + +$ 04_02_validate foobar +? failed +error: Invalid value "foobar" for '': `foobar` isn't a port number + +For more information try --help + +$ 04_02_validate 0 +? failed +error: Invalid value "0" for '': Port not in range 1-65535 + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.rs b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.rs new file mode 100644 index 000000000..ea2f32e67 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_02_validate.rs @@ -0,0 +1,36 @@ +use std::ops::RangeInclusive; + +use clap::{arg, command}; + +fn main() { + let matches = command!() // requires `cargo` feature + .arg( + arg!() + .help("Network port to use") + .value_parser(port_in_range), + ) + .get_matches(); + + // Note, it's safe to call unwrap() because the arg is required + let port: u16 = *matches + .get_one::("PORT") + .expect("'PORT' is required and parsing will fail if its missing"); + println!("PORT = {}", port); +} + +const PORT_RANGE: RangeInclusive = 1..=65535; + +fn port_in_range(s: &str) -> Result { + let port: usize = s + .parse() + .map_err(|_| format!("`{}` isn't a port number", s))?; + if PORT_RANGE.contains(&port) { + Ok(port as u16) + } else { + Err(format!( + "Port not in range {}-{}", + PORT_RANGE.start(), + PORT_RANGE.end() + )) + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.md b/vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.md new file mode 100644 index 000000000..3ea336363 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.md @@ -0,0 +1,58 @@ +```console +$ 04_03_relations --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_03_relations[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] + +ARGS: + some regular input + +OPTIONS: + -c + -h, --help Print help information + --major auto inc major + --minor auto inc minor + --patch auto inc patch + --set-ver set version manually + --spec-in some special input argument + -V, --version Print version information + +$ 04_03_relations +? failed +error: The following required arguments were not provided: + <--set-ver |--major|--minor|--patch> + +USAGE: + 04_03_relations[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] + +For more information try --help + +$ 04_03_relations --major +Version: 2.2.3 + +$ 04_03_relations --major --minor +? failed +error: The argument '--major' cannot be used with '--minor' + +USAGE: + 04_03_relations[EXE] <--set-ver |--major|--minor|--patch> + +For more information try --help + +$ 04_03_relations --major -c config.toml +? failed +error: The following required arguments were not provided: + > + +USAGE: + 04_03_relations[EXE] -c <--set-ver |--major|--minor|--patch> > + +For more information try --help + +$ 04_03_relations --major -c config.toml --spec-in input.txt +Version: 2.2.3 +Doing work using input input.txt and config config.toml + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.rs b/vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.rs new file mode 100644 index 000000000..8e26d3ea9 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_03_relations.rs @@ -0,0 +1,80 @@ +use std::path::PathBuf; + +use clap::{arg, command, value_parser, ArgAction, ArgGroup}; + +fn main() { + // Create application like normal + let matches = command!() // requires `cargo` feature + // Add the version arguments + .arg(arg!(--"set-ver" "set version manually").required(false)) + .arg(arg!(--major "auto inc major").action(ArgAction::SetTrue)) + .arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue)) + .arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue)) + // Create a group, make it required, and add the above arguments + .group( + ArgGroup::new("vers") + .required(true) + .args(&["set-ver", "major", "minor", "patch"]), + ) + // Arguments can also be added to a group individually, these two arguments + // are part of the "input" group which is not required + .arg( + arg!([INPUT_FILE] "some regular input") + .value_parser(value_parser!(PathBuf)) + .group("input"), + ) + .arg( + arg!(--"spec-in" "some special input argument") + .required(false) + .value_parser(value_parser!(PathBuf)) + .group("input"), + ) + // Now let's assume we have a -c [config] argument which requires one of + // (but **not** both) the "input" arguments + .arg( + arg!(config: -c ) + .required(false) + .value_parser(value_parser!(PathBuf)) + .requires("input"), + ) + .get_matches(); + + // Let's assume the old version 1.2.3 + let mut major = 1; + let mut minor = 2; + let mut patch = 3; + + // See if --set-ver was used to set the version manually + let version = if let Some(ver) = matches.get_one::("set-ver") { + ver.to_owned() + } else { + // Increment the one requested (in a real program, we'd reset the lower numbers) + let (maj, min, pat) = ( + matches.get_flag("major"), + matches.get_flag("minor"), + matches.get_flag("patch"), + ); + match (maj, min, pat) { + (true, _, _) => major += 1, + (_, true, _) => minor += 1, + (_, _, true) => patch += 1, + _ => unreachable!(), + }; + format!("{}.{}.{}", major, minor, patch) + }; + + println!("Version: {}", version); + + // Check for usage of -c + if matches.contains_id("config") { + let input = matches + .get_one::("INPUT_FILE") + .unwrap_or_else(|| matches.get_one::("spec-in").unwrap()) + .display(); + println!( + "Doing work using input {} and config {}", + input, + matches.get_one::("config").unwrap().display() + ); + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.md b/vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.md new file mode 100644 index 000000000..26a3df1ab --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.md @@ -0,0 +1,57 @@ +```console +$ 04_04_custom --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] + +ARGS: + some regular input + +OPTIONS: + -c + -h, --help Print help information + --major auto inc major + --minor auto inc minor + --patch auto inc patch + --set-ver set version manually + --spec-in some special input argument + -V, --version Print version information + +$ 04_04_custom +? failed +error: Can only modify one version field + +USAGE: + 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] + +For more information try --help + +$ 04_04_custom --major +Version: 2.2.3 + +$ 04_04_custom --major --minor +? failed +error: Can only modify one version field + +USAGE: + 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] + +For more information try --help + +$ 04_04_custom --major -c config.toml +? failed +Version: 2.2.3 +error: INPUT_FILE or --spec-in is required when using --config + +USAGE: + 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] + +For more information try --help + +$ 04_04_custom --major -c config.toml --spec-in input.txt +Version: 2.2.3 +Doing work using input input.txt and config config.toml + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.rs b/vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.rs new file mode 100644 index 000000000..fb40b2fc4 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/04_04_custom.rs @@ -0,0 +1,88 @@ +use std::path::PathBuf; + +use clap::{arg, command, value_parser, ArgAction, ErrorKind}; + +fn main() { + // Create application like normal + let mut cmd = command!() // requires `cargo` feature + // Add the version arguments + .arg(arg!(--"set-ver" "set version manually").required(false)) + .arg(arg!(--major "auto inc major").action(ArgAction::SetTrue)) + .arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue)) + .arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue)) + // Arguments can also be added to a group individually, these two arguments + // are part of the "input" group which is not required + .arg(arg!([INPUT_FILE] "some regular input").value_parser(value_parser!(PathBuf))) + .arg( + arg!(--"spec-in" "some special input argument") + .required(false) + .value_parser(value_parser!(PathBuf)), + ) + // Now let's assume we have a -c [config] argument which requires one of + // (but **not** both) the "input" arguments + .arg( + arg!(config: -c ) + .required(false) + .value_parser(value_parser!(PathBuf)), + ); + let matches = cmd.get_matches_mut(); + + // Let's assume the old version 1.2.3 + let mut major = 1; + let mut minor = 2; + let mut patch = 3; + + // See if --set-ver was used to set the version manually + let version = if let Some(ver) = matches.get_one::("set-ver") { + if matches.get_flag("major") || matches.get_flag("minor") || matches.get_flag("patch") { + cmd.error( + ErrorKind::ArgumentConflict, + "Can't do relative and absolute version change", + ) + .exit(); + } + ver.to_string() + } else { + // Increment the one requested (in a real program, we'd reset the lower numbers) + let (maj, min, pat) = ( + matches.get_flag("major"), + matches.get_flag("minor"), + matches.get_flag("patch"), + ); + match (maj, min, pat) { + (true, false, false) => major += 1, + (false, true, false) => minor += 1, + (false, false, true) => patch += 1, + _ => { + cmd.error( + ErrorKind::ArgumentConflict, + "Can only modify one version field", + ) + .exit(); + } + }; + format!("{}.{}.{}", major, minor, patch) + }; + + println!("Version: {}", version); + + // Check for usage of -c + if matches.contains_id("config") { + let input = matches + .get_one::("INPUT_FILE") + .or_else(|| matches.get_one::("spec-in")) + .unwrap_or_else(|| { + cmd.error( + ErrorKind::MissingRequiredArgument, + "INPUT_FILE or --spec-in is required when using --config", + ) + .exit() + }) + .display(); + println!( + "Doing work using input {} and config {}", + input, + matches.get_one::("config").unwrap().display() + ); + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_builder/05_01_assert.rs b/vendor/clap-3.2.20/examples/tutorial_builder/05_01_assert.rs new file mode 100644 index 000000000..4b9254230 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_builder/05_01_assert.rs @@ -0,0 +1,25 @@ +use clap::{arg, command, value_parser}; + +fn main() { + let matches = cmd().get_matches(); + + // Note, it's safe to call unwrap() because the arg is required + let port: usize = *matches + .get_one::("PORT") + .expect("'PORT' is required and parsing will fail if its missing"); + println!("PORT = {}", port); +} + +fn cmd() -> clap::Command<'static> { + command!() // requires `cargo` feature + .arg( + arg!() + .help("Network port to use") + .value_parser(value_parser!(usize)), + ) +} + +#[test] +fn verify_cmd() { + cmd().debug_assert(); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/01_quick.md b/vendor/clap-3.2.20/examples/tutorial_derive/01_quick.md new file mode 100644 index 000000000..6f70d2cce --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/01_quick.md @@ -0,0 +1,37 @@ +```console +$ 01_quick_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 01_quick_derive[EXE] [OPTIONS] [NAME] [SUBCOMMAND] + +ARGS: + Optional name to operate on + +OPTIONS: + -c, --config Sets a custom config file + -d, --debug Turn debugging information on + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + help Print this message or the help of the given subcommand(s) + test does testing things + +``` + +By default, the program does nothing: +```console +$ 01_quick_derive +Debug mode is off + +``` + +But you can mix and match the various features +```console +$ 01_quick_derive -dd test +Debug mode is on +Not printing testing lists... + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/01_quick.rs b/vendor/clap-3.2.20/examples/tutorial_derive/01_quick.rs new file mode 100644 index 000000000..2c2031061 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/01_quick.rs @@ -0,0 +1,69 @@ +use std::path::PathBuf; + +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + /// Optional name to operate on + #[clap(value_parser)] + name: Option, + + /// Sets a custom config file + #[clap(short, long, value_parser, value_name = "FILE")] + config: Option, + + /// Turn debugging information on + #[clap(short, long, action = clap::ArgAction::Count)] + debug: u8, + + #[clap(subcommand)] + command: Option, +} + +#[derive(Subcommand)] +enum Commands { + /// does testing things + Test { + /// lists test values + #[clap(short, long, action)] + list: bool, + }, +} + +fn main() { + let cli = Cli::parse(); + + // You can check the value provided by positional arguments, or option arguments + if let Some(name) = cli.name.as_deref() { + println!("Value for name: {}", name); + } + + if let Some(config_path) = cli.config.as_deref() { + println!("Value for config: {}", config_path.display()); + } + + // You can see how many times a particular flag or argument occurred + // Note, only flags can have multiple occurrences + match cli.debug { + 0 => println!("Debug mode is off"), + 1 => println!("Debug mode is kind of on"), + 2 => println!("Debug mode is on"), + _ => println!("Don't be crazy"), + } + + // You can check for the existence of subcommands, and if found use their + // matches just as you would the top level cmd + match &cli.command { + Some(Commands::Test { list }) => { + if *list { + println!("Printing testing lists..."); + } else { + println!("Not printing testing lists..."); + } + } + None => {} + } + + // Continued program logic goes here... +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.md b/vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.md new file mode 100644 index 000000000..ee16c66df --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.md @@ -0,0 +1,19 @@ +```console +$ 02_app_settings_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 02_app_settings_derive[EXE] --two --one + +OPTIONS: + --two + --one + -h, --help Print help information + -V, --version Print version information + +$ 02_app_settings_derive --one -1 --one -3 --two 10 +two: "10" +one: "-3" + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.rs b/vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.rs new file mode 100644 index 000000000..6a06929bb --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/02_app_settings.rs @@ -0,0 +1,19 @@ +use clap::{AppSettings, Parser}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +#[clap(allow_negative_numbers = true)] +#[clap(global_setting(AppSettings::DeriveDisplayOrder))] +struct Cli { + #[clap(long, value_parser)] + two: String, + #[clap(long, value_parser)] + one: String, +} + +fn main() { + let cli = Cli::parse(); + + println!("two: {:?}", cli.two); + println!("one: {:?}", cli.one); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/02_apps.md b/vendor/clap-3.2.20/examples/tutorial_derive/02_apps.md new file mode 100644 index 000000000..0141581c4 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/02_apps.md @@ -0,0 +1,19 @@ +```console +$ 02_apps_derive --help +MyApp 1.0 +Kevin K. +Does awesome things + +USAGE: + 02_apps_derive[EXE] --two --one + +OPTIONS: + -h, --help Print help information + --one + --two + -V, --version Print version information + +$ 02_apps_derive --version +MyApp 1.0 + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/02_apps.rs b/vendor/clap-3.2.20/examples/tutorial_derive/02_apps.rs new file mode 100644 index 000000000..b97ce1eed --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/02_apps.rs @@ -0,0 +1,20 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(name = "MyApp")] +#[clap(author = "Kevin K. ")] +#[clap(version = "1.0")] +#[clap(about = "Does awesome things", long_about = None)] +struct Cli { + #[clap(long, value_parser)] + two: String, + #[clap(long, value_parser)] + one: String, +} + +fn main() { + let cli = Cli::parse(); + + println!("two: {:?}", cli.two); + println!("one: {:?}", cli.one); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/02_crate.md b/vendor/clap-3.2.20/examples/tutorial_derive/02_crate.md new file mode 100644 index 000000000..92c820758 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/02_crate.md @@ -0,0 +1,18 @@ +```console +$ 02_crate_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 02_crate_derive[EXE] --two --one + +OPTIONS: + -h, --help Print help information + --one + --two + -V, --version Print version information + +$ 02_crate_derive --version +clap [..] + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/02_crate.rs b/vendor/clap-3.2.20/examples/tutorial_derive/02_crate.rs new file mode 100644 index 000000000..5576f998c --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/02_crate.rs @@ -0,0 +1,17 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] // Read from `Cargo.toml` +struct Cli { + #[clap(long, value_parser)] + two: String, + #[clap(long, value_parser)] + one: String, +} + +fn main() { + let cli = Cli::parse(); + + println!("two: {:?}", cli.two); + println!("one: {:?}", cli.one); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.md b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.md new file mode 100644 index 000000000..0baaa10ca --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.md @@ -0,0 +1,23 @@ +```console +$ 03_01_flag_bool_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_01_flag_bool_derive[EXE] [OPTIONS] + +OPTIONS: + -h, --help Print help information + -v, --verbose + -V, --version Print version information + +$ 03_01_flag_bool_derive +verbose: false + +$ 03_01_flag_bool_derive --verbose +verbose: true + +$ 03_01_flag_bool_derive --verbose --verbose +verbose: true + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.rs new file mode 100644 index 000000000..de677d8c6 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_bool.rs @@ -0,0 +1,14 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short, long, action)] + verbose: bool, +} + +fn main() { + let cli = Cli::parse(); + + println!("verbose: {:?}", cli.verbose); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.md b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.md new file mode 100644 index 000000000..3d5a53084 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.md @@ -0,0 +1,23 @@ +```console +$ 03_01_flag_count_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_01_flag_count_derive[EXE] [OPTIONS] + +OPTIONS: + -h, --help Print help information + -v, --verbose + -V, --version Print version information + +$ 03_01_flag_count_derive +verbose: 0 + +$ 03_01_flag_count_derive --verbose +verbose: 1 + +$ 03_01_flag_count_derive --verbose --verbose +verbose: 2 + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.rs new file mode 100644 index 000000000..680f7f5e5 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_01_flag_count.rs @@ -0,0 +1,14 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short, long, action = clap::ArgAction::Count)] + verbose: u8, +} + +fn main() { + let cli = Cli::parse(); + + println!("verbose: {:?}", cli.verbose); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.md b/vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.md new file mode 100644 index 000000000..84ff7fa74 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.md @@ -0,0 +1,32 @@ +```console +$ 03_02_option_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_02_option_derive[EXE] [OPTIONS] + +OPTIONS: + -h, --help Print help information + -n, --name + -V, --version Print version information + +$ 03_02_option_derive +name: None + +$ 03_02_option_derive --name bob +name: Some("bob") + +$ 03_02_option_derive --name=bob +name: Some("bob") + +$ 03_02_option_derive -n bob +name: Some("bob") + +$ 03_02_option_derive -n=bob +name: Some("bob") + +$ 03_02_option_derive -nbob +name: Some("bob") + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.rs new file mode 100644 index 000000000..75b67afe7 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_02_option.rs @@ -0,0 +1,14 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short, long, value_parser)] + name: Option, +} + +fn main() { + let cli = Cli::parse(); + + println!("name: {:?}", cli.name.as_deref()); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.md b/vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.md new file mode 100644 index 000000000..7281fe3ff --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.md @@ -0,0 +1,22 @@ +```console +$ 03_03_positional_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_03_positional_derive[EXE] [NAME] + +ARGS: + + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 03_03_positional_derive +name: None + +$ 03_03_positional_derive bob +name: Some("bob") + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.rs new file mode 100644 index 000000000..7478951f1 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_03_positional.rs @@ -0,0 +1,14 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(value_parser)] + name: Option, +} + +fn main() { + let cli = Cli::parse(); + + println!("name: {:?}", cli.name.as_deref()); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.md b/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.md new file mode 100644 index 000000000..02f96e3d3 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.md @@ -0,0 +1,64 @@ +```console +$ 03_04_subcommands_derive help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_04_subcommands_derive[EXE] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + add Adds files to myapp + help Print this message or the help of the given subcommand(s) + +$ 03_04_subcommands_derive help add +03_04_subcommands_derive[EXE]-add [..] +Adds files to myapp + +USAGE: + 03_04_subcommands_derive[EXE] add [NAME] + +ARGS: + + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 03_04_subcommands_derive add bob +'myapp add' was used, name is: Some("bob") + +``` + +Because we used `command: Commands` instead of `command: Option`: +```console +$ 03_04_subcommands_derive +? failed +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_04_subcommands_derive[EXE] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +SUBCOMMANDS: + add Adds files to myapp + help Print this message or the help of the given subcommand(s) + +``` + +Because we added `#[clap(propagate_version = true)]`: +```console +$ 03_04_subcommands_derive --version +clap [..] + +$ 03_04_subcommands_derive add --version +03_04_subcommands_derive[EXE]-add [..] + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.rs new file mode 100644 index 000000000..62a45a97e --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands.rs @@ -0,0 +1,30 @@ +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +#[clap(propagate_version = true)] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Adds files to myapp + Add { + #[clap(value_parser)] + name: Option, + }, +} + +fn main() { + let cli = Cli::parse(); + + // You can check for the existence of subcommands, and if found use their + // matches just as you would the top level cmd + match &cli.command { + Commands::Add { name } => { + println!("'myapp add' was used, name is: {:?}", name) + } + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands_alt.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands_alt.rs new file mode 100644 index 000000000..b6124936c --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_04_subcommands_alt.rs @@ -0,0 +1,33 @@ +use clap::{Args, Parser, Subcommand}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +#[clap(propagate_version = true)] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Adds files to myapp + Add(Add), +} + +#[derive(Args)] +struct Add { + #[clap(value_parser)] + name: Option, +} + +fn main() { + let cli = Cli::parse(); + + // You can check for the existence of subcommands, and if found use their + // matches just as you would the top level cmd + match &cli.command { + Commands::Add(name) => { + println!("'myapp add' was used, name is: {:?}", name.name) + } + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.md b/vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.md new file mode 100644 index 000000000..f7315e736 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.md @@ -0,0 +1,22 @@ +```console +$ 03_05_default_values_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 03_05_default_values_derive[EXE] [NAME] + +ARGS: + [default: alice] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 03_05_default_values_derive +name: "alice" + +$ 03_05_default_values_derive bob +name: "bob" + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.rs b/vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.rs new file mode 100644 index 000000000..10a1ec808 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/03_05_default_values.rs @@ -0,0 +1,14 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(default_value_t = String::from("alice"), value_parser)] + name: String, +} + +fn main() { + let cli = Cli::parse(); + + println!("name: {:?}", cli.name); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.md b/vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.md new file mode 100644 index 000000000..2523af924 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.md @@ -0,0 +1,29 @@ +```console +$ 04_01_enum_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_01_enum_derive[EXE] + +ARGS: + What mode to run the program in [possible values: fast, slow] + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_01_enum_derive fast +Hare + +$ 04_01_enum_derive slow +Tortoise + +$ 04_01_enum_derive medium +? failed +error: "medium" isn't a valid value for '' + [possible values: fast, slow] + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.rs b/vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.rs new file mode 100644 index 000000000..1ac984288 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_01_enum.rs @@ -0,0 +1,28 @@ +use clap::{Parser, ValueEnum}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + /// What mode to run the program in + #[clap(arg_enum, value_parser)] + mode: Mode, +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +enum Mode { + Fast, + Slow, +} + +fn main() { + let cli = Cli::parse(); + + match cli.mode { + Mode::Fast => { + println!("Hare"); + } + Mode::Slow => { + println!("Tortoise"); + } + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.md b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.md new file mode 100644 index 000000000..6079ef193 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.md @@ -0,0 +1,31 @@ +```console +$ 04_02_parse_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_02_parse_derive[EXE] + +ARGS: + Network port to use + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_02_parse_derive 22 +PORT = 22 + +$ 04_02_parse_derive foobar +? failed +error: Invalid value "foobar" for '': invalid digit found in string + +For more information try --help + +$ 04_02_parse_derive 0 +? failed +error: Invalid value "0" for '': 0 is not in 1..=65535 + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.rs b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.rs new file mode 100644 index 000000000..6336a9cf1 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_parse.rs @@ -0,0 +1,15 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + /// Network port to use + #[clap(value_parser = clap::value_parser!(u16).range(1..))] + port: u16, +} + +fn main() { + let cli = Cli::parse(); + + println!("PORT = {}", cli.port); +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.md b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.md new file mode 100644 index 000000000..cc43440ef --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.md @@ -0,0 +1,31 @@ +```console +$ 04_02_validate_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_02_validate_derive[EXE] + +ARGS: + Network port to use + +OPTIONS: + -h, --help Print help information + -V, --version Print version information + +$ 04_02_validate_derive 22 +PORT = 22 + +$ 04_02_validate_derive foobar +? failed +error: Invalid value "foobar" for '': `foobar` isn't a port number + +For more information try --help + +$ 04_02_validate_derive 0 +? failed +error: Invalid value "0" for '': Port not in range 1-65535 + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.rs b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.rs new file mode 100644 index 000000000..7dac79c9f --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_02_validate.rs @@ -0,0 +1,34 @@ +use std::ops::RangeInclusive; + +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + /// Network port to use + #[clap(value_parser = port_in_range)] + port: u16, +} + +fn main() { + let cli = Cli::parse(); + + println!("PORT = {}", cli.port); +} + +const PORT_RANGE: RangeInclusive = 1..=65535; + +fn port_in_range(s: &str) -> Result { + let port: usize = s + .parse() + .map_err(|_| format!("`{}` isn't a port number", s))?; + if PORT_RANGE.contains(&port) { + Ok(port as u16) + } else { + Err(format!( + "Port not in range {}-{}", + PORT_RANGE.start(), + PORT_RANGE.end() + )) + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.md b/vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.md new file mode 100644 index 000000000..4f5703d82 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.md @@ -0,0 +1,58 @@ +```console +$ 04_03_relations_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_03_relations_derive[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] + +ARGS: + some regular input + +OPTIONS: + -c + -h, --help Print help information + --major auto inc major + --minor auto inc minor + --patch auto inc patch + --set-ver set version manually + --spec-in some special input argument + -V, --version Print version information + +$ 04_03_relations_derive +? failed +error: The following required arguments were not provided: + <--set-ver |--major|--minor|--patch> + +USAGE: + 04_03_relations_derive[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] + +For more information try --help + +$ 04_03_relations_derive --major +Version: 2.2.3 + +$ 04_03_relations_derive --major --minor +? failed +error: The argument '--major' cannot be used with '--minor' + +USAGE: + 04_03_relations_derive[EXE] <--set-ver |--major|--minor|--patch> + +For more information try --help + +$ 04_03_relations_derive --major -c config.toml +? failed +error: The following required arguments were not provided: + > + +USAGE: + 04_03_relations_derive[EXE] -c <--set-ver |--major|--minor|--patch> > + +For more information try --help + +$ 04_03_relations_derive --major -c config.toml --spec-in input.txt +Version: 2.2.3 +Doing work using input input.txt and config config.toml + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.rs b/vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.rs new file mode 100644 index 000000000..37efe95e3 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_03_relations.rs @@ -0,0 +1,72 @@ +use clap::{ArgGroup, Parser}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +#[clap(group( + ArgGroup::new("vers") + .required(true) + .args(&["set-ver", "major", "minor", "patch"]), + ))] +struct Cli { + /// set version manually + #[clap(long, value_name = "VER", value_parser)] + set_ver: Option, + + /// auto inc major + #[clap(long, action)] + major: bool, + + /// auto inc minor + #[clap(long, action)] + minor: bool, + + /// auto inc patch + #[clap(long, action)] + patch: bool, + + /// some regular input + #[clap(group = "input", value_parser)] + input_file: Option, + + /// some special input argument + #[clap(long, group = "input", value_parser)] + spec_in: Option, + + #[clap(short, requires = "input", value_parser)] + config: Option, +} + +fn main() { + let cli = Cli::parse(); + + // Let's assume the old version 1.2.3 + let mut major = 1; + let mut minor = 2; + let mut patch = 3; + + // See if --set_ver was used to set the version manually + let version = if let Some(ver) = cli.set_ver.as_deref() { + ver.to_string() + } else { + // Increment the one requested (in a real program, we'd reset the lower numbers) + let (maj, min, pat) = (cli.major, cli.minor, cli.patch); + match (maj, min, pat) { + (true, _, _) => major += 1, + (_, true, _) => minor += 1, + (_, _, true) => patch += 1, + _ => unreachable!(), + }; + format!("{}.{}.{}", major, minor, patch) + }; + + println!("Version: {}", version); + + // Check for usage of -c + if let Some(config) = cli.config.as_deref() { + let input = cli + .input_file + .as_deref() + .unwrap_or_else(|| cli.spec_in.as_deref().unwrap()); + println!("Doing work using input {} and config {}", input, config); + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.md b/vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.md new file mode 100644 index 000000000..0f19bfe31 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.md @@ -0,0 +1,57 @@ +```console +$ 04_04_custom_derive --help +clap [..] +A simple to use, efficient, and full-featured Command Line Argument Parser + +USAGE: + 04_04_custom_derive[EXE] [OPTIONS] [INPUT_FILE] + +ARGS: + some regular input + +OPTIONS: + -c + -h, --help Print help information + --major auto inc major + --minor auto inc minor + --patch auto inc patch + --set-ver set version manually + --spec-in some special input argument + -V, --version Print version information + +$ 04_04_custom_derive +? failed +error: Can only modify one version field + +USAGE: + clap [OPTIONS] [INPUT_FILE] + +For more information try --help + +$ 04_04_custom_derive --major +Version: 2.2.3 + +$ 04_04_custom_derive --major --minor +? failed +error: Can only modify one version field + +USAGE: + clap [OPTIONS] [INPUT_FILE] + +For more information try --help + +$ 04_04_custom_derive --major -c config.toml +? failed +Version: 2.2.3 +error: INPUT_FILE or --spec-in is required when using --config + +USAGE: + clap [OPTIONS] [INPUT_FILE] + +For more information try --help + +$ 04_04_custom_derive --major -c config.toml --spec-in input.txt +Version: 2.2.3 +Doing work using input input.txt and config config.toml + +``` diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.rs b/vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.rs new file mode 100644 index 000000000..454d489c1 --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/04_04_custom.rs @@ -0,0 +1,93 @@ +use clap::{CommandFactory, ErrorKind, Parser}; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + /// set version manually + #[clap(long, value_name = "VER", value_parser)] + set_ver: Option, + + /// auto inc major + #[clap(long, action)] + major: bool, + + /// auto inc minor + #[clap(long, action)] + minor: bool, + + /// auto inc patch + #[clap(long, action)] + patch: bool, + + /// some regular input + #[clap(value_parser)] + input_file: Option, + + /// some special input argument + #[clap(long, value_parser)] + spec_in: Option, + + #[clap(short, value_parser)] + config: Option, +} + +fn main() { + let cli = Cli::parse(); + + // Let's assume the old version 1.2.3 + let mut major = 1; + let mut minor = 2; + let mut patch = 3; + + // See if --set-ver was used to set the version manually + let version = if let Some(ver) = cli.set_ver.as_deref() { + if cli.major || cli.minor || cli.patch { + let mut cmd = Cli::command(); + cmd.error( + ErrorKind::ArgumentConflict, + "Can't do relative and absolute version change", + ) + .exit(); + } + ver.to_string() + } else { + // Increment the one requested (in a real program, we'd reset the lower numbers) + let (maj, min, pat) = (cli.major, cli.minor, cli.patch); + match (maj, min, pat) { + (true, false, false) => major += 1, + (false, true, false) => minor += 1, + (false, false, true) => patch += 1, + _ => { + let mut cmd = Cli::command(); + cmd.error( + ErrorKind::ArgumentConflict, + "Can only modify one version field", + ) + .exit(); + } + }; + format!("{}.{}.{}", major, minor, patch) + }; + + println!("Version: {}", version); + + // Check for usage of -c + if let Some(config) = cli.config.as_deref() { + // todo: remove `#[allow(clippy::or_fun_call)]` lint when MSRV is bumped. + #[allow(clippy::or_fun_call)] + let input = cli + .input_file + .as_deref() + // 'or' is preferred to 'or_else' here since `Option::as_deref` is 'const' + .or(cli.spec_in.as_deref()) + .unwrap_or_else(|| { + let mut cmd = Cli::command(); + cmd.error( + ErrorKind::MissingRequiredArgument, + "INPUT_FILE or --spec-in is required when using --config", + ) + .exit() + }); + println!("Doing work using input {} and config {}", input, config); + } +} diff --git a/vendor/clap-3.2.20/examples/tutorial_derive/05_01_assert.rs b/vendor/clap-3.2.20/examples/tutorial_derive/05_01_assert.rs new file mode 100644 index 000000000..66dca727f --- /dev/null +++ b/vendor/clap-3.2.20/examples/tutorial_derive/05_01_assert.rs @@ -0,0 +1,21 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + /// Network port to use + #[clap(value_parser)] + port: u16, +} + +fn main() { + let cli = Cli::parse(); + + println!("PORT = {}", cli.port); +} + +#[test] +fn verify_cli() { + use clap::CommandFactory; + Cli::command().debug_assert() +} diff --git a/vendor/clap-3.2.20/examples/typed-derive.md b/vendor/clap-3.2.20/examples/typed-derive.md new file mode 100644 index 000000000..9c7615c63 --- /dev/null +++ b/vendor/clap-3.2.20/examples/typed-derive.md @@ -0,0 +1,84 @@ +**This requires enabling the [`derive` feature flag][crate::_features].** + +Help: +```console +$ typed-derive --help +clap + +USAGE: + typed-derive[EXE] [OPTIONS] + +OPTIONS: + --bind Handle IP addresses + -D Hand-written parser for tuples + -h, --help Print help information + -I Allow invalid UTF-8 paths + -O Implicitly using `std::str::FromStr` + --sleep Allow human-readable durations + +``` + +Optimization-level (number) +```console +$ typed-derive -O 1 +Args { optimization: Some(1), include: None, bind: None, sleep: None, defines: [] } + +$ typed-derive -O plaid +? failed +error: Invalid value "plaid" for '-O ': invalid digit found in string + +For more information try --help + +``` + +Include (path) +```console +$ typed-derive -I../hello +Args { optimization: None, include: Some("../hello"), bind: None, sleep: None, defines: [] } + +``` + +IP Address +```console +$ typed-derive --bind 192.0.0.1 +Args { optimization: None, include: None, bind: Some(192.0.0.1), sleep: None, defines: [] } + +$ typed-derive --bind localhost +? failed +error: Invalid value "localhost" for '--bind ': invalid IP address syntax + +For more information try --help + +``` + +Time +```console +$ typed-derive --sleep 10s +Args { optimization: None, include: None, bind: None, sleep: Some(Duration(10s)), defines: [] } + +$ typed-derive --sleep forever +? failed +error: Invalid value "forever" for '--sleep ': expected number at 0 + +For more information try --help + +``` + +Defines (key-value pairs) +```console +$ typed-derive -D Foo=10 -D Alice=30 +Args { optimization: None, include: None, bind: None, sleep: None, defines: [("Foo", 10), ("Alice", 30)] } + +$ typed-derive -D Foo +? failed +error: Invalid value "Foo" for '-D ': invalid KEY=value: no `=` found in `Foo` + +For more information try --help + +$ typed-derive -D Foo=Bar +? failed +error: Invalid value "Foo=Bar" for '-D ': invalid digit found in string + +For more information try --help + +``` diff --git a/vendor/clap-3.2.20/examples/typed-derive.rs b/vendor/clap-3.2.20/examples/typed-derive.rs new file mode 100644 index 000000000..31084029d --- /dev/null +++ b/vendor/clap-3.2.20/examples/typed-derive.rs @@ -0,0 +1,44 @@ +use clap::Parser; +use std::error::Error; + +#[derive(Parser, Debug)] // requires `derive` feature +struct Args { + /// Implicitly using `std::str::FromStr` + #[clap(short = 'O', value_parser)] + optimization: Option, + + /// Allow invalid UTF-8 paths + #[clap(short = 'I', value_parser, value_name = "DIR", value_hint = clap::ValueHint::DirPath)] + include: Option, + + /// Handle IP addresses + #[clap(long, value_parser)] + bind: Option, + + /// Allow human-readable durations + #[clap(long, value_parser)] + sleep: Option, + + /// Hand-written parser for tuples + #[clap(short = 'D', value_parser = parse_key_val::)] + defines: Vec<(String, i32)>, +} + +/// Parse a single key-value pair +fn parse_key_val(s: &str) -> Result<(T, U), Box> +where + T: std::str::FromStr, + T::Err: Error + Send + Sync + 'static, + U: std::str::FromStr, + U::Err: Error + Send + Sync + 'static, +{ + let pos = s + .find('=') + .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?; + Ok((s[..pos].parse()?, s[pos + 1..].parse()?)) +} + +fn main() { + let args = Args::parse(); + println!("{:?}", args); +} diff --git a/vendor/clap-3.2.20/src/_cookbook/cargo_example.rs b/vendor/clap-3.2.20/src/_cookbook/cargo_example.rs new file mode 100644 index 000000000..ec5d582db --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/cargo_example.rs @@ -0,0 +1,7 @@ +//! # Example: cargo subcommand (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/cargo-example.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/cargo-example.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/cargo_example_derive b/vendor/clap-3.2.20/src/_cookbook/cargo_example_derive new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/clap-3.2.20/src/_cookbook/cargo_example_derive.rs b/vendor/clap-3.2.20/src/_cookbook/cargo_example_derive.rs new file mode 100644 index 000000000..d49f956f9 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/cargo_example_derive.rs @@ -0,0 +1,7 @@ +//! # Example: cargo subcommand (Derive API) +//! +//! ```rust +#![doc = include_str!("../../examples/cargo-example-derive.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/cargo-example-derive.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/escaped_positional.rs b/vendor/clap-3.2.20/src/_cookbook/escaped_positional.rs new file mode 100644 index 000000000..99a3f83f3 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/escaped_positional.rs @@ -0,0 +1,7 @@ +//! # Example (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/escaped-positional.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/escaped-positional.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/escaped_positional_derive.rs b/vendor/clap-3.2.20/src/_cookbook/escaped_positional_derive.rs new file mode 100644 index 000000000..e6f99ad17 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/escaped_positional_derive.rs @@ -0,0 +1,7 @@ +//! # Example (Derive API) +//! +//! ```rust +#![doc = include_str!("../../examples/escaped-positional-derive.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/escaped-positional-derive.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/git.rs b/vendor/clap-3.2.20/src/_cookbook/git.rs new file mode 100644 index 000000000..03a926ca8 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/git.rs @@ -0,0 +1,7 @@ +//! # Example: git-like CLI (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/git.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/git.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/git_derive.rs b/vendor/clap-3.2.20/src/_cookbook/git_derive.rs new file mode 100644 index 000000000..d3119736d --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/git_derive.rs @@ -0,0 +1,7 @@ +//! # Example: git-like CLI (Derive API) +//! +//! ```rust +#![doc = include_str!("../../examples/git-derive.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/git-derive.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/mod.rs b/vendor/clap-3.2.20/src/_cookbook/mod.rs new file mode 100644 index 000000000..1a78ed11b --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/mod.rs @@ -0,0 +1,55 @@ +// Contributing +// +// New examples: +// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. +// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax +// - Link the `.md` file from here + +//! # Documentation: Cookbook +//! +//! Typed arguments: [derive][typed_derive] +//! - Topics: +//! - Custom `parse()` +//! +//! Custom cargo command: [builder][cargo_example], [derive][cargo_example_derive] +//! - Topics: +//! - Subcommands +//! - Cargo plugins +//! +//! git-like interface: [builder][git], [derive][git_derive] +//! - Topics: +//! - Subcommands +//! - External subcommands +//! - Optional subcommands +//! - Default subcommands +//! +//! pacman-like interface: [builder][pacman] +//! - Topics: +//! - Flag subcommands +//! - Conflicting arguments +//! +//! Escaped positionals with `--`: [builder][escaped_positional], [derive][escaped_positional_derive] +//! +//! Multi-call +//! - busybox: [builder][multicall_busybox] +//! - Topics: +//! - Subcommands +//! - hostname: [builder][multicall_hostname] +//! - Topics: +//! - Subcommands +//! +//! repl: [builder][repl] +//! - Topics: +//! - Read-Eval-Print Loops / Custom command lines + +pub mod cargo_example; +pub mod cargo_example_derive; +pub mod escaped_positional; +pub mod escaped_positional_derive; +pub mod git; +pub mod git_derive; +pub mod multicall_busybox; +pub mod multicall_hostname; +pub mod pacman; +pub mod repl; +pub mod typed_derive; diff --git a/vendor/clap-3.2.20/src/_cookbook/multicall_busybox.rs b/vendor/clap-3.2.20/src/_cookbook/multicall_busybox.rs new file mode 100644 index 000000000..e3384d682 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/multicall_busybox.rs @@ -0,0 +1,7 @@ +//! # Example: busybox-like CLI (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/multicall-busybox.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/multicall-busybox.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/multicall_hostname.rs b/vendor/clap-3.2.20/src/_cookbook/multicall_hostname.rs new file mode 100644 index 000000000..9777654dc --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/multicall_hostname.rs @@ -0,0 +1,7 @@ +//! # Example: hostname-like CLI (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/multicall-hostname.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/multicall-hostname.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/pacman.rs b/vendor/clap-3.2.20/src/_cookbook/pacman.rs new file mode 100644 index 000000000..880c58158 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/pacman.rs @@ -0,0 +1,7 @@ +//! # Example: pacman-like CLI (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/pacman.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/pacman.md")] diff --git a/vendor/clap-3.2.20/src/_cookbook/repl.rs b/vendor/clap-3.2.20/src/_cookbook/repl.rs new file mode 100644 index 000000000..549ec8259 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/repl.rs @@ -0,0 +1,5 @@ +//! # Example: Command REPL (Builder API) +//! +//! ```rust +#![doc = include_str!("../../examples/repl.rs")] +//! ``` diff --git a/vendor/clap-3.2.20/src/_cookbook/typed_derive.rs b/vendor/clap-3.2.20/src/_cookbook/typed_derive.rs new file mode 100644 index 000000000..a5fd15ff8 --- /dev/null +++ b/vendor/clap-3.2.20/src/_cookbook/typed_derive.rs @@ -0,0 +1,7 @@ +//! # Example: Custom Types (Derive API) +//! +//! ```rust +#![doc = include_str!("../../examples/typed-derive.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/typed-derive.md")] diff --git a/vendor/clap-3.2.20/src/_derive/_tutorial.rs b/vendor/clap-3.2.20/src/_derive/_tutorial.rs new file mode 100644 index 000000000..abd57cef8 --- /dev/null +++ b/vendor/clap-3.2.20/src/_derive/_tutorial.rs @@ -0,0 +1,205 @@ +// Contributing +// +// New example code: +// - Please update the corresponding section in the derive tutorial +// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. +// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax +// +// See also the general CONTRIBUTING + +//! # Documentation: Derive Tutorial +//! +//! 1. [Quick Start](#quick-start) +//! 2. [Configuring the Parser](#configuring-the-parser) +//! 3. [Adding Arguments](#adding-arguments) +//! 1. [Positionals](#positionals) +//! 2. [Options](#options) +//! 3. [Flags](#flags) +//! 4. [Subcommands](#subcommands) +//! 5. [Defaults](#defaults) +//! 4. Validation +//! 1. [Enumerated values](#enumerated-values) +//! 2. [Validated values](#validated-values) +//! 3. [Argument Relations](#argument-relations) +//! 4. [Custom Validation](#custom-validation) +//! 5. [Testing](#testing) +//! +//! See also +//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis] +//! - The [cookbook][crate::_cookbook] for more application-focused examples +//! +//! ## Quick Start +//! +//! You can create an application declaratively with a `struct` and some +//! attributes. **This requires enabling the [`derive` feature flag][crate::_features].** +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/01_quick.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/tutorial_derive/01_quick.md")] +//! +//! ## Configuring the Parser +//! +//! You use derive [`Parser`][crate::Parser] to start building a parser. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/02_apps.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/tutorial_derive/02_apps.md")] +//! +//! You can use `#[clap(author, version, about)]` attribute defaults to fill these fields in from your `Cargo.toml` file. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/02_crate.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/02_crate.md")] +//! +//! You can use attributes to change the application level behavior of clap. Any [`Command`][crate::Command]] builder function can be used as an attribute. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.md")] +//! +//! ## Adding Arguments +//! +//! ### Positionals +//! +//! You can have users specify values by their position on the command-line: +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.md")] +//! +//! ### Options +//! +//! You can name your arguments with a flag: +//! - Order doesn't matter +//! - They can be optional +//! - Intent is clearer +//! +//! The `#[clap(short = 'n')]` and `#[clap(long = "name")]` attributes that define +//! the flags are [`Arg`][crate::Args] methods that are derived from the field name when no value +//! is specified (`#[clap(short)]` and `#[clap(long)]`). +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_02_option.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/03_02_option.md")] +//! +//! ### Flags +//! +//! Flags can also be switches that can be on/off. This is enabled via the +//! `#[clap(action = ArgAction::SetTrue)]` attribute though this is implied when the field is a +//! `bool`. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.md")] +//! +//! Or counted with `#[clap(action = clap::ArgAction::Count)]`: +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.md")] +//! +//! ### Subcommands +//! +//! Subcommands are derived with `#[derive(Subcommand)]` and be added via `#[clap(subcommand)]` attribute. Each +//! instance of a [Subcommand][crate::Subcommand] can have its own version, author(s), Args, and even its own +//! subcommands. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.rs")] +//! ``` +//! We used a struct-variant to define the `add` subcommand. +//! Alternatively, you can use a struct for your subcommand's arguments: +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands_alt.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.md")] +//! +//! ### Defaults +//! +//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional. +//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can +//! set `#[clap(default_value_t)]`. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.md")] +//! +//! ## Validation +//! +//! ### Enumerated values +//! +//! If you have arguments of specific values you want to test for, you can derive +//! [`ValueEnum`][crate::ValueEnum]. +//! +//! This allows you specify the valid values for that argument. If the user does not use one of +//! those specific values, they will receive a graceful exit with error message informing them +//! of the mistake, and what the possible valid values are +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.md")] +//! +//! ### Validated values +//! +//! More generally, you can validate and parse into any data type. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.md")] +//! +//! A custom parser can be used to improve the error messages or provide additional validation: +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")] +//! +//! ### Argument Relations +//! +//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even +//! [`ArgGroup`][crate::ArgGroup]s. +//! +//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list +//! each individually, or when you want a rule to apply "any but not all" arguments. +//! +//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one +//! argument to be present out of a given set. Imagine that you had multiple arguments, and you +//! want one of them to be required, but making all of them required isn't feasible because perhaps +//! they conflict with each other. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.md")] +//! +//! ### Custom Validation +//! +//! As a last resort, you can create custom errors with the basics of clap's formatting. +//! +//! ```rust +#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.rs")] +//! ``` +#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.md")] +//! +//! ## Testing +//! +//! clap reports most development errors as `debug_assert!`s. Rather than checking every +//! subcommand, you should have a test that calls +//! [`Command::debug_assert`][crate::App::debug_assert]: +//! ```rust,no_run +#![doc = include_str!("../../examples/tutorial_derive/05_01_assert.rs")] +//! ``` diff --git a/vendor/clap-3.2.20/src/_derive/mod.rs b/vendor/clap-3.2.20/src/_derive/mod.rs new file mode 100644 index 000000000..fc9f35db5 --- /dev/null +++ b/vendor/clap-3.2.20/src/_derive/mod.rs @@ -0,0 +1,510 @@ +//! # Documentation: Derive Reference +//! +//! 1. [Overview](#overview) +//! 2. [Attributes](#attributes) +//! 1. [Terminology](#terminology) +//! 2. [Command Attributes](#command-attributes) +//! 3. [Arg Attributes](#arg-attributes) +//! 4. [ValueEnum Attributes](#valueenum-attributes) +//! 5. [Possible Value Attributes](#possible-value-attributes) +//! 3. [Arg Types](#arg-types) +//! 4. [Doc Comments](#doc-comments) +//! 5. [Mixing Builder and Derive APIs](#mixing-builder-and-derive-apis) +//! 6. [Tips](#tips) +//! +//! ## Overview +//! +//! To derive `clap` types, you need to enable the [`derive` feature flag][crate::_features]. +//! +//! Example: +//! ```rust +#![doc = include_str!("../../examples/demo.rs")] +//! ``` +//! +//! Let's start by breaking down the anatomy of the derive attributes: +//! ```rust +//! use clap::{Parser, Args, Subcommand, ValueEnum}; +//! +//! /// Doc comment +//! #[derive(Parser)] +//! #[clap(APP ATTRIBUTE)] +//! struct Cli { +//! /// Doc comment +//! #[clap(ARG ATTRIBUTE)] +//! field: UserType, +//! +//! #[clap(value_enum, ARG ATTRIBUTE...)] +//! field: EnumValues, +//! +//! #[clap(flatten)] +//! delegate: Struct, +//! +//! #[clap(subcommand)] +//! command: Command, +//! } +//! +//! /// Doc comment +//! #[derive(Args)] +//! #[clap(PARENT APP ATTRIBUTE)] +//! struct Struct { +//! /// Doc comment +//! #[clap(ARG ATTRIBUTE)] +//! field: UserType, +//! } +//! +//! /// Doc comment +//! #[derive(Subcommand)] +//! #[clap(PARENT APP ATTRIBUTE)] +//! enum Command { +//! /// Doc comment +//! #[clap(APP ATTRIBUTE)] +//! Variant1(Struct), +//! +//! /// Doc comment +//! #[clap(APP ATTRIBUTE)] +//! Variant2 { +//! /// Doc comment +//! #[clap(ARG ATTRIBUTE)] +//! field: UserType, +//! } +//! } +//! +//! /// Doc comment +//! #[derive(ValueEnum)] +//! #[clap(VALUE ENUM ATTRIBUTE)] +//! enum EnumValues { +//! /// Doc comment +//! #[clap(POSSIBLE VALUE ATTRIBUTE)] +//! Variant1, +//! } +//! +//! fn main() { +//! let cli = Cli::parse(); +//! } +//! ``` +//! +//! Traits: +//! - [`Parser`][crate::Parser] parses arguments into a `struct` (arguments) or `enum` (subcommands). +//! - [`Args`][crate::Args] allows defining a set of re-usable arguments that get merged into their parent container. +//! - [`Subcommand`][crate::Subcommand] defines available subcommands. +//! - Subcommand arguments can be defined in a struct-variant or automatically flattened with a tuple-variant. +//! - [`ValueEnum`][crate::ValueEnum] allows parsing a value directly into an `enum`, erroring on unsupported values. +//! - The derive doesn't work on enums that contain non-unit variants, unless they are skipped +//! +//! *See also the [derive tutorial][crate::_derive::_tutorial] and [cookbook][crate::_cookbook]* +//! +//! ## Attributes +//! +//! ### Terminology +//! +//! **Raw attributes** are forwarded directly to the underlying [`clap` builder][crate::builder]. Any +//! [`Command`][crate::Command], [`Arg`][crate::Arg], or [`PossibleValue`][crate::PossibleValue] method can be used as an attribute. +//! +//! Raw attributes come in two different syntaxes: +//! ```rust,ignore +//! #[clap( +//! global = true, // name = arg form, neat for one-arg methods +//! required_if_eq("out", "file") // name(arg1, arg2, ...) form. +//! )] +//! ``` +//! +//! - `method = arg` can only be used for methods which take only one argument. +//! - `method(arg1, arg2)` can be used with any method. +//! +//! As long as `method_name` is not one of the magical methods it will be +//! translated into a mere method call. +//! +//! **Magic attributes** have post-processing done to them, whether that is +//! - Providing of defaults +//! - Special behavior is triggered off of it +//! +//! Magic attributes are more constrained in the syntax they support, usually just +//! ` = ` though some use `()` instead. See the specific +//! magic attributes documentation for details. This allows users to access the +//! raw behavior of an attribute via `()` syntax. +//! +//! **NOTE:** Some attributes are inferred from [Arg Types](#arg-types) and [Doc +//! Comments](#doc-comments). Explicit attributes take precedence over inferred +//! attributes. +//! +//! ### Command Attributes +//! +//! These correspond to a [`Command`][crate::Command] which is used for both top-level parsers and +//! when defining subcommands. +//! +//! **Raw attributes:** Any [`Command` method][crate::Command] can also be used as an attribute, +//! see [Terminology](#terminology) for syntax. +//! - e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)` +//! +//! **Magic attributes:** +//! - `name = `: [`Command::name`][crate::App::name] +//! - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (if on [`Parser`][crate::Parser] container), variant name (if on [`Subcommand`][crate::Subcommand] variant) +//! - `version [= ]`: [`Command::version`][crate::App::version] +//! - When not present: no version set +//! - Without ``: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field) +//! - `author [= ]`: [`Command::author`][crate::App::author] +//! - When not present: no author set +//! - Without ``: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field) +//! - `about [= ]`: [`Command::about`][crate::App::about] +//! - When not present: [Doc comment summary](#doc-comments) +//! - Without ``: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) ([`Parser`][crate::Parser] container) +//! - **TIP:** When a doc comment is also present, you most likely want to add +//! `#[clap(long_about = None)]` to clear the doc comment so only [`about`][crate::App::about] +//! gets shown with both `-h` and `--help`. +//! - `long_about = `: [`Command::long_about`][crate::App::long_about] +//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing +//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`about`][crate::App::about] / [`long_about`][crate::App::long_about] +//! - `next_display_order`: [`Command::next_display_order`][crate::App::next_display_order] +//! - `next_help_heading`: [`Command::next_help_heading`][crate::App::next_help_heading] +//! - When `flatten`ing [`Args`][crate::Args], this is scoped to just the args in this struct and any struct `flatten`ed into it +//! - `rename_all = `: Override default field / variant name case conversion for [`Command::name`][crate::Command::name] / [`Arg::id`][crate::Arg::id] +//! - When not present: `"kebab-case"` +//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"` +//! - `rename_all_env = `: Override default field name case conversion for env variables for [`Arg::env`][crate::Arg::env] +//! - When not present: `"SCREAMING_SNAKE_CASE"` +//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"` +//! +//! And for [`Subcommand`][crate::Subcommand] variants: +//! - `skip`: Ignore this variant +//! - `flatten`: Delegates to the variant for more subcommands (must implement +//! [`Subcommand`][crate::Subcommand]) +//! - `subcommand`: Nest subcommands under the current set of subcommands (must implement +//! [`Subcommand`][crate::Subcommand]) +//! - `external_subcommand`: [`Command::allow_external_subcommand(true)`][crate::App::allow_external_subcommands] +//! - Variant must be either `Variant(Vec)` or `Variant(Vec)` +//! +//! ### Arg Attributes +//! +//! These correspond to a [`Arg`][crate::Arg]. +//! +//! **Raw attributes:** Any [`Arg` method][crate::Arg] can also be used as an attribute, see [Terminology](#terminology) for syntax. +//! - e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)` +//! +//! **Magic attributes**: +//! - `id = `: [`Arg::id`][crate::Arg::id] +//! - When not present: case-converted field name is used +//! - `name = `: [`Arg::id`][crate::Arg::id] +//! - **Deprecated:** use `id` +//! - `value_parser [= ]`: [`Arg::value_parser`][crate::Arg::value_parser] +//! - When not present: will auto-select an implementation based on the field type using +//! [`value_parser!][crate::value_parser!] +//! - When present but defaulted: opt-in to clap v4 semantics +//! - Env parsing is now dependent on inferred parser +//! - `PathBuf` will implicitly skip UTF-8 validation (before it required specifying +//! `try_from_os_str`) +//! - When present, implies `#[clap(action)]` +//! - To register a custom type's [`ValueParser`][crate::builder::ValueParser], implement [`ValueParserFactory`][crate::builder::ValueParserFactory] +//! - `action [= ]`: [`Arg::action`][crate::Arg::action] +//! - When not present: will auto-select an action based on the field type +//! - When present but defaulted: opt-in to clap v4 semantics +//! - When present, implies `#[clap(value_parser)]` +//! - `args_override_self` is forced on for single flags +//! - `help = `: [`Arg::help`][crate::Arg::help] +//! - When not present: [Doc comment summary](#doc-comments) +//! - `long_help = `: [`Arg::long_help`][crate::Arg::long_help] +//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing +//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`help`][crate::Arg::help] / [`long_help`][crate::Arg::long_help] +//! - `short [= ]`: [`Arg::short`][crate::Arg::short] +//! - When not present: no short set +//! - Without ``: defaults to first character in the case-converted field name +//! - `long [= ]`: [`Arg::long`][crate::Arg::long] +//! - When not present: no long set +//! - Without ``: defaults to the case-converted field name +//! - `env [= ]`: [`Arg::env`][crate::Arg::env] (needs [`env` feature][crate::_features] enabled) +//! - When not present: no env set +//! - Without ``: defaults to the case-converted field name +//! - `flatten`: Delegates to the field for more arguments (must implement [`Args`][crate::Args]) +//! - Only [`next_help_heading`][crate::Command::next_help_heading] can be used with `flatten`. See +//! [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why +//! arg attributes are not generally supported. +//! - **Tip:** Though we do apply a flattened [`Args`][crate::Args]'s Parent Command Attributes, this +//! makes reuse harder. Generally prefer putting the cmd attributes on the +//! [`Parser`][crate::Parser] or on the flattened field. +//! - `subcommand`: Delegates definition of subcommands to the field (must implement +//! [`Subcommand`][crate::Subcommand]) +//! - When `Option`, the subcommand becomes optional +//! - `from_global`: Read a [`Arg::global`][crate::Arg::global] argument (raw attribute), regardless of what subcommand you are in +//! - `parse( [= ])`: [`Arg::validator`][crate::Arg::validator] and [`ArgMatches::values_of_t`][crate::ArgMatches::values_of_t] +//! - **Deprecated:** +//! - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str` +//! - Use `action(ArgAction::Count` for `from_occurrences` +//! - Use `action(ArgAction::SetTrue` for `from_flag` +//! - Default: `try_from_str` +//! - Warning: for `Path` / `OsString`, be sure to use `try_from_os_str` +//! - See [Arg Types](#arg-types) for more details +//! - `value_enum`: Parse the value using the [`ValueEnum`][crate::ValueEnum] +//! - `skip [= ]`: Ignore this field, filling in with `` +//! - Without ``: fills the field with `Default::default()` +//! - `default_value = `: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required] +//! - `default_value_t [= ]`: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required] +//! - Requires `std::fmt::Display` or `#[clap(value_enum)]` +//! - Without ``, relies on `Default::default()` +//! - `default_values_t = `: [`Arg::default_values`][crate::Arg::default_values] and [`Arg::required(false)`][crate::Arg::required] +//! - Requires field arg to be of type `Vec` and `T` to implement `std::fmt::Display` or `#[clap(value_enum)]` +//! - `` must implement `IntoIterator` +//! - `default_value_os_t [= ]`: [`Arg::default_value_os`][crate::Arg::default_value_os] and [`Arg::required(false)`][crate::Arg::required] +//! - Requires `std::convert::Into` or `#[clap(value_enum)]` +//! - Without ``, relies on `Default::default()` +//! - `default_values_os_t = `: [`Arg::default_values_os`][crate::Arg::default_values_os] and [`Arg::required(false)`][crate::Arg::required] +//! - Requires field arg to be of type `Vec` and `T` to implement `std::convert::Into` or `#[clap(value_enum)]` +//! - `` must implement `IntoIterator` +//! +//! ### ValueEnum Attributes +//! +//! - `rename_all = `: Override default field / variant name case conversion for [`PossibleValue::new`][crate::PossibleValue] +//! - When not present: `"kebab-case"` +//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"` +//! +//! ### Possible Value Attributes +//! +//! These correspond to a [`PossibleValue`][crate::PossibleValue]. +//! +//! **Raw attributes:** Any [`PossibleValue` method][crate::PossibleValue] can also be used as an attribute, see [Terminology](#terminology) for syntax. +//! - e.g. `#[clap(alias("foo"))]` would translate to `pv.alias("foo")` +//! +//! **Magic attributes**: +//! - `name = `: [`PossibleValue::new`][crate::PossibleValue::new] +//! - When not present: case-converted field name is used +//! - `help = `: [`PossibleValue::help`][crate::PossibleValue::help] +//! - When not present: [Doc comment summary](#doc-comments) +//! +//! ## Arg Types +//! +//! `clap` assumes some intent based on the type used: +//! +//! | Type | Effect | Implies | +//! |---------------------|--------------------------------------|------------------------------------------------------------------| +//! | `bool` | flag | `#[clap(parse(from_flag))]` | +//! | `Option` | optional argument | `.takes_value(true).required(false)` | +//! | `Option>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` | +//! | `T` | required argument | `.takes_value(true).required(!has_default)` | +//! | `Vec` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` | +//! | `Option>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` | +//! +//! Notes: +//! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones +//! - For example, see [custom-bool](./custom-bool.md) +//! - `Option>` will be `None` instead of `vec![]` if no arguments are provided. +//! - This gives the user some flexibility in designing their argument, like with `min_values(0)` +//! +//! You can then support your custom type with `#[clap(parse( [= ]))]`: +//! +//! | `` | Signature | Default `` | +//! |--------------------------|---------------------------------------|---------------------------------| +//! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | +//! | `try_from_str` (default) | `fn(&str) -> Result` | `::std::str::FromStr::from_str` | +//! | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` | +//! | `try_from_os_str` | `fn(&OsStr) -> Result` | (no default function) | +//! | `from_occurrences` | `fn(u64) -> T` | `value as T` | +//! | `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` | +//! +//! Notes: +//! - `from_os_str`: +//! - Implies `arg.takes_value(true).allow_invalid_utf8(true)` +//! - `try_from_os_str`: +//! - Implies `arg.takes_value(true).allow_invalid_utf8(true)` +//! - `from_occurrences`: +//! - Implies `arg.takes_value(false).multiple_occurrences(true)` +//! - Reads from `clap::ArgMatches::occurrences_of` rather than a `get_one` function +//! - Note: operations on values, like `default_value`, are unlikely to do what you want +//! - `from_flag` +//! - Implies `arg.takes_value(false)` +//! - Reads from `clap::ArgMatches::is_present` rather than a `get_one` function +//! - Note: operations on values, like `default_value`, are unlikely to do what you want +//! +//! **Warning:** +//! - To support non-UTF8 paths, you should use `#[clap(value_parser)]` otherwise +//! `clap` will parse it as a `String` which will fail on some paths. +//! +//! ## Doc Comments +//! +//! In clap, help messages for the whole binary can be specified +//! via [`Command::about`][crate::App::about] and [`Command::long_about`][crate::App::long_about] while help messages +//! for individual arguments can be specified via [`Arg::help`][crate::Arg::help] and [`Arg::long_help`][crate::Arg::long_help]. +//! +//! `long_*` variants are used when user calls the program with +//! `--help` and "short" variants are used with `-h` flag. +//! +//! ```rust +//! # use clap::Parser; +//! +//! #[derive(Parser)] +//! #[clap(about = "I am a program and I work, just pass `-h`", long_about = None)] +//! struct Foo { +//! #[clap(short, help = "Pass `-h` and you'll see me!")] +//! bar: String, +//! } +//! ``` +//! +//! For convenience, doc comments can be used instead of raw methods +//! (this example works exactly like the one above): +//! +//! ```rust +//! # use clap::Parser; +//! +//! #[derive(Parser)] +//! /// I am a program and I work, just pass `-h` +//! struct Foo { +//! /// Pass `-h` and you'll see me! +//! bar: String, +//! } +//! ``` +//! +//! **NOTE:** Attributes have priority over doc comments! +//! +//! **Top level doc comments always generate `Command::about/long_about` calls!** +//! If you really want to use the `Command::about/long_about` methods (you likely don't), +//! use the `about` / `long_about` attributes to override the calls generated from +//! the doc comment. To clear `long_about`, you can use +//! `#[clap(long_about = None)]`. +//! +//! **TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time. +//! +//! ### Pre-processing +//! +//! ```rust +//! # use clap::Parser; +//! #[derive(Parser)] +//! /// Hi there, I'm Robo! +//! /// +//! /// I like beeping, stumbling, eating your electricity, +//! /// and making records of you singing in a shower. +//! /// Pay up, or I'll upload it to youtube! +//! struct Robo { +//! /// Call my brother SkyNet. +//! /// +//! /// I am artificial superintelligence. I won't rest +//! /// until I'll have destroyed humanity. Enjoy your +//! /// pathetic existence, you mere mortals. +//! #[clap(long, action)] +//! kill_all_humans: bool, +//! } +//! ``` +//! +//! A doc comment consists of three parts: +//! - Short summary +//! - A blank line (whitespace only) +//! - Detailed description, all the rest +//! +//! The summary corresponds with `Command::about` / `Arg::help`. When a blank line is +//! present, the whole doc comment will be passed to `Command::long_about` / +//! `Arg::long_help`. Or in other words, a doc may result in just a `Command::about` / +//! `Arg::help` or `Command::about` / `Arg::help` and `Command::long_about` / +//! `Arg::long_help` +//! +//! In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including: +//! +//! - Strip leading and trailing whitespace from every line, if present. +//! +//! - Strip leading and trailing blank lines, if present. +//! +//! - Interpret each group of non-empty lines as a word-wrapped paragraph. +//! +//! We replace newlines within paragraphs with spaces to allow the output +//! to be re-wrapped to the terminal width. +//! +//! - Strip any excess blank lines so that there is exactly one per paragraph break. +//! +//! - If the first paragraph ends in exactly one period, +//! remove the trailing period (i.e. strip trailing periods but not trailing ellipses). +//! +//! Sometimes you don't want this preprocessing to apply, for example the comment contains +//! some ASCII art or markdown tables, you would need to preserve LFs along with +//! blank lines and the leading/trailing whitespace. When you pass use the +//! `verbatim_doc_comment` magic attribute, you preserve +//! them. +//! +//! **Note:** Keep in mind that `verbatim_doc_comment` will *still* +//! - Remove one leading space from each line, even if this attribute is present, +//! to allow for a space between `///` and the content. +//! - Remove leading and trailing blank lines +//! +//! ## Mixing Builder and Derive APIs +//! +//! The builder and derive APIs do not live in isolation. They can work together, which is +//! especially helpful if some arguments can be specified at compile-time while others must be +//! specified at runtime. +//! +//! ### Using derived arguments in a builder application +//! +//! When using the derive API, you can `#[clap(flatten)]` a struct deriving `Args` into a struct +//! deriving `Args` or `Parser`. This example shows how you can augment a `Command` instance +//! created using the builder API with `Args` created using the derive API. +//! +//! It uses the [`Args::augment_args`][crate::Args::augment_args] method to add the arguments to +//! the `Command` instance. +//! +//! Crates such as [clap-verbosity-flag](https://github.com/rust-cli/clap-verbosity-flag) provide +//! structs that implement `Args`. Without the technique shown in this example, it would not be +//! possible to use such crates with the builder API. +//! +//! For example: +//! ```rust +#![doc = include_str!("../../examples/derive_ref/augment_args.rs")] +//! ``` +//! +//! ### Using derived subcommands in a builder application +//! +//! When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add +//! subcommands. The type of the field is usually an enum that derived `Parser`. However, you can +//! also add the subcommands in that enum to a `Command` instance created with the builder API. +//! +//! It uses the [`Subcommand::augment_subcommands`][crate::Subcommand::augment_subcommands] method +//! to add the subcommands to the `Command` instance. +//! +//! For example: +//! ```rust +#![doc = include_str!("../../examples/derive_ref/augment_subcommands.rs")] +//! ``` +//! +//! ### Adding hand-implemented subcommands to a derived application +//! +//! When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add +//! subcommands. The type of the field is usually an enum that derived `Parser`. However, you can +//! also implement the `Subcommand` trait manually on this enum (or any other type) and it can +//! still be used inside the struct created with the derive API. The implementation of the +//! `Subcommand` trait will use the builder API to add the subcommands to the `Command` instance +//! created behind the scenes for you by the derive API. +//! +//! Notice how in the previous example we used +//! [`augment_subcommands`][crate::Subcommand::augment_subcommands] on an enum that derived +//! `Parser`, whereas now we implement +//! [`augment_subcommands`][crate::Subcommand::augment_subcommands] ourselves, but the derive API +//! calls it automatically since we used the `#[clap(subcommand)]` attribute. +//! +//! For example: +//! ```rust +#![doc = include_str!("../../examples/derive_ref/hand_subcommand.rs")] +//! ``` +//! +//! ### Flattening hand-implemented args into a derived application +//! +//! When using the derive API, you can use `#[clap(flatten)]` inside the struct to add arguments as +//! if they were added directly to the containing struct. The type of the field is usually an +//! struct that derived `Args`. However, you can also implement the `Args` trait manually on this +//! struct (or any other type) and it can still be used inside the struct created with the derive +//! API. The implementation of the `Args` trait will use the builder API to add the arguments to +//! the `Command` instance created behind the scenes for you by the derive API. +//! +//! Notice how in the previous example we used [`augment_args`][crate::Args::augment_args] on the +//! struct that derived `Parser`, whereas now we implement +//! [`augment_args`][crate::Args::augment_args] ourselves, but the derive API calls it +//! automatically since we used the `#[clap(flatten)]` attribute. +//! +//! For example: +//! ```rust +#![doc = include_str!("../../examples/derive_ref/flatten_hand_args.rs")] +//! ``` +//! +//! ## Tips +//! +//! - To get access to a [`Command`][crate::Command] call +//! [`CommandFactory::command`][crate::CommandFactory::command] (implemented when deriving +//! [`Parser`][crate::Parser]) +//! - Proactively check for bad [`Command`][crate::Command] configurations by calling +//! [`Command::debug_assert`][crate::App::debug_assert] in a test +//! ([example](../tutorial_derive/05_01_assert.rs)) + +pub mod _tutorial; +#[doc(inline)] +pub use crate::_cookbook; diff --git a/vendor/clap-3.2.20/src/_faq.rs b/vendor/clap-3.2.20/src/_faq.rs new file mode 100644 index 000000000..661a7e73d --- /dev/null +++ b/vendor/clap-3.2.20/src/_faq.rs @@ -0,0 +1,95 @@ +//! # Documentation: FAQ +//! +//! 1. [Comparisons](#comparisons) +//! 1. [How does `clap` compare to structopt?](#how-does-clap-compare-to-structopt) +//! 2. [What are some reasons to use `clap`? (The Pitch)](#what-are-some-reasons-to-use-clap-the-pitch) +//! 3. [What are some reasons *not* to use `clap`? (The Anti Pitch)](#what-are-some-reasons-not-to-use-clap-the-anti-pitch) +//! 4. [Reasons to use `clap`](#reasons-to-use-clap) +//! 2. [How many approaches are there to create a parser?](#how-many-approaches-are-there-to-create-a-parser) +//! 3. [When should I use the builder vs derive APIs?](#when-should-i-use-the-builder-vs-derive-apis) +//! 4. [Why is there a default subcommand of help?](#why-is-there-a-default-subcommand-of-help) +//! +//! ### Comparisons +//! +//! First, let me say that these comparisons are highly subjective, and not meant +//! in a critical or harsh manner. All the argument parsing libraries out there (to +//! include `clap`) have their own strengths and weaknesses. Sometimes it just +//! comes down to personal taste when all other factors are equal. When in doubt, +//! try them all and pick one that you enjoy :) There's plenty of room in the Rust +//! community for multiple implementations! +//! +//! For less detailed but more broad comparisons, see +//! [argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs). +//! +//! #### How does `clap` compare to [structopt](https://github.com/TeXitoi/structopt)? +//! +//! Simple! `clap` *is* `structopt`. `structopt` started as a derive API built on +//! top of clap v2. With clap v3, we've forked structopt and integrated it +//! directly into clap. structopt is in +//! [maintenance mode](https://github.com/TeXitoi/structopt/issues/516#issuecomment-989566094) +//! with the release of `clap_derive`. +//! +//! The benefits of integrating `structopt` and `clap` are: +//! - Easier cross-linking in documentation +//! - [Documentation parity](../examples) +//! - Tighter design feedback loop, ensuring all new features are designed with +//! derives in mind and easier to change `clap` in response to `structopt` bugs. +//! - Clearer endorsement of `structopt` +//! +//! See also +//! - [`clap` v3 CHANGELOG](../CHANGELOG.md#300---2021-12-31) +//! - [`structopt` migration guide](../CHANGELOG.md#migrate-structopt) +//! +//! #### What are some reasons to use `clap`? (The Pitch) +//! +//! `clap` is as fast, and as lightweight as possible while still giving all the features you'd expect from a modern argument parser. In fact, for the amount and type of features `clap` offers it remains about as fast as `getopts`. If you use `clap` when just need some simple arguments parsed, you'll find it's a walk in the park. `clap` also makes it possible to represent extremely complex, and advanced requirements, without too much thought. `clap` aims to be intuitive, easy to use, and fully capable for wide variety use cases and needs. +//! +//! #### What are some reasons *not* to use `clap`? (The Anti Pitch) +//! +//! Depending on the style in which you choose to define the valid arguments, `clap` can be very verbose. `clap` also offers so many finetuning knobs and dials, that learning everything can seem overwhelming. I strive to keep the simple cases simple, but when turning all those custom dials it can get complex. `clap` is also opinionated about parsing. Even though so much can be tweaked and tuned with `clap` (and I'm adding more all the time), there are still certain features which `clap` implements in specific ways which may be contrary to some users use-cases. +//! +//! #### Reasons to use `clap` +//! +//! * You want all the nice CLI features your users may expect, yet you don't want to implement them all yourself. You'd like to focus your application, not argument parsing. +//! * In addition to the point above; you don't want to sacrifice performance to get all those nice features +//! * You have complex requirements/conflicts between your various valid args. +//! * You want to use subcommands (although other libraries also support subcommands, they are not nearly as feature rich as those provided by `clap`) +//! * You want some sort of custom validation built into the argument parsing process, instead of as part of your application (which allows for earlier failures, better error messages, more cohesive experience, etc.) +//! +//! ### How many approaches are there to create a parser? +//! +//! The following APIs are supported: +//! - [Derive][crate::_derive::_tutorial] +//! - [Builder][crate::_tutorial] +//! +//! Previously, we supported: +//! - [YAML](https://github.com/clap-rs/clap/issues/3087) +//! - [docopt](http://docopt.org/)-inspired [usage parser](https://github.com/clap-rs/clap/issues/3086) +//! - [`clap_app!`](https://github.com/clap-rs/clap/issues/2835) +//! +//! There are also experiments with other APIs: +//! - [fncmd](https://github.com/yuhr/fncmd): function attribute +//! - [clap-serde](https://github.com/aobatact/clap-serde): create an `Command` from a deserializer +//! +//! ### When should I use the builder vs derive APIs? +//! +//! Our default answer is to use the [Derive API][crate::_derive::_tutorial]: +//! - Easier to read, write, and modify +//! - Easier to keep the argument declaration and reading of argument in sync +//! - Easier to reuse, e.g. [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag) +//! +//! The [Builder API][crate::_tutorial] is a lower-level API that someone might want to use for +//! - Faster compile times if you aren't already using other procedural macros +//! - More flexibility, e.g. you can look up an [arguments values][crate::ArgMatches::get_many], +//! their [ordering with other arguments][crate::ArgMatches::indices_of], and [what set +//! them][crate::ArgMatches::value_source]. The Derive API can only report values and not +//! indices of or other data. +//! +//! You can [interop between Derive and Builder APIs][crate::_derive#mixing-builder-and-derive-apis]. +//! +//! ### Why is there a default subcommand of help? +//! +//! There is only a default subcommand of `help` when other subcommands have been defined manually. So it's opt-in(ish), being that you only get a `help` subcommand if you're actually using subcommands. +//! +//! Also, if the user defined a `help` subcommand themselves, the auto-generated one wouldn't be added (meaning it's only generated if the user hasn't defined one themselves). +//! diff --git a/vendor/clap-3.2.20/src/_features.rs b/vendor/clap-3.2.20/src/_features.rs new file mode 100644 index 000000000..923134c45 --- /dev/null +++ b/vendor/clap-3.2.20/src/_features.rs @@ -0,0 +1,27 @@ +//! ## Documentation: Feature Flags +//! +//! Available [compile-time feature flags](https://doc.rust-lang.org/cargo/reference/features.html#dependency-features) +//! +//! #### Default Features +//! +//! * **std**: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner. +//! * **color**: Turns on colored error messages. +//! * **suggestions**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. +//! +//! #### Optional features +//! +//! * **deprecated**: Guided experience to prepare for next breaking release (at different stages of development, this may become default) +//! * **derive**: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above. +//! * **cargo**: Turns on macros that read values from [`CARGO_*` environment variables](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates). +//! * **env**: Turns on the usage of environment variables during parsing. +//! * **regex**: Enables regex validators. +//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages. +//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size. +//! +//! #### Experimental features +//! +//! **Warning:** These may contain breaking changes between minor releases. +//! +//! * **unstable-replace**: Enable [`Command::replace`](https://github.com/clap-rs/clap/issues/2836) +//! * **unstable-grouped**: Enable [`ArgMatches::grouped_values_of`](https://github.com/clap-rs/clap/issues/2924) +//! * **unstable-v4**: Preview features which will be stable on the v4.0 release diff --git a/vendor/clap-3.2.20/src/_tutorial.rs b/vendor/clap-3.2.20/src/_tutorial.rs new file mode 100644 index 000000000..9dbfc6864 --- /dev/null +++ b/vendor/clap-3.2.20/src/_tutorial.rs @@ -0,0 +1,204 @@ +// Contributing +// +// New example code: +// - Please update the corresponding section in the derive tutorial +// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. +// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax +// +// See also the general CONTRIBUTING + +//! # Documentation: Builder Tutorial +//! +//! 1. [Quick Start](#quick-start) +//! 2. [Configuring the Parser](#configuring-the-parser) +//! 3. [Adding Arguments](#adding-arguments) +//! 1. [Positionals](#positionals) +//! 2. [Options](#options) +//! 3. [Flags](#flags) +//! 4. [Subcommands](#subcommands) +//! 5. [Defaults](#defaults) +//! 4. Validation +//! 1. [Enumerated values](#enumerated-values) +//! 2. [Validated values](#validated-values) +//! 3. [Argument Relations](#argument-relations) +//! 4. [Custom Validation](#custom-validation) +//! 5. [Testing](#testing) +//! +//! See also +//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis] +//! - The [cookbook][crate::_cookbook] for more application-focused examples +//! +//! ## Quick Start +//! +//! You can create an application with several arguments using usage strings. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/01_quick.rs")] +//! ``` +//! +#![doc = include_str!("../examples/tutorial_builder/01_quick.md")] +//! +//! ## Configuring the Parser +//! +//! You use [`Command`][crate::Command] to start building a parser. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/02_apps.rs")] +//! ``` +//! +#![doc = include_str!("../examples/tutorial_builder/02_apps.md")] +//! +//! You can use [`command!()`][crate::command!] to fill these fields in from your `Cargo.toml` +//! file. **This requires the [`cargo` feature flag][crate::_features].** +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/02_crate.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/02_crate.md")] +//! +//! You can use [`Command`][crate::Command] methods to change the application level behavior of +//! clap. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/02_app_settings.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/02_app_settings.md")] +//! +//! ## Adding Arguments +//! +//! ### Positionals +//! +//! You can have users specify values by their position on the command-line: +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/03_03_positional.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/03_03_positional.md")] +//! +//! ### Options +//! +//! You can name your arguments with a flag: +//! - Order doesn't matter +//! - They can be optional +//! - Intent is clearer +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/03_02_option.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/03_02_option.md")] +//! +//! ### Flags +//! +//! Flags can also be switches that can be on/off: +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.md")] +//! +//! Or counted. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.md")] +//! +//! ### Subcommands +//! +//! Subcommands are defined as [`Command`][crate::Command]s that get added via +//! [`Command::subcommand`][crate::Command::subcommand]. Each instance of a Subcommand can have its +//! own version, author(s), Args, and even its own subcommands. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.md")] +//! +//! ### Defaults +//! +//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional. +//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can set +//! [`Arg::default_value`][crate::Arg::default_value]. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.md")] +//! +//! ## Validation +//! +//! ### Enumerated values +//! +//! If you have arguments of specific values you want to test for, you can use the +//! [`PossibleValuesParser`][crate::builder::PossibleValuesParser] or [`Arg::value_parser(["val1", +//! ...])`][crate::Arg::value_parser] for short. +//! +//! This allows you specify the valid values for that argument. If the user does not use one of +//! those specific values, they will receive a graceful exit with error message informing them +//! of the mistake, and what the possible valid values are +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/04_01_possible.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/04_01_possible.md")] +//! +//! When enabling the [`derive` feature][crate::_features], you can use +//! [`ValueEnum`][crate::ValueEnum] to take care of the boiler plate for you, giving the same +//! results. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/04_01_enum.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/04_01_enum.md")] +//! +//! ### Validated values +//! +//! More generally, you can validate and parse into any data type. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/04_02_parse.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/04_02_parse.md")] +//! +//! A custom parser can be used to improve the error messages or provide additional validation: +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/04_02_validate.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/04_02_validate.md")] +//! +//! ### Argument Relations +//! +//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even +//! [`ArgGroup`][crate::ArgGroup]s. +//! +//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list +//! each individually, or when you want a rule to apply "any but not all" arguments. +//! +//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one +//! argument to be present out of a given set. Imagine that you had multiple arguments, and you +//! want one of them to be required, but making all of them required isn't feasible because perhaps +//! they conflict with each other. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/04_03_relations.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/04_03_relations.md")] +//! +//! ### Custom Validation +//! +//! As a last resort, you can create custom errors with the basics of clap's formatting. +//! +//! ```rust +#![doc = include_str!("../examples/tutorial_builder/04_04_custom.rs")] +//! ``` +#![doc = include_str!("../examples/tutorial_builder/04_04_custom.md")] +//! +//! ## Testing +//! +//! clap reports most development errors as `debug_assert!`s. Rather than checking every +//! subcommand, you should have a test that calls +//! [`Command::debug_assert`][crate::App::debug_assert]: +//! ```rust,no_run +#![doc = include_str!("../examples/tutorial_builder/05_01_assert.rs")] +//! ``` diff --git a/vendor/clap-3.2.20/src/bin/stdio-fixture.rs b/vendor/clap-3.2.20/src/bin/stdio-fixture.rs new file mode 100644 index 000000000..e3f34b41a --- /dev/null +++ b/vendor/clap-3.2.20/src/bin/stdio-fixture.rs @@ -0,0 +1,14 @@ +fn main() { + let cmd = clap::Command::new("stdio-fixture") + .version("1.0") + .long_version("1.0 - a2132c") + .arg_required_else_help(true) + .subcommand(clap::Command::new("more")) + .arg( + clap::Arg::new("verbose") + .long("verbose") + .help("log") + .long_help("more log"), + ); + cmd.get_matches(); +} diff --git a/vendor/clap-3.2.20/src/builder/action.rs b/vendor/clap-3.2.20/src/builder/action.rs new file mode 100644 index 000000000..71a91a8b1 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/action.rs @@ -0,0 +1,325 @@ +/// Behavior of arguments when they are encountered while parsing +/// +/// # Examples +/// +/// ```rust +/// # use clap::Command; +/// # use clap::Arg; +/// let cmd = Command::new("mycmd") +/// .arg( +/// Arg::new("special-help") +/// .short('?') +/// .action(clap::ArgAction::Help) +/// ); +/// +/// // Existing help still exists +/// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); +/// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); +/// +/// // New help available +/// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); +/// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); +/// ``` +#[derive(Clone, Debug)] +#[non_exhaustive] +#[allow(missing_copy_implementations)] // In the future, we may accept `Box` +pub enum ArgAction { + /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::Set) + /// ); + /// + /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_many::("flag").unwrap_or_default().map(|v| v.as_str()).collect::>(), + /// vec!["value"] + /// ); + /// ``` + Set, + /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::Append) + /// ); + /// + /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value1", "--flag", "value2"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_many::("flag").unwrap_or_default().map(|v| v.as_str()).collect::>(), + /// vec!["value1", "value2"] + /// ); + /// ``` + Append, + /// Deprecated, replaced with [`ArgAction::Set`] or [`ArgAction::Append`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `ArgAction::Set` or `ArgAction::Append`" + ) + )] + StoreValue, + /// Deprecated, replaced with [`ArgAction::SetTrue`] or [`ArgAction::Count`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `ArgAction::SetTrue` or `ArgAction::Count`" + ) + )] + IncOccurrence, + /// When encountered, act as if `"true"` was encountered on the command-line + /// + /// If no [`default_value`][super::Arg::default_value] is set, it will be `false`. + /// + /// No value is allowed. To optionally accept a value, see + /// [`Arg::default_missing_value`][super::Arg::default_missing_value] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::SetTrue) + /// ); + /// + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_one::("flag").copied(), + /// Some(true) + /// ); + /// + /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_one::("flag").copied(), + /// Some(false) + /// ); + /// ``` + SetTrue, + /// When encountered, act as if `"false"` was encountered on the command-line + /// + /// If no [`default_value`][super::Arg::default_value] is set, it will be `true`. + /// + /// No value is allowed. To optionally accept a value, see + /// [`Arg::default_missing_value`][super::Arg::default_missing_value] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::SetFalse) + /// ); + /// + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_one::("flag").copied(), + /// Some(false) + /// ); + /// + /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_one::("flag").copied(), + /// Some(true) + /// ); + /// ``` + SetFalse, + /// When encountered, increment a `u8` counter + /// + /// If no [`default_value`][super::Arg::default_value] is set, it will be `0`. + /// + /// No value is allowed. To optionally accept a value, see + /// [`Arg::default_missing_value`][super::Arg::default_missing_value] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::Count) + /// ); + /// + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_count("flag"), + /// 2 + /// ); + /// + /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_count("flag"), + /// 0 + /// ); + /// ``` + Count, + /// When encountered, display [`Command::print_help`][super::App::print_help] + /// + /// Depending on the flag, [`Command::print_long_help`][super::App::print_long_help] may be shown + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("special-help") + /// .short('?') + /// .action(clap::ArgAction::Help) + /// ); + /// + /// // Existing help still exists + /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + /// + /// // New help available + /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + /// ``` + Help, + /// When encountered, display [`Command::version`][super::App::version] + /// + /// Depending on the flag, [`Command::long_version`][super::App::long_version] may be shown + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .version("1.0.0") + /// .arg( + /// Arg::new("special-version") + /// .long("special-version") + /// .action(clap::ArgAction::Version) + /// ); + /// + /// // Existing help still exists + /// let err = cmd.clone().try_get_matches_from(["mycmd", "--version"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion); + /// + /// // New help available + /// let err = cmd.try_get_matches_from(["mycmd", "--special-version"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion); + /// ``` + Version, +} + +impl ArgAction { + /// Returns whether this action accepts values on the command-line + /// + /// [`default_values`][super::Arg::default_values] and [`env`][super::Arg::env] may still be + /// processed. + pub fn takes_values(&self) -> bool { + match self { + Self::Set => true, + Self::Append => true, + #[allow(deprecated)] + Self::StoreValue => true, + #[allow(deprecated)] + Self::IncOccurrence => false, + Self::SetTrue => false, + Self::SetFalse => false, + Self::Count => false, + Self::Help => false, + Self::Version => false, + } + } + + pub(crate) fn default_value(&self) -> Option<&'static std::ffi::OsStr> { + match self { + Self::Set => None, + Self::Append => None, + #[allow(deprecated)] + Self::StoreValue => None, + #[allow(deprecated)] + Self::IncOccurrence => None, + Self::SetTrue => Some(std::ffi::OsStr::new("false")), + Self::SetFalse => Some(std::ffi::OsStr::new("true")), + Self::Count => Some(std::ffi::OsStr::new("0")), + Self::Help => None, + Self::Version => None, + } + } + + pub(crate) fn default_value_parser(&self) -> Option { + match self { + Self::Set => None, + Self::Append => None, + #[allow(deprecated)] + Self::StoreValue => None, + #[allow(deprecated)] + Self::IncOccurrence => None, + Self::SetTrue => Some(super::ValueParser::bool()), + Self::SetFalse => Some(super::ValueParser::bool()), + Self::Count => Some(crate::value_parser!(u8).into()), + Self::Help => None, + Self::Version => None, + } + } + + #[cfg(debug_assertions)] + pub(crate) fn value_type_id(&self) -> Option { + use crate::parser::AnyValueId; + + match self { + Self::Set => None, + Self::Append => None, + #[allow(deprecated)] + Self::StoreValue => None, + #[allow(deprecated)] + Self::IncOccurrence => None, + Self::SetTrue => Some(AnyValueId::of::()), + Self::SetFalse => Some(AnyValueId::of::()), + Self::Count => Some(AnyValueId::of::()), + Self::Help => None, + Self::Version => None, + } + } +} + +pub(crate) type CountType = u8; diff --git a/vendor/clap-3.2.20/src/builder/app_settings.rs b/vendor/clap-3.2.20/src/builder/app_settings.rs new file mode 100644 index 000000000..88bc243c4 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/app_settings.rs @@ -0,0 +1,864 @@ +#![allow(deprecated)] + +// Std +use std::ops::BitOr; +#[cfg(feature = "yaml")] +use std::str::FromStr; + +#[allow(unused)] +use crate::Arg; +#[allow(unused)] +use crate::Command; + +// Third party +use bitflags::bitflags; + +#[doc(hidden)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct AppFlags(Flags); + +impl Default for AppFlags { + fn default() -> Self { + AppFlags(Flags::COLOR_AUTO) + } +} + +/// Application level settings, which affect how [`Command`] operates +/// +/// **NOTE:** When these settings are used, they apply only to current command, and are *not* +/// propagated down or up through child or parent subcommands +/// +/// [`Command`]: crate::Command +#[derive(Debug, PartialEq, Copy, Clone)] +#[non_exhaustive] +pub enum AppSettings { + /// Deprecated, replaced with [`Command::ignore_errors`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command::ignore_errors`") + )] + IgnoreErrors, + + /// Deprecated, replace + /// ```rust,no_run + /// let cmd = clap::Command::new("cmd") + /// .global_setting(clap::AppSettings::WaitOnError) + /// .arg(clap::arg!(--flag)); + /// let m = cmd.get_matches(); + /// ``` + /// with + /// ```rust + /// let cmd = clap::Command::new("cmd") + /// .arg(clap::arg!(--flag)); + /// let m = match cmd.try_get_matches() { + /// Ok(m) => m, + /// Err(err) => { + /// if err.use_stderr() { + /// let _ = err.print(); + /// + /// eprintln!("\nPress [ENTER] / [RETURN] to continue..."); + /// use std::io::BufRead; + /// let mut s = String::new(); + /// let i = std::io::stdin(); + /// i.lock().read_line(&mut s).unwrap(); + /// + /// std::process::exit(2); + /// } else { + /// let _ = err.print(); + /// std::process::exit(0); + /// } + /// } + /// }; + /// ``` + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "See documentation for how to hand-implement this" + ) + )] + WaitOnError, + + /// Deprecated, replaced with [`Command::allow_hyphen_values`] and + /// [`Arg::is_allow_hyphen_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`" + ) + )] + AllowHyphenValues, + + /// Deprecated, replaced with [`Command::allow_negative_numbers`] and + /// [`Command::is_allow_negative_numbers_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::allow_negative_numbers` and `Command::is_allow_negative_numbers_set`" + ) + )] + AllowNegativeNumbers, + + /// Deprecated, replaced with [`Command::args_override_self`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command::args_override_self`") + )] + AllArgsOverrideSelf, + + /// Deprecated, replaced with [`Command::allow_missing_positional`] and + /// [`Command::is_allow_missing_positional_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::allow_missing_positional` and `Command::is_allow_missing_positional_set`" + ) + )] + AllowMissingPositional, + + /// Deprecated, replaced with [`Command::trailing_var_arg`] and [`Command::is_trailing_var_arg_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::trailing_var_arg` and `Command::is_trailing_var_arg_set`" + ) + )] + TrailingVarArg, + + /// Deprecated, replaced with [`Command::dont_delimit_trailing_values`] and + /// [`Command::is_dont_delimit_trailing_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::dont_delimit_trailing_values` and `Command::is_dont_delimit_trailing_values_set`" + ) + )] + DontDelimitTrailingValues, + + /// Deprecated, replaced with [`Command::infer_long_args`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command::infer_long_args`") + )] + InferLongArgs, + + /// Deprecated, replaced with [`Command::infer_subcommands`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command::infer_subcommands`") + )] + InferSubcommands, + + /// Deprecated, replaced with [`Command::subcommand_required`] and + /// [`Command::is_subcommand_required_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::subcommand_required` and `Command::is_subcommand_required_set`" + ) + )] + SubcommandRequired, + + /// Deprecated, replaced with [`Command::subcommand_required`] combined with + /// [`Command::arg_required_else_help`]. + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::subcommand_required` combined with `Command::arg_required_else_help`" + ) + )] + SubcommandRequiredElseHelp, + + /// Deprecated, replaced with [`Command::allow_external_subcommands`] and + /// [`Command::is_allow_external_subcommands_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::allow_external_subcommands` and `Command::is_allow_external_subcommands_set`" + ) + )] + AllowExternalSubcommands, + + /// Deprecated, replaced with [`Command::multicall`] and [`Command::is_multicall_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::multicall` and `Command::is_multicall_set`" + ) + )] + Multicall, + + /// Deprecated, replaced with [`Command::allow_invalid_utf8_for_external_subcommands`] and [`Command::is_allow_invalid_utf8_for_external_subcommands_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::allow_invalid_utf8_for_external_subcommands` and `Command::is_allow_invalid_utf8_for_external_subcommands_set`" + ) + )] + AllowInvalidUtf8ForExternalSubcommands, + + /// Deprecated, this is now the default + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "This is now the default") + )] + UseLongFormatForHelpSubcommand, + + /// Deprecated, replaced with [`Command::subcommand_negates_reqs`] and + /// [`Command::is_subcommand_negates_reqs_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::subcommand_negates_reqs` and `Command::is_subcommand_negates_reqs_set`" + ) + )] + SubcommandsNegateReqs, + + /// Deprecated, replaced with [`Command::args_conflicts_with_subcommands`] and + /// [`Command::is_args_conflicts_with_subcommands_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::args_conflicts_with_subcommands` and `Command::is_args_conflicts_with_subcommands_set`" + ) + )] + ArgsNegateSubcommands, + + /// Deprecated, replaced with [`Command::subcommand_precedence_over_arg`] and + /// [`Command::is_subcommand_precedence_over_arg_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::subcommand_precedence_over_arg` and `Command::is_subcommand_precedence_over_arg_set`" + ) + )] + SubcommandPrecedenceOverArg, + + /// Deprecated, replaced with [`Command::arg_required_else_help`] and + /// [`Command::is_arg_required_else_help_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::arg_required_else_help` and `Command::is_arg_required_else_help_set`" + ) + )] + ArgRequiredElseHelp, + + /// Displays the arguments and [`subcommands`] in the help message in the order that they were + /// declared in, and not alphabetically which is the default. + /// + /// To override the declaration order, see [`Arg::display_order`] and [`Command::display_order`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, AppSettings}; + /// Command::new("myprog") + /// .global_setting(AppSettings::DeriveDisplayOrder) + /// .get_matches(); + /// ``` + /// + /// [`subcommands`]: crate::Command::subcommand() + /// [`Arg::display_order`]: crate::Arg::display_order + /// [`Command::display_order`]: crate::Command::display_order + DeriveDisplayOrder, + + /// Deprecated, replaced with [`Command::dont_collapse_args_in_usage`] and + /// [`Command::is_dont_collapse_args_in_usage_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::dont_collapse_args_in_usage` and `Command::is_dont_collapse_args_in_usage_set`" + ) + )] + DontCollapseArgsInUsage, + + /// Deprecated, replaced with [`Command::next_line_help`] and [`Command::is_next_line_help_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::next_line_help` and `Command::is_next_line_help_set`" + ) + )] + NextLineHelp, + + /// Deprecated, replaced with [`Command::disable_colored_help`] and + /// [`Command::is_disable_colored_help_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::disable_colored_help` and `Command::is_disable_colored_help_set`" + ) + )] + DisableColoredHelp, + + /// Deprecated, replaced with [`Command::disable_help_flag`] and [`Command::is_disable_help_flag_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::disable_help_flag` and `Command::is_disable_help_flag_set`" + ) + )] + DisableHelpFlag, + + /// Deprecated, replaced with [`Command::disable_help_subcommand`] and + /// [`Command::is_disable_help_subcommand_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::disable_help_subcommand` and `Command::is_disable_help_subcommand_set`" + ) + )] + DisableHelpSubcommand, + + /// Deprecated, replaced with [`Command::disable_version_flag`] and + /// [`Command::is_disable_version_flag_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::disable_version_flag` and `Command::is_disable_version_flag_set`" + ) + )] + DisableVersionFlag, + + /// Deprecated, replaced with [`Command::propagate_version`] and [`Command::is_propagate_version_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::propagate_version` and `Command::is_propagate_version_set`" + ) + )] + PropagateVersion, + + /// Deprecated, replaced with [`Command::hide`] and [`Command::is_hide_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::hide` and `Command::is_hide_set`" + ) + )] + Hidden, + + /// Deprecated, replaced with [`Command::hide_possible_values`] and + /// [`Arg::is_hide_possible_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Command::hide_possible_values` and `Arg::is_hide_possible_values_set`" + ) + )] + HidePossibleValues, + + /// Deprecated, replaced with [`Command::help_expected`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command::help_expected`") + )] + HelpExpected, + + /// Deprecated, replaced with [`Command::no_binary_name`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command::no_binary_name`") + )] + NoBinaryName, + + /// Deprecated, replaced with [`Arg::action`][super::Arg::action] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::action`") + )] + NoAutoHelp, + + /// Deprecated, replaced with [`Arg::action`][super::Arg::action] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::action`") + )] + NoAutoVersion, + + /// Deprecated, replaced with [`Command::allow_hyphen_values`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Command::allow_hyphen_values`") + )] + #[doc(hidden)] + AllowLeadingHyphen, + + /// Deprecated, replaced with [`Command::allow_invalid_utf8_for_external_subcommands`] and [`Command::is_allow_invalid_utf8_for_external_subcommands_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Command::allow_invalid_utf8_for_external_subcommands` and `Command::is_allow_invalid_utf8_for_external_subcommands_set`" + ) + )] + #[doc(hidden)] + StrictUtf8, + + /// Deprecated, this is now the default + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "This is now the default") + )] + #[doc(hidden)] + UnifiedHelpMessage, + + /// Deprecated, this is now the default + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "This is now the default") + )] + #[doc(hidden)] + ColoredHelp, + + /// Deprecated, see [`Command::color`][crate::Command::color] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Command::color`") + )] + #[doc(hidden)] + ColorAuto, + + /// Deprecated, replaced with [`Command::color`][crate::Command::color] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Command::color`") + )] + #[doc(hidden)] + ColorAlways, + + /// Deprecated, replaced with [`Command::color`][crate::Command::color] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Command::color`") + )] + #[doc(hidden)] + ColorNever, + + /// Deprecated, replaced with [`Command::disable_help_flag`] and [`Command::is_disable_help_flag_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Command::disable_help_flag` and `Command::is_disable_help_flag_set`" + ) + )] + #[doc(hidden)] + DisableHelpFlags, + + /// Deprecated, replaced with [`Command::disable_version_flag`] and + /// [`Command::is_disable_version_flag_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Command::disable_version_flag` and `Command::is_disable_version_flag_set`" + ) + )] + #[doc(hidden)] + DisableVersion, + + /// Deprecated, replaced with [`Command::propagate_version`] and [`Command::is_propagate_version_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Command::propagate_version` and `Command::is_propagate_version_set`" + ) + )] + #[doc(hidden)] + GlobalVersion, + + /// Deprecated, replaced with [`Command::hide_possible_values`] and + /// [`Arg::is_hide_possible_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Command::hide_possible_values` and `Arg::is_hide_possible_values_set`" + ) + )] + #[doc(hidden)] + HidePossibleValuesInHelp, + + /// Deprecated, this is now the default + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "This is now the default") + )] + #[doc(hidden)] + UnifiedHelp, + + /// If the cmd is already built, used for caching. + #[doc(hidden)] + Built, + + /// If the cmd's bin name is already built, used for caching. + #[doc(hidden)] + BinNameBuilt, +} + +bitflags! { + struct Flags: u64 { + const SC_NEGATE_REQS = 1; + const SC_REQUIRED = 1 << 1; + const ARG_REQUIRED_ELSE_HELP = 1 << 2; + const PROPAGATE_VERSION = 1 << 3; + const DISABLE_VERSION_FOR_SC = 1 << 4; + const WAIT_ON_ERROR = 1 << 6; + const SC_REQUIRED_ELSE_HELP = 1 << 7; + const NO_AUTO_HELP = 1 << 8; + const NO_AUTO_VERSION = 1 << 9; + const DISABLE_VERSION_FLAG = 1 << 10; + const HIDDEN = 1 << 11; + const TRAILING_VARARG = 1 << 12; + const NO_BIN_NAME = 1 << 13; + const ALLOW_UNK_SC = 1 << 14; + const SC_UTF8_NONE = 1 << 15; + const LEADING_HYPHEN = 1 << 16; + const NO_POS_VALUES = 1 << 17; + const NEXT_LINE_HELP = 1 << 18; + const DERIVE_DISP_ORDER = 1 << 19; + const DISABLE_COLORED_HELP = 1 << 20; + const COLOR_ALWAYS = 1 << 21; + const COLOR_AUTO = 1 << 22; + const COLOR_NEVER = 1 << 23; + const DONT_DELIM_TRAIL = 1 << 24; + const ALLOW_NEG_NUMS = 1 << 25; + const DISABLE_HELP_SC = 1 << 27; + const DONT_COLLAPSE_ARGS = 1 << 28; + const ARGS_NEGATE_SCS = 1 << 29; + const PROPAGATE_VALS_DOWN = 1 << 30; + const ALLOW_MISSING_POS = 1 << 31; + const TRAILING_VALUES = 1 << 32; + const BUILT = 1 << 33; + const BIN_NAME_BUILT = 1 << 34; + const VALID_ARG_FOUND = 1 << 35; + const INFER_SUBCOMMANDS = 1 << 36; + const CONTAINS_LAST = 1 << 37; + const ARGS_OVERRIDE_SELF = 1 << 38; + const HELP_REQUIRED = 1 << 39; + const SUBCOMMAND_PRECEDENCE_OVER_ARG = 1 << 40; + const DISABLE_HELP_FLAG = 1 << 41; + const USE_LONG_FORMAT_FOR_HELP_SC = 1 << 42; + const INFER_LONG_ARGS = 1 << 43; + const IGNORE_ERRORS = 1 << 44; + const MULTICALL = 1 << 45; + const NO_OP = 0; + } +} + +impl_settings! { AppSettings, AppFlags, + ArgRequiredElseHelp + => Flags::ARG_REQUIRED_ELSE_HELP, + SubcommandPrecedenceOverArg + => Flags::SUBCOMMAND_PRECEDENCE_OVER_ARG, + ArgsNegateSubcommands + => Flags::ARGS_NEGATE_SCS, + AllowExternalSubcommands + => Flags::ALLOW_UNK_SC, + StrictUtf8 + => Flags::NO_OP, + AllowInvalidUtf8ForExternalSubcommands + => Flags::SC_UTF8_NONE, + AllowHyphenValues + => Flags::LEADING_HYPHEN, + AllowLeadingHyphen + => Flags::LEADING_HYPHEN, + AllowNegativeNumbers + => Flags::ALLOW_NEG_NUMS, + AllowMissingPositional + => Flags::ALLOW_MISSING_POS, + UnifiedHelpMessage + => Flags::NO_OP, + ColoredHelp + => Flags::NO_OP, + ColorAlways + => Flags::COLOR_ALWAYS, + ColorAuto + => Flags::COLOR_AUTO, + ColorNever + => Flags::COLOR_NEVER, + DontDelimitTrailingValues + => Flags::DONT_DELIM_TRAIL, + DontCollapseArgsInUsage + => Flags::DONT_COLLAPSE_ARGS, + DeriveDisplayOrder + => Flags::DERIVE_DISP_ORDER, + DisableColoredHelp + => Flags::DISABLE_COLORED_HELP, + DisableHelpSubcommand + => Flags::DISABLE_HELP_SC, + DisableHelpFlag + => Flags::DISABLE_HELP_FLAG, + DisableHelpFlags + => Flags::DISABLE_HELP_FLAG, + DisableVersionFlag + => Flags::DISABLE_VERSION_FLAG, + DisableVersion + => Flags::DISABLE_VERSION_FLAG, + PropagateVersion + => Flags::PROPAGATE_VERSION, + GlobalVersion + => Flags::PROPAGATE_VERSION, + HidePossibleValues + => Flags::NO_POS_VALUES, + HidePossibleValuesInHelp + => Flags::NO_POS_VALUES, + HelpExpected + => Flags::HELP_REQUIRED, + Hidden + => Flags::HIDDEN, + Multicall + => Flags::MULTICALL, + NoAutoHelp + => Flags::NO_AUTO_HELP, + NoAutoVersion + => Flags::NO_AUTO_VERSION, + NoBinaryName + => Flags::NO_BIN_NAME, + SubcommandsNegateReqs + => Flags::SC_NEGATE_REQS, + SubcommandRequired + => Flags::SC_REQUIRED, + SubcommandRequiredElseHelp + => Flags::SC_REQUIRED_ELSE_HELP, + UseLongFormatForHelpSubcommand + => Flags::USE_LONG_FORMAT_FOR_HELP_SC, + TrailingVarArg + => Flags::TRAILING_VARARG, + UnifiedHelp => Flags::NO_OP, + NextLineHelp + => Flags::NEXT_LINE_HELP, + IgnoreErrors + => Flags::IGNORE_ERRORS, + WaitOnError + => Flags::WAIT_ON_ERROR, + Built + => Flags::BUILT, + BinNameBuilt + => Flags::BIN_NAME_BUILT, + InferSubcommands + => Flags::INFER_SUBCOMMANDS, + AllArgsOverrideSelf + => Flags::ARGS_OVERRIDE_SELF, + InferLongArgs + => Flags::INFER_LONG_ARGS +} + +/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? +#[cfg(feature = "yaml")] +impl FromStr for AppSettings { + type Err = String; + fn from_str(s: &str) -> Result::Err> { + #[allow(deprecated)] + #[allow(unreachable_patterns)] + match &*s.to_ascii_lowercase() { + "argrequiredelsehelp" => Ok(AppSettings::ArgRequiredElseHelp), + "subcommandprecedenceoverarg" => Ok(AppSettings::SubcommandPrecedenceOverArg), + "argsnegatesubcommands" => Ok(AppSettings::ArgsNegateSubcommands), + "allowexternalsubcommands" => Ok(AppSettings::AllowExternalSubcommands), + "strictutf8" => Ok(AppSettings::StrictUtf8), + "allowinvalidutf8forexternalsubcommands" => { + Ok(AppSettings::AllowInvalidUtf8ForExternalSubcommands) + } + "allowhyphenvalues" => Ok(AppSettings::AllowHyphenValues), + "allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen), + "allownegativenumbers" => Ok(AppSettings::AllowNegativeNumbers), + "allowmissingpositional" => Ok(AppSettings::AllowMissingPositional), + "unifiedhelpmessage" => Ok(AppSettings::UnifiedHelpMessage), + "coloredhelp" => Ok(AppSettings::ColoredHelp), + "coloralways" => Ok(AppSettings::ColorAlways), + "colorauto" => Ok(AppSettings::ColorAuto), + "colornever" => Ok(AppSettings::ColorNever), + "dontdelimittrailingvalues" => Ok(AppSettings::DontDelimitTrailingValues), + "dontcollapseargsinusage" => Ok(AppSettings::DontCollapseArgsInUsage), + "derivedisplayorder" => Ok(AppSettings::DeriveDisplayOrder), + "disablecoloredhelp" => Ok(AppSettings::DisableColoredHelp), + "disablehelpsubcommand" => Ok(AppSettings::DisableHelpSubcommand), + "disablehelpflag" => Ok(AppSettings::DisableHelpFlag), + "disablehelpflags" => Ok(AppSettings::DisableHelpFlags), + "disableversionflag" => Ok(AppSettings::DisableVersionFlag), + "disableversion" => Ok(AppSettings::DisableVersion), + "propagateversion" => Ok(AppSettings::PropagateVersion), + "propagateversion" => Ok(AppSettings::GlobalVersion), + "hidepossiblevalues" => Ok(AppSettings::HidePossibleValues), + "hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp), + "helpexpected" => Ok(AppSettings::HelpExpected), + "hidden" => Ok(AppSettings::Hidden), + "noautohelp" => Ok(AppSettings::NoAutoHelp), + "noautoversion" => Ok(AppSettings::NoAutoVersion), + "nobinaryname" => Ok(AppSettings::NoBinaryName), + "subcommandsnegatereqs" => Ok(AppSettings::SubcommandsNegateReqs), + "subcommandrequired" => Ok(AppSettings::SubcommandRequired), + "subcommandrequiredelsehelp" => Ok(AppSettings::SubcommandRequiredElseHelp), + "uselongformatforhelpsubcommand" => Ok(AppSettings::UseLongFormatForHelpSubcommand), + "trailingvararg" => Ok(AppSettings::TrailingVarArg), + "unifiedhelp" => Ok(AppSettings::UnifiedHelp), + "nextlinehelp" => Ok(AppSettings::NextLineHelp), + "ignoreerrors" => Ok(AppSettings::IgnoreErrors), + "waitonerror" => Ok(AppSettings::WaitOnError), + "built" => Ok(AppSettings::Built), + "binnamebuilt" => Ok(AppSettings::BinNameBuilt), + "infersubcommands" => Ok(AppSettings::InferSubcommands), + "allargsoverrideself" => Ok(AppSettings::AllArgsOverrideSelf), + "inferlongargs" => Ok(AppSettings::InferLongArgs), + _ => Err(format!("unknown AppSetting: `{}`", s)), + } + } +} + +#[cfg(test)] +mod test { + #[allow(clippy::cognitive_complexity)] + #[test] + #[cfg(feature = "yaml")] + fn app_settings_fromstr() { + use super::AppSettings; + + assert_eq!( + "disablehelpflag".parse::().unwrap(), + AppSettings::DisableHelpFlag + ); + assert_eq!( + "argsnegatesubcommands".parse::().unwrap(), + AppSettings::ArgsNegateSubcommands + ); + assert_eq!( + "argrequiredelsehelp".parse::().unwrap(), + AppSettings::ArgRequiredElseHelp + ); + assert_eq!( + "subcommandprecedenceoverarg" + .parse::() + .unwrap(), + AppSettings::SubcommandPrecedenceOverArg + ); + assert_eq!( + "allowexternalsubcommands".parse::().unwrap(), + AppSettings::AllowExternalSubcommands + ); + assert_eq!( + "allowinvalidutf8forexternalsubcommands" + .parse::() + .unwrap(), + AppSettings::AllowInvalidUtf8ForExternalSubcommands + ); + assert_eq!( + "allowhyphenvalues".parse::().unwrap(), + AppSettings::AllowHyphenValues + ); + assert_eq!( + "allownegativenumbers".parse::().unwrap(), + AppSettings::AllowNegativeNumbers + ); + assert_eq!( + "disablehelpsubcommand".parse::().unwrap(), + AppSettings::DisableHelpSubcommand + ); + assert_eq!( + "disableversionflag".parse::().unwrap(), + AppSettings::DisableVersionFlag + ); + assert_eq!( + "dontcollapseargsinusage".parse::().unwrap(), + AppSettings::DontCollapseArgsInUsage + ); + assert_eq!( + "dontdelimittrailingvalues".parse::().unwrap(), + AppSettings::DontDelimitTrailingValues + ); + assert_eq!( + "derivedisplayorder".parse::().unwrap(), + AppSettings::DeriveDisplayOrder + ); + assert_eq!( + "disablecoloredhelp".parse::().unwrap(), + AppSettings::DisableColoredHelp + ); + assert_eq!( + "propagateversion".parse::().unwrap(), + AppSettings::PropagateVersion + ); + assert_eq!( + "hidden".parse::().unwrap(), + AppSettings::Hidden + ); + assert_eq!( + "hidepossiblevalues".parse::().unwrap(), + AppSettings::HidePossibleValues + ); + assert_eq!( + "helpexpected".parse::().unwrap(), + AppSettings::HelpExpected + ); + assert_eq!( + "nobinaryname".parse::().unwrap(), + AppSettings::NoBinaryName + ); + assert_eq!( + "nextlinehelp".parse::().unwrap(), + AppSettings::NextLineHelp + ); + assert_eq!( + "subcommandsnegatereqs".parse::().unwrap(), + AppSettings::SubcommandsNegateReqs + ); + assert_eq!( + "subcommandrequired".parse::().unwrap(), + AppSettings::SubcommandRequired + ); + assert_eq!( + "subcommandrequiredelsehelp".parse::().unwrap(), + AppSettings::SubcommandRequiredElseHelp + ); + assert_eq!( + "uselongformatforhelpsubcommand" + .parse::() + .unwrap(), + AppSettings::UseLongFormatForHelpSubcommand + ); + assert_eq!( + "trailingvararg".parse::().unwrap(), + AppSettings::TrailingVarArg + ); + assert_eq!( + "waitonerror".parse::().unwrap(), + AppSettings::WaitOnError + ); + assert_eq!("built".parse::().unwrap(), AppSettings::Built); + assert_eq!( + "binnamebuilt".parse::().unwrap(), + AppSettings::BinNameBuilt + ); + assert_eq!( + "infersubcommands".parse::().unwrap(), + AppSettings::InferSubcommands + ); + assert!("hahahaha".parse::().is_err()); + } +} diff --git a/vendor/clap-3.2.20/src/builder/arg.rs b/vendor/clap-3.2.20/src/builder/arg.rs new file mode 100644 index 000000000..e9403d0b7 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/arg.rs @@ -0,0 +1,5494 @@ +#![allow(deprecated)] + +// Std +use std::{ + borrow::Cow, + cmp::{Ord, Ordering}, + error::Error, + ffi::OsStr, + fmt::{self, Display, Formatter}, + str, + sync::{Arc, Mutex}, +}; +#[cfg(feature = "env")] +use std::{env, ffi::OsString}; + +#[cfg(feature = "yaml")] +use yaml_rust::Yaml; + +// Internal +use crate::builder::usage_parser::UsageParser; +use crate::builder::ArgPredicate; +use crate::util::{Id, Key}; +use crate::ArgAction; +use crate::PossibleValue; +use crate::ValueHint; +use crate::INTERNAL_ERROR_MSG; +use crate::{ArgFlags, ArgSettings}; + +#[cfg(feature = "regex")] +use crate::builder::RegexRef; + +/// The abstract representation of a command line argument. Used to set all the options and +/// relationships that define a valid argument for the program. +/// +/// There are two methods for constructing [`Arg`]s, using the builder pattern and setting options +/// manually, or using a usage string which is far less verbose but has fewer options. You can also +/// use a combination of the two methods to achieve the best of both worlds. +/// +/// - [Basic API][crate::Arg#basic-api] +/// - [Value Handling][crate::Arg#value-handling] +/// - [Help][crate::Arg#help-1] +/// - [Advanced Argument Relations][crate::Arg#advanced-argument-relations] +/// - [Reflection][crate::Arg#reflection] +/// +/// # Examples +/// +/// ```rust +/// # use clap::{Arg, arg}; +/// // Using the traditional builder pattern and setting each option manually +/// let cfg = Arg::new("config") +/// .short('c') +/// .long("config") +/// .takes_value(true) +/// .value_name("FILE") +/// .help("Provides a config file to myprog"); +/// // Using a usage string (setting a similar argument to the one above) +/// let input = arg!(-i --input "Provides an input file to the program"); +/// ``` +#[allow(missing_debug_implementations)] +#[derive(Default, Clone)] +pub struct Arg<'help> { + pub(crate) id: Id, + pub(crate) provider: ArgProvider, + pub(crate) name: &'help str, + pub(crate) help: Option<&'help str>, + pub(crate) long_help: Option<&'help str>, + pub(crate) action: Option, + pub(crate) value_parser: Option, + pub(crate) blacklist: Vec, + pub(crate) settings: ArgFlags, + pub(crate) overrides: Vec, + pub(crate) groups: Vec, + pub(crate) requires: Vec<(ArgPredicate<'help>, Id)>, + pub(crate) r_ifs: Vec<(Id, &'help str)>, + pub(crate) r_ifs_all: Vec<(Id, &'help str)>, + pub(crate) r_unless: Vec, + pub(crate) r_unless_all: Vec, + pub(crate) short: Option, + pub(crate) long: Option<&'help str>, + pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible) + pub(crate) short_aliases: Vec<(char, bool)>, // (name, visible) + pub(crate) disp_ord: DisplayOrder, + pub(crate) possible_vals: Vec>, + pub(crate) val_names: Vec<&'help str>, + pub(crate) num_vals: Option, + pub(crate) max_occurs: Option, + pub(crate) max_vals: Option, + pub(crate) min_vals: Option, + pub(crate) validator: Option>>>, + pub(crate) validator_os: Option>>>, + pub(crate) val_delim: Option, + pub(crate) default_vals: Vec<&'help OsStr>, + pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate<'help>, Option<&'help OsStr>)>, + pub(crate) default_missing_vals: Vec<&'help OsStr>, + #[cfg(feature = "env")] + pub(crate) env: Option<(&'help OsStr, Option)>, + pub(crate) terminator: Option<&'help str>, + pub(crate) index: Option, + pub(crate) help_heading: Option>, + pub(crate) value_hint: Option, +} + +/// # Basic API +impl<'help> Arg<'help> { + /// Create a new [`Arg`] with a unique name. + /// + /// The name is used to check whether or not the argument was used at + /// runtime, get values, set relationships with other args, etc.. + /// + /// **NOTE:** In the case of arguments that take values (i.e. [`Arg::takes_value(true)`]) + /// and positional arguments (i.e. those without a preceding `-` or `--`) the name will also + /// be displayed when the user prints the usage/help information of the program. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("config") + /// # ; + /// ``` + /// [`Arg::takes_value(true)`]: Arg::takes_value() + pub fn new>(n: S) -> Self { + Arg::default().name(n) + } + + /// Set the identifier used for referencing this argument in the clap API. + /// + /// See [`Arg::new`] for more details. + #[must_use] + pub fn id>(mut self, n: S) -> Self { + let name = n.into(); + self.id = Id::from(&*name); + self.name = name; + self + } + + /// Deprecated, replaced with [`Arg::id`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Arg::id`") + )] + pub fn name>(self, n: S) -> Self { + self.id(n) + } + + /// Sets the short version of the argument without the preceding `-`. + /// + /// By default `V` and `h` are used by the auto-generated `version` and `help` arguments, + /// respectively. You may use the uppercase `V` or lowercase `h` for your own arguments, in + /// which case `clap` simply will not assign those to the auto-generated + /// `version` or `help` arguments. + /// + /// # Examples + /// + /// When calling `short`, use a single valid UTF-8 character which will allow using the + /// argument via a single hyphen (`-`) such as `-c`: + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("config") + /// .short('c') + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "-c", "file.toml" + /// ]); + /// + /// assert_eq!(m.get_one::("config").map(String::as_str), Some("file.toml")); + /// ``` + #[inline] + #[must_use] + pub fn short(mut self, s: char) -> Self { + assert!(s != '-', "short option name cannot be `-`"); + + self.short = Some(s); + self + } + + /// Sets the long version of the argument without the preceding `--`. + /// + /// By default `version` and `help` are used by the auto-generated `version` and `help` + /// arguments, respectively. You may use the word `version` or `help` for the long form of your + /// own arguments, in which case `clap` simply will not assign those to the auto-generated + /// `version` or `help` arguments. + /// + /// **NOTE:** Any leading `-` characters will be stripped + /// + /// # Examples + /// + /// To set `long` use a word containing valid UTF-8. If you supply a double leading + /// `--` such as `--config` they will be stripped. Hyphens in the middle of the word, however, + /// will *not* be stripped (i.e. `config-file` is allowed). + /// + /// Setting `long` allows using the argument via a double hyphen (`--`) such as `--config` + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--config", "file.toml" + /// ]); + /// + /// assert_eq!(m.get_one::("cfg").map(String::as_str), Some("file.toml")); + /// ``` + #[inline] + #[must_use] + pub fn long(mut self, l: &'help str) -> Self { + #[cfg(feature = "unstable-v4")] + { + self.long = Some(l); + } + #[cfg(not(feature = "unstable-v4"))] + { + self.long = Some(l.trim_start_matches(|c| c == '-')); + } + self + } + + /// Add an alias, which functions as a hidden long flag. + /// + /// This is more efficient, and easier than creating multiple hidden arguments as one only + /// needs to check for the existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .long("test") + /// .alias("alias") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--alias", "cool" + /// ]); + /// assert!(m.contains_id("test")); + /// assert_eq!(m.value_of("test"), Some("cool")); + /// ``` + #[must_use] + pub fn alias>(mut self, name: S) -> Self { + self.aliases.push((name.into(), false)); + self + } + + /// Add an alias, which functions as a hidden short flag. + /// + /// This is more efficient, and easier than creating multiple hidden arguments as one only + /// needs to check for the existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .short('t') + /// .short_alias('e') + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "-e", "cool" + /// ]); + /// assert!(m.contains_id("test")); + /// assert_eq!(m.value_of("test"), Some("cool")); + /// ``` + #[must_use] + pub fn short_alias(mut self, name: char) -> Self { + assert!(name != '-', "short alias name cannot be `-`"); + + self.short_aliases.push((name, false)); + self + } + + /// Add aliases, which function as hidden long flags. + /// + /// This is more efficient, and easier than creating multiple hidden subcommands as one only + /// needs to check for the existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .long("test") + /// .aliases(&["do-stuff", "do-tests", "tests"]) + /// .action(ArgAction::SetTrue) + /// .help("the file to add") + /// .required(false)) + /// .get_matches_from(vec![ + /// "prog", "--do-tests" + /// ]); + /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); + /// ``` + #[must_use] + pub fn aliases(mut self, names: &[&'help str]) -> Self { + self.aliases.extend(names.iter().map(|&x| (x, false))); + self + } + + /// Add aliases, which functions as a hidden short flag. + /// + /// This is more efficient, and easier than creating multiple hidden subcommands as one only + /// needs to check for the existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .short('t') + /// .short_aliases(&['e', 's']) + /// .action(ArgAction::SetTrue) + /// .help("the file to add") + /// .required(false)) + /// .get_matches_from(vec![ + /// "prog", "-s" + /// ]); + /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); + /// ``` + #[must_use] + pub fn short_aliases(mut self, names: &[char]) -> Self { + for s in names { + assert!(s != &'-', "short alias name cannot be `-`"); + self.short_aliases.push((*s, false)); + } + self + } + + /// Add an alias, which functions as a visible long flag. + /// + /// Like [`Arg::alias`], except that they are visible inside the help message. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .visible_alias("something-awesome") + /// .long("test") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--something-awesome", "coffee" + /// ]); + /// assert!(m.contains_id("test")); + /// assert_eq!(m.value_of("test"), Some("coffee")); + /// ``` + /// [`Command::alias`]: Arg::alias() + #[must_use] + pub fn visible_alias>(mut self, name: S) -> Self { + self.aliases.push((name.into(), true)); + self + } + + /// Add an alias, which functions as a visible short flag. + /// + /// Like [`Arg::short_alias`], except that they are visible inside the help message. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .long("test") + /// .visible_short_alias('t') + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "-t", "coffee" + /// ]); + /// assert!(m.contains_id("test")); + /// assert_eq!(m.value_of("test"), Some("coffee")); + /// ``` + #[must_use] + pub fn visible_short_alias(mut self, name: char) -> Self { + assert!(name != '-', "short alias name cannot be `-`"); + + self.short_aliases.push((name, true)); + self + } + + /// Add aliases, which function as visible long flags. + /// + /// Like [`Arg::aliases`], except that they are visible inside the help message. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .long("test") + /// .action(ArgAction::SetTrue) + /// .visible_aliases(&["something", "awesome", "cool"])) + /// .get_matches_from(vec![ + /// "prog", "--awesome" + /// ]); + /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); + /// ``` + /// [`Command::aliases`]: Arg::aliases() + #[must_use] + pub fn visible_aliases(mut self, names: &[&'help str]) -> Self { + self.aliases.extend(names.iter().map(|n| (*n, true))); + self + } + + /// Add aliases, which function as visible short flags. + /// + /// Like [`Arg::short_aliases`], except that they are visible inside the help message. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("prog") + /// .arg(Arg::new("test") + /// .long("test") + /// .action(ArgAction::SetTrue) + /// .visible_short_aliases(&['t', 'e'])) + /// .get_matches_from(vec![ + /// "prog", "-t" + /// ]); + /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); + /// ``` + #[must_use] + pub fn visible_short_aliases(mut self, names: &[char]) -> Self { + for n in names { + assert!(n != &'-', "short alias name cannot be `-`"); + self.short_aliases.push((*n, true)); + } + self + } + + /// Specifies the index of a positional argument **starting at** 1. + /// + /// **NOTE:** The index refers to position according to **other positional argument**. It does + /// not define position in the argument list as a whole. + /// + /// **NOTE:** You can optionally leave off the `index` method, and the index will be + /// assigned in order of evaluation. Utilizing the `index` method allows for setting + /// indexes out of order + /// + /// **NOTE:** This is only meant to be used for positional arguments and shouldn't to be used + /// with [`Arg::short`] or [`Arg::long`]. + /// + /// **NOTE:** When utilized with [`Arg::multiple_values(true)`], only the **last** positional argument + /// may be defined as multiple (i.e. with the highest index) + /// + /// # Panics + /// + /// [`Command`] will [`panic!`] if indexes are skipped (such as defining `index(1)` and `index(3)` + /// but not `index(2)`, or a positional argument is defined as multiple and is not the highest + /// index + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("config") + /// .index(1) + /// # ; + /// ``` + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("mode") + /// .index(1)) + /// .arg(Arg::new("debug") + /// .long("debug")) + /// .get_matches_from(vec![ + /// "prog", "--debug", "fast" + /// ]); + /// + /// assert!(m.contains_id("mode")); + /// assert_eq!(m.value_of("mode"), Some("fast")); // notice index(1) means "first positional" + /// // *not* first argument + /// ``` + /// [`Arg::short`]: Arg::short() + /// [`Arg::long`]: Arg::long() + /// [`Arg::multiple_values(true)`]: Arg::multiple_values() + /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html + /// [`Command`]: crate::Command + #[inline] + #[must_use] + pub fn index(mut self, idx: usize) -> Self { + self.index = Some(idx); + self + } + + /// This arg is the last, or final, positional argument (i.e. has the highest + /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args -- + /// last_arg`). + /// + /// Even, if no other arguments are left to parse, if the user omits the `--` syntax + /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also + /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with + /// the `--` syntax is otherwise not possible. + /// + /// **NOTE:** This will change the usage string to look like `$ prog [OPTIONS] [-- ]` if + /// `ARG` is marked as `.last(true)`. + /// + /// **NOTE:** This setting will imply [`crate::Command::dont_collapse_args_in_usage`] because failing + /// to set this can make the usage string very confusing. + /// + /// **NOTE**: This setting only applies to positional arguments, and has no effect on OPTIONS + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`] + /// + /// **CAUTION:** Using this setting *and* having child subcommands is not + /// recommended with the exception of *also* using + /// [`crate::Command::args_conflicts_with_subcommands`] + /// (or [`crate::Command::subcommand_negates_reqs`] if the argument marked `Last` is also + /// marked [`Arg::required`]) + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("args") + /// .takes_value(true) + /// .last(true) + /// # ; + /// ``` + /// + /// Setting `last` ensures the arg has the highest [index] of all positional args + /// and requires that the `--` syntax be used to access it early. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("first")) + /// .arg(Arg::new("second")) + /// .arg(Arg::new("third") + /// .takes_value(true) + /// .last(true)) + /// .try_get_matches_from(vec![ + /// "prog", "one", "--", "three" + /// ]); + /// + /// assert!(res.is_ok()); + /// let m = res.unwrap(); + /// assert_eq!(m.value_of("third"), Some("three")); + /// assert!(m.value_of("second").is_none()); + /// ``` + /// + /// Even if the positional argument marked `Last` is the only argument left to parse, + /// failing to use the `--` syntax results in an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("first")) + /// .arg(Arg::new("second")) + /// .arg(Arg::new("third") + /// .takes_value(true) + /// .last(true)) + /// .try_get_matches_from(vec![ + /// "prog", "one", "two", "three" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + /// [index]: Arg::index() + /// [`UnknownArgument`]: crate::ErrorKind::UnknownArgument + #[inline] + #[must_use] + pub fn last(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::Last) + } else { + self.unset_setting(ArgSettings::Last) + } + } + + /// Specifies that the argument must be present. + /// + /// Required by default means it is required, when no other conflicting rules or overrides have + /// been evaluated. Conflicting rules take precedence over being required. + /// + /// **Pro tip:** Flags (i.e. not positional, or arguments that take values) shouldn't be + /// required by default. This is because if a flag were to be required, it should simply be + /// implied. No additional information is required from user. Flags by their very nature are + /// simply boolean on/off switches. The only time a user *should* be required to use a flag + /// is if the operation is destructive in nature, and the user is essentially proving to you, + /// "Yes, I know what I'm doing." + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required(true) + /// # ; + /// ``` + /// + /// Setting required requires that the argument be used at runtime. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required(true) + /// .takes_value(true) + /// .long("config")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "file.conf", + /// ]); + /// + /// assert!(res.is_ok()); + /// ``` + /// + /// Setting required and then *not* supplying that argument at runtime is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required(true) + /// .takes_value(true) + /// .long("config")) + /// .try_get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + #[inline] + #[must_use] + pub fn required(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::Required) + } else { + self.unset_setting(ArgSettings::Required) + } + } + + /// Sets an argument that is required when this one is present + /// + /// i.e. when using this argument, the following argument *must* be present. + /// + /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .requires("input") + /// # ; + /// ``` + /// + /// Setting [`Arg::requires(name)`] requires that the argument be used at runtime if the + /// defining argument is used. If the defining argument isn't used, the other argument isn't + /// required + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires("input") + /// .long("config")) + /// .arg(Arg::new("input")) + /// .try_get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(res.is_ok()); // We didn't use cfg, so input wasn't required + /// ``` + /// + /// Setting [`Arg::requires(name)`] and *not* supplying that argument is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires("input") + /// .long("config")) + /// .arg(Arg::new("input")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "file.conf" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [`Arg::requires(name)`]: Arg::requires() + /// [Conflicting]: Arg::conflicts_with() + /// [override]: Arg::overrides_with() + #[must_use] + pub fn requires(mut self, arg_id: T) -> Self { + self.requires.push((ArgPredicate::IsPresent, arg_id.into())); + self + } + + /// This argument must be passed alone; it conflicts with all other arguments. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .exclusive(true) + /// # ; + /// ``` + /// + /// Setting an exclusive argument and having any other arguments present at runtime + /// is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("exclusive") + /// .takes_value(true) + /// .exclusive(true) + /// .long("exclusive")) + /// .arg(Arg::new("debug") + /// .long("debug")) + /// .arg(Arg::new("input")) + /// .try_get_matches_from(vec![ + /// "prog", "--exclusive", "file.conf", "file.txt" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict); + /// ``` + #[inline] + #[must_use] + pub fn exclusive(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::Exclusive) + } else { + self.unset_setting(ArgSettings::Exclusive) + } + } + + /// Specifies that an argument can be matched to all child [`Subcommand`]s. + /// + /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however + /// their values once a user uses them will be propagated back up to parents. In effect, this + /// means one should *define* all global arguments at the top level, however it doesn't matter + /// where the user *uses* the global argument. + /// + /// # Examples + /// + /// Assume an application with two subcommands, and you'd like to define a + /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't + /// want to clutter the source with three duplicate [`Arg`] definitions. + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("prog") + /// .arg(Arg::new("verb") + /// .long("verbose") + /// .short('v') + /// .action(ArgAction::SetTrue) + /// .global(true)) + /// .subcommand(Command::new("test")) + /// .subcommand(Command::new("do-stuff")) + /// .get_matches_from(vec![ + /// "prog", "do-stuff", "--verbose" + /// ]); + /// + /// assert_eq!(m.subcommand_name(), Some("do-stuff")); + /// let sub_m = m.subcommand_matches("do-stuff").unwrap(); + /// assert_eq!(*sub_m.get_one::("verb").expect("defaulted by clap"), true); + /// ``` + /// + /// [`Subcommand`]: crate::Subcommand + #[inline] + #[must_use] + pub fn global(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::Global) + } else { + self.unset_setting(ArgSettings::Global) + } + } + + /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::action` (Issue #3772)") + )] + pub fn multiple_occurrences(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::MultipleOccurrences) + } else { + self.unset_setting(ArgSettings::MultipleOccurrences) + } + } + + /// Deprecated, for flags this is replaced with `action(ArgAction::Count).value_parser(value_parser!(u8).range(..max))` + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "For flags, replaced with `action(ArgAction::Count).value_parser(value_parser!(u8).range(..max))`" + ) + )] + pub fn max_occurrences(mut self, qty: usize) -> Self { + self.max_occurs = Some(qty); + if qty > 1 { + self.multiple_occurrences(true) + } else { + self + } + } + + /// Check if the [`ArgSettings`] variant is currently set on the argument. + /// + /// [`ArgSettings`]: crate::ArgSettings + #[inline] + pub fn is_set(&self, s: ArgSettings) -> bool { + self.settings.is_set(s) + } + + /// Apply a setting to the argument. + /// + /// See [`ArgSettings`] for a full list of possibilities and examples. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Arg, ArgSettings}; + /// Arg::new("config") + /// .setting(ArgSettings::Required) + /// .setting(ArgSettings::TakesValue) + /// # ; + /// ``` + /// + /// ```no_run + /// # use clap::{Arg, ArgSettings}; + /// Arg::new("config") + /// .setting(ArgSettings::Required | ArgSettings::TakesValue) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn setting(mut self, setting: F) -> Self + where + F: Into, + { + self.settings.insert(setting.into()); + self + } + + /// Remove a setting from the argument. + /// + /// See [`ArgSettings`] for a full list of possibilities and examples. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Arg, ArgSettings}; + /// Arg::new("config") + /// .unset_setting(ArgSettings::Required) + /// .unset_setting(ArgSettings::TakesValue) + /// # ; + /// ``` + /// + /// ```no_run + /// # use clap::{Arg, ArgSettings}; + /// Arg::new("config") + /// .unset_setting(ArgSettings::Required | ArgSettings::TakesValue) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn unset_setting(mut self, setting: F) -> Self + where + F: Into, + { + self.settings.remove(setting.into()); + self + } +} + +/// # Value Handling +impl<'help> Arg<'help> { + /// Specifies that the argument takes a value at run time. + /// + /// **NOTE:** values for arguments may be specified in any of the following methods + /// + /// - Using a space such as `-o value` or `--option value` + /// - Using an equals and no space such as `-o=value` or `--option=value` + /// - Use a short and no space such as `-ovalue` + /// + /// **NOTE:** By default, args which allow [multiple values] are delimited by commas, meaning + /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to + /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`], + /// alternatively you can turn delimiting values **OFF** by using + /// [`Arg::use_value_delimiter(false)`][Arg::use_value_delimiter] + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("mode") + /// .long("mode") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--mode", "fast" + /// ]); + /// + /// assert!(m.contains_id("mode")); + /// assert_eq!(m.value_of("mode"), Some("fast")); + /// ``` + /// [`Arg::value_delimiter(char)`]: Arg::value_delimiter() + /// [multiple values]: Arg::multiple_values + #[inline] + #[must_use] + pub fn takes_value(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::TakesValue) + } else { + self.unset_setting(ArgSettings::TakesValue) + } + } + + /// Specify the behavior when parsing an argument + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::Set) + /// ); + /// + /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!(matches.occurrences_of("flag"), 0); + /// assert_eq!( + /// matches.get_many::("flag").unwrap_or_default().map(|v| v.as_str()).collect::>(), + /// vec!["value"] + /// ); + /// ``` + #[inline] + #[must_use] + pub fn action(mut self, action: ArgAction) -> Self { + self.action = Some(action); + self + } + + /// Specify the type of the argument. + /// + /// This allows parsing and validating a value before storing it into + /// [`ArgMatches`][crate::ArgMatches]. + /// + /// See also + /// - [`value_parser!`][crate::value_parser!] for auto-selecting a value parser for a given type + /// - [`BoolishValueParser`][crate::builder::BoolishValueParser], and [`FalseyValueParser`][crate::builder::FalseyValueParser] for alternative `bool` implementations + /// - [`NonEmptyStringValueParser`][crate::builder::NonEmptyStringValueParser] for basic validation for strings + /// - [`RangedI64ValueParser`][crate::builder::RangedI64ValueParser] and [`RangedU64ValueParser`][crate::builder::RangedU64ValueParser] for numeric ranges + /// - [`EnumValueParser`][crate::builder::EnumValueParser] and [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values + /// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation + /// + /// ```rust + /// let mut cmd = clap::Command::new("raw") + /// .arg( + /// clap::Arg::new("color") + /// .long("color") + /// .value_parser(["always", "auto", "never"]) + /// .default_value("auto") + /// ) + /// .arg( + /// clap::Arg::new("hostname") + /// .long("hostname") + /// .value_parser(clap::builder::NonEmptyStringValueParser::new()) + /// .takes_value(true) + /// .required(true) + /// ) + /// .arg( + /// clap::Arg::new("port") + /// .long("port") + /// .value_parser(clap::value_parser!(u16).range(3000..)) + /// .takes_value(true) + /// .required(true) + /// ); + /// + /// let m = cmd.try_get_matches_from_mut( + /// ["cmd", "--hostname", "rust-lang.org", "--port", "3001"] + /// ).unwrap(); + /// + /// let color: &String = m.get_one("color") + /// .expect("default"); + /// assert_eq!(color, "auto"); + /// + /// let hostname: &String = m.get_one("hostname") + /// .expect("required"); + /// assert_eq!(hostname, "rust-lang.org"); + /// + /// let port: u16 = *m.get_one("port") + /// .expect("required"); + /// assert_eq!(port, 3001); + /// ``` + pub fn value_parser(mut self, parser: impl Into) -> Self { + self.value_parser = Some(parser.into()); + self + } + + /// Specifies that the argument may have an unknown number of values + /// + /// Without any other settings, this argument may appear only *once*. + /// + /// For example, `--opt val1 val2` is allowed, but `--opt val1 val2 --opt val3` is not. + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`]. + /// + /// **WARNING:** + /// + /// Setting `multiple_values` for an argument that takes a value, but with no other details can + /// be dangerous in some circumstances. Because multiple values are allowed, + /// `--option val1 val2 val3` is perfectly valid. Be careful when designing a CLI where + /// positional arguments are *also* expected as `clap` will continue parsing *values* until one + /// of the following happens: + /// + /// - It reaches the [maximum number of values] + /// - It reaches a [specific number of values] + /// - It finds another flag or option (i.e. something that starts with a `-`) + /// - It reaches a [value terminator][Arg::value_terminator] is reached + /// + /// Alternatively, [require a delimiter between values][Arg::require_delimiter]. + /// + /// **WARNING:** + /// + /// When using args with `multiple_values` and [`subcommands`], one needs to consider the + /// possibility of an argument value being the same as a valid subcommand. By default `clap` will + /// parse the argument in question as a value *only if* a value is possible at that moment. + /// Otherwise it will be parsed as a subcommand. In effect, this means using `multiple_values` with no + /// additional parameters and a value that coincides with a subcommand name, the subcommand + /// cannot be called unless another argument is passed between them. + /// + /// As an example, consider a CLI with an option `--ui-paths=...` and subcommand `signer` + /// + /// The following would be parsed as values to `--ui-paths`. + /// + /// ```text + /// $ program --ui-paths path1 path2 signer + /// ``` + /// + /// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values + /// until another argument is reached and it knows `--ui-paths` is done parsing. + /// + /// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding + /// [`Arg::number_of_values(1)`] or using *only* [`ArgAction::Append`]. The following are all + /// valid, and `signer` is parsed as a subcommand in the first case, but a value in the second + /// case. + /// + /// ```text + /// $ program --ui-paths path1 signer + /// $ program --ui-paths path1 --ui-paths signer signer + /// ``` + /// + /// # Examples + /// + /// An example with options + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .multiple_values(true) + /// .short('F')) + /// .get_matches_from(vec![ + /// "prog", "-F", "file1", "file2", "file3" + /// ]); + /// + /// assert!(m.contains_id("file")); + /// let files: Vec<_> = m.values_of("file").unwrap().collect(); + /// assert_eq!(files, ["file1", "file2", "file3"]); + /// ``` + /// + /// Although `multiple_values` has been specified, we cannot use the argument more than once. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .multiple_values(true) + /// .short('F')) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1", "-F", "file2", "-F", "file3" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage) + /// ``` + /// + /// A common mistake is to define an option which allows multiple values, and a positional + /// argument. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .multiple_values(true) + /// .short('F')) + /// .arg(Arg::new("word")) + /// .get_matches_from(vec![ + /// "prog", "-F", "file1", "file2", "file3", "word" + /// ]); + /// + /// assert!(m.contains_id("file")); + /// let files: Vec<_> = m.values_of("file").unwrap().collect(); + /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?! + /// assert!(!m.contains_id("word")); // but we clearly used word! + /// ``` + /// + /// The problem is `clap` doesn't know when to stop parsing values for "files". This is further + /// compounded by if we'd said `word -F file1 file2` it would have worked fine, so it would + /// appear to only fail sometimes...not good! + /// + /// A solution for the example above is to limit how many values with a [maximum], or [specific] + /// number, or to say [`ArgAction::Append`] is ok, but multiple values is not. + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .action(ArgAction::Append) + /// .short('F')) + /// .arg(Arg::new("word")) + /// .get_matches_from(vec![ + /// "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word" + /// ]); + /// + /// assert!(m.contains_id("file")); + /// let files: Vec<_> = m.values_of("file").unwrap().collect(); + /// assert_eq!(files, ["file1", "file2", "file3"]); + /// assert!(m.contains_id("word")); + /// assert_eq!(m.value_of("word"), Some("word")); + /// ``` + /// + /// As a final example, let's fix the above error and get a pretty message to the user :) + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind, ArgAction}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .action(ArgAction::Append) + /// .short('F')) + /// .arg(Arg::new("word")) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1", "file2", "file3", "word" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + /// + /// [`subcommands`]: crate::Command::subcommand() + /// [`Arg::number_of_values(1)`]: Arg::number_of_values() + /// [maximum number of values]: Arg::max_values() + /// [specific number of values]: Arg::number_of_values() + /// [maximum]: Arg::max_values() + /// [specific]: Arg::number_of_values() + #[inline] + #[must_use] + pub fn multiple_values(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::MultipleValues) + } else { + self.unset_setting(ArgSettings::MultipleValues) + } + } + + /// The number of values allowed for this argument. + /// + /// For example, if you had a + /// `-f ` argument where you wanted exactly 3 'files' you would set + /// `.number_of_values(3)`, and this argument wouldn't be satisfied unless the user provided + /// 3 and only 3 values. + /// + /// **NOTE:** Does *not* require [`Arg::multiple_occurrences(true)`] to be set. Setting + /// [`Arg::multiple_occurrences(true)`] would allow `-f -f ` where + /// as *not* setting it would only allow one occurrence of this argument. + /// + /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] and [`Arg::multiple_values(true)`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("file") + /// .short('f') + /// .number_of_values(3); + /// ``` + /// + /// Not supplying the correct number of values is an error + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .number_of_values(2) + /// .short('F')) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::WrongNumberOfValues); + /// ``` + /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences() + #[inline] + #[must_use] + pub fn number_of_values(mut self, qty: usize) -> Self { + self.num_vals = Some(qty); + self.takes_value(true).multiple_values(true) + } + + /// The *maximum* number of values are for this argument. + /// + /// For example, if you had a + /// `-f ` argument where you wanted up to 3 'files' you would set `.max_values(3)`, and + /// this argument would be satisfied if the user provided, 1, 2, or 3 values. + /// + /// **NOTE:** This does *not* implicitly set [`Arg::multiple_occurrences(true)`]. This is because + /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single + /// occurrence with multiple values. For positional arguments this **does** set + /// [`Arg::multiple_occurrences(true)`] because there is no way to determine the difference between multiple + /// occurrences and multiple values. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("file") + /// .short('f') + /// .max_values(3); + /// ``` + /// + /// Supplying less than the maximum number of values is allowed + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .max_values(3) + /// .short('F')) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1", "file2" + /// ]); + /// + /// assert!(res.is_ok()); + /// let m = res.unwrap(); + /// let files: Vec<_> = m.values_of("file").unwrap().collect(); + /// assert_eq!(files, ["file1", "file2"]); + /// ``` + /// + /// Supplying more than the maximum number of values is an error + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .max_values(2) + /// .short('F')) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1", "file2", "file3" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences() + #[inline] + #[must_use] + pub fn max_values(mut self, qty: usize) -> Self { + self.max_vals = Some(qty); + self.takes_value(true).multiple_values(true) + } + + /// The *minimum* number of values for this argument. + /// + /// For example, if you had a + /// `-f ` argument where you wanted at least 2 'files' you would set + /// `.min_values(2)`, and this argument would be satisfied if the user provided, 2 or more + /// values. + /// + /// **NOTE:** This does not implicitly set [`Arg::multiple_occurrences(true)`]. This is because + /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single + /// occurrence with multiple values. For positional arguments this **does** set + /// [`Arg::multiple_occurrences(true)`] because there is no way to determine the difference between multiple + /// occurrences and multiple values. + /// + /// **NOTE:** Passing a non-zero value is not the same as specifying [`Arg::required(true)`]. + /// This is due to min and max validation only being performed for present arguments, + /// marking them as required will thus perform validation and a min value of 1 + /// is unnecessary, ignored if not required. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("file") + /// .short('f') + /// .min_values(3); + /// ``` + /// + /// Supplying more than the minimum number of values is allowed + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .min_values(2) + /// .short('F')) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1", "file2", "file3" + /// ]); + /// + /// assert!(res.is_ok()); + /// let m = res.unwrap(); + /// let files: Vec<_> = m.values_of("file").unwrap().collect(); + /// assert_eq!(files, ["file1", "file2", "file3"]); + /// ``` + /// + /// Supplying less than the minimum number of values is an error + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("file") + /// .takes_value(true) + /// .min_values(2) + /// .short('F')) + /// .try_get_matches_from(vec![ + /// "prog", "-F", "file1" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::TooFewValues); + /// ``` + /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences() + /// [`Arg::required(true)`]: Arg::required() + #[inline] + #[must_use] + pub fn min_values(mut self, qty: usize) -> Self { + self.min_vals = Some(qty); + self.takes_value(true).multiple_values(true) + } + + /// Placeholder for the argument's value in the help message / usage. + /// + /// This name is cosmetic only; the name is **not** used to access arguments. + /// This setting can be very helpful when describing the type of input the user should be + /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to + /// use all capital letters for the value name. + /// + /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("cfg") + /// .long("config") + /// .value_name("FILE") + /// # ; + /// ``` + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("config") + /// .long("config") + /// .value_name("FILE") + /// .help("Some help text")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// Running the above program produces the following output + /// + /// ```text + /// valnames + /// + /// USAGE: + /// valnames [OPTIONS] + /// + /// OPTIONS: + /// --config Some help text + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + /// [option]: Arg::takes_value() + /// [positional]: Arg::index() + /// [`Arg::takes_value(true)`]: Arg::takes_value() + #[inline] + #[must_use] + pub fn value_name(self, name: &'help str) -> Self { + self.value_names(&[name]) + } + + /// Placeholders for the argument's values in the help message / usage. + /// + /// These names are cosmetic only, used for help and usage strings only. The names are **not** + /// used to access arguments. The values of the arguments are accessed in numeric order (i.e. + /// if you specify two names `one` and `two` `one` will be the first matched value, `two` will + /// be the second). + /// + /// This setting can be very helpful when describing the type of input the user should be + /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to + /// use all capital letters for the value name. + /// + /// **Pro Tip:** It may help to use [`Arg::next_line_help(true)`] if there are long, or + /// multiple value names in order to not throw off the help text alignment of all options. + /// + /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] and [`Arg::multiple_values(true)`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("speed") + /// .short('s') + /// .value_names(&["fast", "slow"]); + /// ``` + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("io") + /// .long("io-files") + /// .value_names(&["INFILE", "OUTFILE"])) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// Running the above program produces the following output + /// + /// ```text + /// valnames + /// + /// USAGE: + /// valnames [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// --io-files Some help text + /// -V, --version Print version information + /// ``` + /// [`Arg::next_line_help(true)`]: Arg::next_line_help() + /// [`Arg::number_of_values`]: Arg::number_of_values() + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`Arg::multiple_values(true)`]: Arg::multiple_values() + #[must_use] + pub fn value_names(mut self, names: &[&'help str]) -> Self { + self.val_names = names.to_vec(); + self.takes_value(true) + } + + /// Provide the shell a hint about how to complete this argument. + /// + /// See [`ValueHint`][crate::ValueHint] for more information. + /// + /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]. + /// + /// For example, to take a username as argument: + /// + /// ``` + /// # use clap::{Arg, ValueHint}; + /// Arg::new("user") + /// .short('u') + /// .long("user") + /// .value_hint(ValueHint::Username); + /// ``` + /// + /// To take a full command line and its arguments (for example, when writing a command wrapper): + /// + /// ``` + /// # use clap::{Command, Arg, ValueHint}; + /// Command::new("prog") + /// .trailing_var_arg(true) + /// .arg( + /// Arg::new("command") + /// .takes_value(true) + /// .multiple_values(true) + /// .value_hint(ValueHint::CommandWithArguments) + /// ); + /// ``` + #[must_use] + pub fn value_hint(mut self, value_hint: ValueHint) -> Self { + self.value_hint = Some(value_hint); + self.takes_value(true) + } + + /// Deprecated, replaced with [`Arg::value_parser(...)`] + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::value_parser(...)`") + )] + pub fn validator(mut self, mut f: F) -> Self + where + F: FnMut(&str) -> Result + Send + 'help, + E: Into>, + { + self.validator = Some(Arc::new(Mutex::new(move |s: &str| { + f(s).map(|_| ()).map_err(|e| e.into()) + }))); + self + } + + /// Deprecated, replaced with [`Arg::value_parser(...)`] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::value_parser(...)`") + )] + pub fn validator_os(mut self, mut f: F) -> Self + where + F: FnMut(&OsStr) -> Result + Send + 'help, + E: Into>, + { + self.validator_os = Some(Arc::new(Mutex::new(move |s: &OsStr| { + f(s).map(|_| ()).map_err(|e| e.into()) + }))); + self + } + + /// Deprecated in [Issue #3743](https://github.com/clap-rs/clap/issues/3743), replaced with [`Arg::value_parser(...)`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Deprecated in Issue #3743; eplaced with `Arg::value_parser(...)`" + ) + )] + #[cfg(feature = "regex")] + #[must_use] + pub fn validator_regex( + self, + regex: impl Into>, + err_message: &'help str, + ) -> Self { + let regex = regex.into(); + self.validator(move |s: &str| { + if regex.is_match(s) { + Ok(()) + } else { + Err(err_message) + } + }) + } + + /// Deprecated, replaced with [`Arg::value_parser(PossibleValuesParser::new(...))`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `Arg::value_parser(PossibleValuesParser::new(...)).takes_value(true)`" + ) + )] + #[must_use] + pub fn possible_value(mut self, value: T) -> Self + where + T: Into>, + { + self.possible_vals.push(value.into()); + self.takes_value(true) + } + + /// Deprecated, replaced with [`Arg::value_parser(PossibleValuesParser::new(...))`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `Arg::value_parser(PossibleValuesParser::new(...)).takes_value(true)`" + ) + )] + #[must_use] + pub fn possible_values(mut self, values: I) -> Self + where + I: IntoIterator, + T: Into>, + { + self.possible_vals + .extend(values.into_iter().map(|value| value.into())); + self.takes_value(true) + } + + /// Match values against [`Arg::possible_values`] without matching case. + /// + /// When other arguments are conditionally required based on the + /// value of a case-insensitive argument, the equality check done + /// by [`Arg::required_if_eq`], [`Arg::required_if_eq_any`], or + /// [`Arg::required_if_eq_all`] is case-insensitive. + /// + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`] + /// + /// **NOTE:** To do unicode case folding, enable the `unicode` feature flag. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("pv") + /// .arg(Arg::new("option") + /// .long("option") + /// .takes_value(true) + /// .ignore_case(true) + /// .value_parser(["test123"])) + /// .get_matches_from(vec![ + /// "pv", "--option", "TeSt123", + /// ]); + /// + /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123")); + /// ``` + /// + /// This setting also works when multiple values can be defined: + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("pv") + /// .arg(Arg::new("option") + /// .short('o') + /// .long("option") + /// .takes_value(true) + /// .ignore_case(true) + /// .multiple_values(true) + /// .value_parser(["test123", "test321"])) + /// .get_matches_from(vec![ + /// "pv", "--option", "TeSt123", "teST123", "tESt321" + /// ]); + /// + /// let matched_vals = m.values_of("option").unwrap().collect::>(); + /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]); + /// ``` + #[inline] + #[must_use] + pub fn ignore_case(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::IgnoreCase) + } else { + self.unset_setting(ArgSettings::IgnoreCase) + } + } + + /// Allows values which start with a leading hyphen (`-`) + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`] + /// + /// **WARNING**: Take caution when using this setting combined with + /// [`Arg::multiple_values`], as this becomes ambiguous `$ prog --arg -- -- val`. All + /// three `--, --, val` will be values when the user may have thought the second `--` would + /// constitute the normal, "Only positional args follow" idiom. To fix this, consider using + /// [`Arg::multiple_occurrences`] which only allows a single value at a time. + /// + /// **WARNING**: When building your CLIs, consider the effects of allowing leading hyphens and + /// the user passing in a value that matches a valid short. For example, `prog -opt -F` where + /// `-F` is supposed to be a value, yet `-F` is *also* a valid short for another arg. + /// Care should be taken when designing these args. This is compounded by the ability to "stack" + /// short args. I.e. if `-val` is supposed to be a value, but `-v`, `-a`, and `-l` are all valid + /// shorts. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("pat") + /// .takes_value(true) + /// .allow_hyphen_values(true) + /// .long("pattern")) + /// .get_matches_from(vec![ + /// "prog", "--pattern", "-file" + /// ]); + /// + /// assert_eq!(m.value_of("pat"), Some("-file")); + /// ``` + /// + /// Not setting `Arg::allow_hyphen_values(true)` and supplying a value which starts with a + /// hyphen is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("pat") + /// .takes_value(true) + /// .long("pattern")) + /// .try_get_matches_from(vec![ + /// "prog", "--pattern", "-file" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + /// [`Arg::number_of_values(1)`]: Arg::number_of_values() + #[inline] + #[must_use] + pub fn allow_hyphen_values(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::AllowHyphenValues) + } else { + self.unset_setting(ArgSettings::AllowHyphenValues) + } + } + + /// Deprecated, replaced with [`Arg::value_parser(...)`] with either [`ValueParser::os_string()`][crate::builder::ValueParser::os_string] + /// or [`ValueParser::path_buf()`][crate::builder::ValueParser::path_buf] + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `Arg::value_parser(...)` with either `ValueParser::os_string()` or `ValueParser::path_buf()`" + ) + )] + pub fn allow_invalid_utf8(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::AllowInvalidUtf8) + } else { + self.unset_setting(ArgSettings::AllowInvalidUtf8) + } + } + + /// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`] + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`" + ) + )] + pub fn forbid_empty_values(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::ForbidEmptyValues) + } else { + self.unset_setting(ArgSettings::ForbidEmptyValues) + } + } + + /// Requires that options use the `--option=val` syntax + /// + /// i.e. an equals between the option and associated value. + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`] + /// + /// # Examples + /// + /// Setting `require_equals` requires that the option have an equals sign between + /// it and the associated value. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .require_equals(true) + /// .long("config")) + /// .try_get_matches_from(vec![ + /// "prog", "--config=file.conf" + /// ]); + /// + /// assert!(res.is_ok()); + /// ``` + /// + /// Setting `require_equals` and *not* supplying the equals will cause an + /// error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .require_equals(true) + /// .long("config")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "file.conf" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals); + /// ``` + #[inline] + #[must_use] + pub fn require_equals(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::RequireEquals) + } else { + self.unset_setting(ArgSettings::RequireEquals) + } + } + + /// Specifies that an argument should allow grouping of multiple values via a + /// delimiter. + /// + /// i.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`, + /// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the + /// value delimiter for all arguments that accept values (options and positional arguments) + /// + /// **NOTE:** When this setting is used, it will default [`Arg::value_delimiter`] + /// to the comma `,`. + /// + /// **NOTE:** Implicitly sets [`Arg::takes_value`] + /// + /// # Examples + /// + /// The following example shows the default behavior. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let delims = Command::new("prog") + /// .arg(Arg::new("option") + /// .long("option") + /// .use_value_delimiter(true) + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--option=val1,val2,val3", + /// ]); + /// + /// assert!(delims.contains_id("option")); + /// assert_eq!(delims.values_of("option").unwrap().collect::>(), ["val1", "val2", "val3"]); + /// ``` + /// The next example shows the difference when turning delimiters off. This is the default + /// behavior + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let nodelims = Command::new("prog") + /// .arg(Arg::new("option") + /// .long("option") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--option=val1,val2,val3", + /// ]); + /// + /// assert!(nodelims.contains_id("option")); + /// assert_eq!(nodelims.value_of("option").unwrap(), "val1,val2,val3"); + /// ``` + /// [`Arg::value_delimiter`]: Arg::value_delimiter() + #[inline] + #[must_use] + pub fn use_value_delimiter(mut self, yes: bool) -> Self { + if yes { + if self.val_delim.is_none() { + self.val_delim = Some(','); + } + self.takes_value(true) + .setting(ArgSettings::UseValueDelimiter) + } else { + self.val_delim = None; + self.unset_setting(ArgSettings::UseValueDelimiter) + } + } + + /// Deprecated, replaced with [`Arg::use_value_delimiter`] + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Arg::use_value_delimiter`") + )] + pub fn use_delimiter(self, yes: bool) -> Self { + self.use_value_delimiter(yes) + } + + /// Separator between the arguments values, defaults to `,` (comma). + /// + /// **NOTE:** implicitly sets [`Arg::use_value_delimiter(true)`] + /// + /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("config") + /// .short('c') + /// .long("config") + /// .value_delimiter(';')) + /// .get_matches_from(vec![ + /// "prog", "--config=val1;val2;val3" + /// ]); + /// + /// assert_eq!(m.values_of("config").unwrap().collect::>(), ["val1", "val2", "val3"]) + /// ``` + /// [`Arg::use_value_delimiter(true)`]: Arg::use_value_delimiter() + /// [`Arg::takes_value(true)`]: Arg::takes_value() + #[inline] + #[must_use] + pub fn value_delimiter(mut self, d: char) -> Self { + self.val_delim = Some(d); + self.takes_value(true).use_value_delimiter(true) + } + + /// Specifies that *multiple values* may only be set using the delimiter. + /// + /// This means if an option is encountered, and no delimiter is found, it is assumed that no + /// additional values for that option follow. This is unlike the default, where it is generally + /// assumed that more values will follow regardless of whether or not a delimiter is used. + /// + /// **NOTE:** The default is `false`. + /// + /// **NOTE:** Setting this requires [`Arg::use_value_delimiter`] and + /// [`Arg::takes_value`] + /// + /// **NOTE:** It's a good idea to inform the user that use of a delimiter is required, either + /// through help text or other means. + /// + /// # Examples + /// + /// These examples demonstrate what happens when `require_delimiter(true)` is used. Notice + /// everything works in this first example, as we use a delimiter, as expected. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let delims = Command::new("prog") + /// .arg(Arg::new("opt") + /// .short('o') + /// .takes_value(true) + /// .use_value_delimiter(true) + /// .require_delimiter(true) + /// .multiple_values(true)) + /// .get_matches_from(vec![ + /// "prog", "-o", "val1,val2,val3", + /// ]); + /// + /// assert!(delims.contains_id("opt")); + /// assert_eq!(delims.values_of("opt").unwrap().collect::>(), ["val1", "val2", "val3"]); + /// ``` + /// + /// In this next example, we will *not* use a delimiter. Notice it's now an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("opt") + /// .short('o') + /// .takes_value(true) + /// .use_value_delimiter(true) + /// .require_delimiter(true)) + /// .try_get_matches_from(vec![ + /// "prog", "-o", "val1", "val2", "val3", + /// ]); + /// + /// assert!(res.is_err()); + /// let err = res.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::UnknownArgument); + /// ``` + /// + /// What's happening is `-o` is getting `val1`, and because delimiters are required yet none + /// were present, it stops parsing `-o`. At this point it reaches `val2` and because no + /// positional arguments have been defined, it's an error of an unexpected argument. + /// + /// In this final example, we contrast the above with `clap`'s default behavior where the above + /// is *not* an error. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let delims = Command::new("prog") + /// .arg(Arg::new("opt") + /// .short('o') + /// .takes_value(true) + /// .multiple_values(true)) + /// .get_matches_from(vec![ + /// "prog", "-o", "val1", "val2", "val3", + /// ]); + /// + /// assert!(delims.contains_id("opt")); + /// assert_eq!(delims.values_of("opt").unwrap().collect::>(), ["val1", "val2", "val3"]); + /// ``` + #[inline] + #[must_use] + pub fn require_value_delimiter(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::RequireDelimiter) + } else { + self.unset_setting(ArgSettings::RequireDelimiter) + } + } + + /// Deprecated, replaced with [`Arg::require_value_delimiter`] + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Arg::require_value_delimiter`") + )] + pub fn require_delimiter(self, yes: bool) -> Self { + self.require_value_delimiter(yes) + } + + /// Sentinel to **stop** parsing multiple values of a give argument. + /// + /// By default when + /// one sets [`multiple_values(true)`] on an argument, clap will continue parsing values for that + /// argument until it reaches another valid argument, or one of the other more specific settings + /// for multiple values is used (such as [`min_values`], [`max_values`] or + /// [`number_of_values`]). + /// + /// **NOTE:** This setting only applies to [options] and [positional arguments] + /// + /// **NOTE:** When the terminator is passed in on the command line, it is **not** stored as one + /// of the values + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("vals") + /// .takes_value(true) + /// .multiple_values(true) + /// .value_terminator(";") + /// # ; + /// ``` + /// + /// The following example uses two arguments, a sequence of commands, and the location in which + /// to perform them + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cmds") + /// .takes_value(true) + /// .multiple_values(true) + /// .allow_hyphen_values(true) + /// .value_terminator(";")) + /// .arg(Arg::new("location")) + /// .get_matches_from(vec![ + /// "prog", "find", "-type", "f", "-name", "special", ";", "/home/clap" + /// ]); + /// let cmds: Vec<_> = m.values_of("cmds").unwrap().collect(); + /// assert_eq!(&cmds, &["find", "-type", "f", "-name", "special"]); + /// assert_eq!(m.value_of("location"), Some("/home/clap")); + /// ``` + /// [options]: Arg::takes_value() + /// [positional arguments]: Arg::index() + /// [`multiple_values(true)`]: Arg::multiple_values() + /// [`min_values`]: Arg::min_values() + /// [`number_of_values`]: Arg::number_of_values() + /// [`max_values`]: Arg::max_values() + #[inline] + #[must_use] + pub fn value_terminator(mut self, term: &'help str) -> Self { + self.terminator = Some(term); + self.takes_value(true) + } + + /// Consume all following arguments. + /// + /// Do not be parse them individually, but rather pass them in entirety. + /// + /// It is worth noting that setting this requires all values to come after a `--` to indicate + /// they should all be captured. For example: + /// + /// ```text + /// --foo something -- -v -v -v -b -b -b --baz -q -u -x + /// ``` + /// + /// Will result in everything after `--` to be considered one raw argument. This behavior + /// may not be exactly what you are expecting and using [`crate::Command::trailing_var_arg`] + /// may be more appropriate. + /// + /// **NOTE:** Implicitly sets [`Arg::takes_value(true)`] [`Arg::multiple_values(true)`], + /// [`Arg::allow_hyphen_values(true)`], and [`Arg::last(true)`] when set to `true`. + /// + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`Arg::multiple_values(true)`]: Arg::multiple_values() + /// [`Arg::allow_hyphen_values(true)`]: Arg::allow_hyphen_values() + /// [`Arg::last(true)`]: Arg::last() + #[inline] + #[must_use] + pub fn raw(self, yes: bool) -> Self { + self.takes_value(yes) + .multiple_values(yes) + .allow_hyphen_values(yes) + .last(yes) + } + + /// Value for the argument when not present. + /// + /// **NOTE:** If the user *does not* use this argument at runtime, [`ArgMatches::occurrences_of`] + /// will return `0` even though the [`ArgMatches::value_of`] will return the default specified. + /// + /// **NOTE:** If the user *does not* use this argument at runtime [`ArgMatches::contains_id`] will + /// still return `true`. If you wish to determine whether the argument was used at runtime or + /// not, consider [`ArgMatches::value_source`][crate::ArgMatches::value_source]. + /// + /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value_if`] but slightly + /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg + /// at runtime. `Arg::default_value_if` however only takes effect when the user has not provided + /// a value at runtime **and** these other conditions are met as well. If you have set + /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide this arg + /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value` + /// will be applied. + /// + /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`]. + /// + /// # Examples + /// + /// First we use the default value without providing any value at runtime. + /// + /// ```rust + /// # use clap::{Command, Arg, ValueSource}; + /// let m = Command::new("prog") + /// .arg(Arg::new("opt") + /// .long("myopt") + /// .default_value("myval")) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert_eq!(m.value_of("opt"), Some("myval")); + /// assert!(m.contains_id("opt")); + /// assert_eq!(m.value_source("opt"), Some(ValueSource::DefaultValue)); + /// ``` + /// + /// Next we provide a value at runtime to override the default. + /// + /// ```rust + /// # use clap::{Command, Arg, ValueSource}; + /// let m = Command::new("prog") + /// .arg(Arg::new("opt") + /// .long("myopt") + /// .default_value("myval")) + /// .get_matches_from(vec![ + /// "prog", "--myopt=non_default" + /// ]); + /// + /// assert_eq!(m.value_of("opt"), Some("non_default")); + /// assert!(m.contains_id("opt")); + /// assert_eq!(m.value_source("opt"), Some(ValueSource::CommandLine)); + /// ``` + /// [`ArgMatches::occurrences_of`]: crate::ArgMatches::occurrences_of() + /// [`ArgMatches::value_of`]: crate::ArgMatches::value_of() + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`ArgMatches::contains_id`]: crate::ArgMatches::contains_id() + /// [`Arg::default_value_if`]: Arg::default_value_if() + #[inline] + #[must_use] + pub fn default_value(self, val: &'help str) -> Self { + self.default_values_os(&[OsStr::new(val)]) + } + + /// Value for the argument when not present. + /// + /// See [`Arg::default_value`]. + /// + /// [`Arg::default_value`]: Arg::default_value() + /// [`OsStr`]: std::ffi::OsStr + #[inline] + #[must_use] + pub fn default_value_os(self, val: &'help OsStr) -> Self { + self.default_values_os(&[val]) + } + + /// Value for the argument when not present. + /// + /// See [`Arg::default_value`]. + /// + /// [`Arg::default_value`]: Arg::default_value() + #[inline] + #[must_use] + pub fn default_values(self, vals: &[&'help str]) -> Self { + let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect(); + self.default_values_os(&vals_vec[..]) + } + + /// Value for the argument when not present. + /// + /// See [`Arg::default_values`]. + /// + /// [`Arg::default_values`]: Arg::default_values() + /// [`OsStr`]: std::ffi::OsStr + #[inline] + #[must_use] + pub fn default_values_os(mut self, vals: &[&'help OsStr]) -> Self { + self.default_vals = vals.to_vec(); + self.takes_value(true) + } + + /// Value for the argument when the flag is present but no value is specified. + /// + /// This configuration option is often used to give the user a shortcut and allow them to + /// efficiently specify an option argument without requiring an explicitly value. The `--color` + /// argument is a common example. By, supplying an default, such as `default_missing_value("always")`, + /// the user can quickly just add `--color` to the command line to produce the desired color output. + /// + /// **NOTE:** using this configuration option requires the use of the `.min_values(0)` and the + /// `.require_equals(true)` configuration option. These are required in order to unambiguously + /// determine what, if any, value was supplied for the argument. + /// + /// # Examples + /// + /// For POSIX style `--color`: + /// ```rust + /// # use clap::{Command, Arg, ValueSource}; + /// fn cli() -> Command<'static> { + /// Command::new("prog") + /// .arg(Arg::new("color").long("color") + /// .value_name("WHEN") + /// .value_parser(["always", "auto", "never"]) + /// .default_value("auto") + /// .min_values(0) + /// .require_equals(true) + /// .default_missing_value("always") + /// .help("Specify WHEN to colorize output.") + /// ) + /// } + /// + /// // first, we'll provide no arguments + /// let m = cli().get_matches_from(vec![ + /// "prog" + /// ]); + /// assert_eq!(m.value_of("color"), Some("auto")); + /// assert_eq!(m.value_source("color"), Some(ValueSource::DefaultValue)); + /// + /// // next, we'll provide a runtime value to override the default (as usually done). + /// let m = cli().get_matches_from(vec![ + /// "prog", "--color=never" + /// ]); + /// assert_eq!(m.value_of("color"), Some("never")); + /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine)); + /// + /// // finally, we will use the shortcut and only provide the argument without a value. + /// let m = cli().get_matches_from(vec![ + /// "prog", "--color" + /// ]); + /// assert_eq!(m.value_of("color"), Some("always")); + /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine)); + /// ``` + /// + /// For bool literals: + /// ```rust + /// # use clap::{Command, Arg, ValueSource, value_parser}; + /// fn cli() -> Command<'static> { + /// Command::new("prog") + /// .arg(Arg::new("create").long("create") + /// .value_name("BOOL") + /// .value_parser(value_parser!(bool)) + /// .min_values(0) + /// .require_equals(true) + /// .default_missing_value("true") + /// ) + /// } + /// + /// // first, we'll provide no arguments + /// let m = cli().get_matches_from(vec![ + /// "prog" + /// ]); + /// assert_eq!(m.get_one::("create").copied(), None); + /// + /// // next, we'll provide a runtime value to override the default (as usually done). + /// let m = cli().get_matches_from(vec![ + /// "prog", "--create=false" + /// ]); + /// assert_eq!(m.get_one::("create").copied(), Some(false)); + /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine)); + /// + /// // finally, we will use the shortcut and only provide the argument without a value. + /// let m = cli().get_matches_from(vec![ + /// "prog", "--create" + /// ]); + /// assert_eq!(m.get_one::("create").copied(), Some(true)); + /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine)); + /// ``` + /// + /// [`ArgMatches::value_of`]: ArgMatches::value_of() + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`Arg::default_value`]: Arg::default_value() + #[inline] + #[must_use] + pub fn default_missing_value(self, val: &'help str) -> Self { + self.default_missing_values_os(&[OsStr::new(val)]) + } + + /// Value for the argument when the flag is present but no value is specified. + /// + /// See [`Arg::default_missing_value`]. + /// + /// [`Arg::default_missing_value`]: Arg::default_missing_value() + /// [`OsStr`]: std::ffi::OsStr + #[inline] + #[must_use] + pub fn default_missing_value_os(self, val: &'help OsStr) -> Self { + self.default_missing_values_os(&[val]) + } + + /// Value for the argument when the flag is present but no value is specified. + /// + /// See [`Arg::default_missing_value`]. + /// + /// [`Arg::default_missing_value`]: Arg::default_missing_value() + #[inline] + #[must_use] + pub fn default_missing_values(self, vals: &[&'help str]) -> Self { + let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect(); + self.default_missing_values_os(&vals_vec[..]) + } + + /// Value for the argument when the flag is present but no value is specified. + /// + /// See [`Arg::default_missing_values`]. + /// + /// [`Arg::default_missing_values`]: Arg::default_missing_values() + /// [`OsStr`]: std::ffi::OsStr + #[inline] + #[must_use] + pub fn default_missing_values_os(mut self, vals: &[&'help OsStr]) -> Self { + self.default_missing_vals = vals.to_vec(); + self.takes_value(true) + } + + /// Read from `name` environment variable when argument is not present. + /// + /// If it is not present in the environment, then default + /// rules will apply. + /// + /// If user sets the argument in the environment: + /// - When [`Arg::takes_value(true)`] is not set, the flag is considered raised. + /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will + /// return value of the environment variable. + /// + /// If user doesn't set the argument in the environment: + /// - When [`Arg::takes_value(true)`] is not set, the flag is considered off. + /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will + /// return the default specified. + /// + /// # Examples + /// + /// In this example, we show the variable coming from the environment: + /// + /// ```rust + /// # use std::env; + /// # use clap::{Command, Arg}; + /// + /// env::set_var("MY_FLAG", "env"); + /// + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag") + /// .env("MY_FLAG") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert_eq!(m.value_of("flag"), Some("env")); + /// ``` + /// + /// In this example, because [`Arg::takes_value(false)`] (by default), + /// `prog` is a flag that accepts an optional, case-insensitive boolean literal. + /// A `false` literal is `n`, `no`, `f`, `false`, `off` or `0`. + /// An absent environment variable will also be considered as `false`. + /// Anything else will considered as `true`. + /// + /// ```rust + /// # use std::env; + /// # use clap::{Command, Arg}; + /// + /// env::set_var("TRUE_FLAG", "true"); + /// env::set_var("FALSE_FLAG", "0"); + /// + /// let m = Command::new("prog") + /// .arg(Arg::new("true_flag") + /// .long("true_flag") + /// .env("TRUE_FLAG")) + /// .arg(Arg::new("false_flag") + /// .long("false_flag") + /// .env("FALSE_FLAG")) + /// .arg(Arg::new("absent_flag") + /// .long("absent_flag") + /// .env("ABSENT_FLAG")) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(m.is_present("true_flag")); + /// assert_eq!(m.value_of("true_flag"), None); + /// assert!(!m.is_present("false_flag")); + /// assert!(!m.is_present("absent_flag")); + /// ``` + /// + /// In this example, we show the variable coming from an option on the CLI: + /// + /// ```rust + /// # use std::env; + /// # use clap::{Command, Arg}; + /// + /// env::set_var("MY_FLAG", "env"); + /// + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag") + /// .env("MY_FLAG") + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "prog", "--flag", "opt" + /// ]); + /// + /// assert_eq!(m.value_of("flag"), Some("opt")); + /// ``` + /// + /// In this example, we show the variable coming from the environment even with the + /// presence of a default: + /// + /// ```rust + /// # use std::env; + /// # use clap::{Command, Arg}; + /// + /// env::set_var("MY_FLAG", "env"); + /// + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag") + /// .env("MY_FLAG") + /// .takes_value(true) + /// .default_value("default")) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert_eq!(m.value_of("flag"), Some("env")); + /// ``` + /// + /// In this example, we show the use of multiple values in a single environment variable: + /// + /// ```rust + /// # use std::env; + /// # use clap::{Command, Arg}; + /// + /// env::set_var("MY_FLAG_MULTI", "env1,env2"); + /// + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag") + /// .env("MY_FLAG_MULTI") + /// .takes_value(true) + /// .multiple_values(true) + /// .use_value_delimiter(true)) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert_eq!(m.values_of("flag").unwrap().collect::>(), vec!["env1", "env2"]); + /// ``` + /// [`ArgMatches::value_of`]: crate::ArgMatches::value_of() + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`Arg::use_value_delimiter(true)`]: Arg::use_value_delimiter() + #[cfg(feature = "env")] + #[inline] + #[must_use] + pub fn env(self, name: &'help str) -> Self { + self.env_os(OsStr::new(name)) + } + + /// Read from `name` environment variable when argument is not present. + /// + /// See [`Arg::env`]. + #[cfg(feature = "env")] + #[inline] + #[must_use] + pub fn env_os(mut self, name: &'help OsStr) -> Self { + self.env = Some((name, env::var_os(name))); + self + } +} + +/// # Help +impl<'help> Arg<'help> { + /// Sets the description of the argument for short help (`-h`). + /// + /// Typically, this is a short (one line) description of the arg. + /// + /// If [`Arg::long_help`] is not specified, this message will be displayed for `--help`. + /// + /// **NOTE:** Only `Arg::help` is used in completion script generation in order to be concise + /// + /// # Examples + /// + /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to + /// include a newline in the help text and have the following text be properly aligned with all + /// the other help text. + /// + /// Setting `help` displays a short message to the side of the argument when the user passes + /// `-h` or `--help` (by default). + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .help("Some help text describing the --config arg")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// The above example displays + /// + /// ```notrust + /// helptest + /// + /// USAGE: + /// helptest [OPTIONS] + /// + /// OPTIONS: + /// --config Some help text describing the --config arg + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + /// [`Arg::long_help`]: Arg::long_help() + #[inline] + #[must_use] + pub fn help(mut self, h: impl Into>) -> Self { + self.help = h.into(); + self + } + + /// Sets the description of the argument for long help (`--help`). + /// + /// Typically this a more detailed (multi-line) message + /// that describes the arg. + /// + /// If [`Arg::help`] is not specified, this message will be displayed for `-h`. + /// + /// **NOTE:** Only [`Arg::help`] is used in completion script generation in order to be concise + /// + /// # Examples + /// + /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to + /// include a newline in the help text and have the following text be properly aligned with all + /// the other help text. + /// + /// Setting `help` displays a short message to the side of the argument when the user passes + /// `-h` or `--help` (by default). + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .long_help( + /// "The config file used by the myprog must be in JSON format + /// with only valid keys and may not contain other nonsense + /// that cannot be read by this program. Obviously I'm going on + /// and on, so I'll stop now.")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// The above example displays + /// + /// ```text + /// prog + /// + /// USAGE: + /// prog [OPTIONS] + /// + /// OPTIONS: + /// --config + /// The config file used by the myprog must be in JSON format + /// with only valid keys and may not contain other nonsense + /// that cannot be read by this program. Obviously I'm going on + /// and on, so I'll stop now. + /// + /// -h, --help + /// Print help information + /// + /// -V, --version + /// Print version information + /// ``` + /// [`Arg::help`]: Arg::help() + #[inline] + #[must_use] + pub fn long_help(mut self, h: impl Into>) -> Self { + self.long_help = h.into(); + self + } + + /// Allows custom ordering of args within the help message. + /// + /// Args with a lower value will be displayed first in the help message. This is helpful when + /// one would like to emphasise frequently used args, or prioritize those towards the top of + /// the list. Args with duplicate display orders will be displayed in alphabetical order. + /// + /// **NOTE:** The default is 999 for all arguments. + /// + /// **NOTE:** This setting is ignored for [positional arguments] which are always displayed in + /// [index] order. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("a") // Typically args are grouped alphabetically by name. + /// // Args without a display_order have a value of 999 and are + /// // displayed alphabetically with all other 999 valued args. + /// .long("long-option") + /// .short('o') + /// .takes_value(true) + /// .help("Some help and text")) + /// .arg(Arg::new("b") + /// .long("other-option") + /// .short('O') + /// .takes_value(true) + /// .display_order(1) // In order to force this arg to appear *first* + /// // all we have to do is give it a value lower than 999. + /// // Any other args with a value of 1 will be displayed + /// // alphabetically with this one...then 2 values, then 3, etc. + /// .help("I should be first!")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// The above example displays the following help message + /// + /// ```text + /// cust-ord + /// + /// USAGE: + /// cust-ord [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// -O, --other-option I should be first! + /// -o, --long-option Some help and text + /// ``` + /// [positional arguments]: Arg::index() + /// [index]: Arg::index() + #[inline] + #[must_use] + pub fn display_order(mut self, ord: usize) -> Self { + self.disp_ord.set_explicit(ord); + self + } + + /// Override the [current] help section. + /// + /// [current]: crate::Command::help_heading + #[inline] + #[must_use] + pub fn help_heading(mut self, heading: O) -> Self + where + O: Into>, + { + self.help_heading = Some(heading.into()); + self + } + + /// Render the [help][Arg::help] on the line after the argument. + /// + /// This can be helpful for arguments with very long or complex help messages. + /// This can also be helpful for arguments with very long flag names, or many/long value names. + /// + /// **NOTE:** To apply this setting to all arguments and subcommands, consider using + /// [`crate::Command::next_line_help`] + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("opt") + /// .long("long-option-flag") + /// .short('o') + /// .takes_value(true) + /// .next_line_help(true) + /// .value_names(&["value1", "value2"]) + /// .help("Some really long help and complex\n\ + /// help that makes more sense to be\n\ + /// on a line after the option")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// The above example displays the following help message + /// + /// ```text + /// nlh + /// + /// USAGE: + /// nlh [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// -o, --long-option-flag + /// Some really long help and complex + /// help that makes more sense to be + /// on a line after the option + /// ``` + #[inline] + #[must_use] + pub fn next_line_help(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::NextLineHelp) + } else { + self.unset_setting(ArgSettings::NextLineHelp) + } + } + + /// Do not display the argument in help message. + /// + /// **NOTE:** This does **not** hide the argument from usage strings on error + /// + /// # Examples + /// + /// Setting `Hidden` will hide the argument when displaying help text + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .hide(true) + /// .help("Some help text describing the --config arg")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// The above example displays + /// + /// ```text + /// helptest + /// + /// USAGE: + /// helptest [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + #[inline] + #[must_use] + pub fn hide(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::Hidden) + } else { + self.unset_setting(ArgSettings::Hidden) + } + } + + /// Do not display the [possible values][crate::builder::ValueParser::possible_values] in the help message. + /// + /// This is useful for args with many values, or ones which are explained elsewhere in the + /// help text. + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`] + /// + /// To set this for all arguments, see + /// [`Command::hide_possible_values`][crate::Command::hide_possible_values]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("mode") + /// .long("mode") + /// .value_parser(["fast", "slow"]) + /// .takes_value(true) + /// .hide_possible_values(true)); + /// ``` + /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of + /// the help text would be omitted. + #[inline] + #[must_use] + pub fn hide_possible_values(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::HidePossibleValues) + } else { + self.unset_setting(ArgSettings::HidePossibleValues) + } + } + + /// Do not display the default value of the argument in the help message. + /// + /// This is useful when default behavior of an arg is explained elsewhere in the help text. + /// + /// **NOTE:** Setting this requires [`Arg::takes_value`] + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("connect") + /// .arg(Arg::new("host") + /// .long("host") + /// .default_value("localhost") + /// .takes_value(true) + /// .hide_default_value(true)); + /// + /// ``` + /// + /// If we were to run the above program with `--help` the `[default: localhost]` portion of + /// the help text would be omitted. + #[inline] + #[must_use] + pub fn hide_default_value(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::HideDefaultValue) + } else { + self.unset_setting(ArgSettings::HideDefaultValue) + } + } + + /// Do not display in help the environment variable name. + /// + /// This is useful when the variable option is explained elsewhere in the help text. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("mode") + /// .long("mode") + /// .env("MODE") + /// .takes_value(true) + /// .hide_env(true)); + /// ``` + /// + /// If we were to run the above program with `--help` the `[env: MODE]` portion of the help + /// text would be omitted. + #[cfg(feature = "env")] + #[inline] + #[must_use] + pub fn hide_env(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::HideEnv) + } else { + self.unset_setting(ArgSettings::HideEnv) + } + } + + /// Do not display in help any values inside the associated ENV variables for the argument. + /// + /// This is useful when ENV vars contain sensitive values. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("connect") + /// .arg(Arg::new("host") + /// .long("host") + /// .env("CONNECT") + /// .takes_value(true) + /// .hide_env_values(true)); + /// + /// ``` + /// + /// If we were to run the above program with `$ CONNECT=super_secret connect --help` the + /// `[default: CONNECT=super_secret]` portion of the help text would be omitted. + #[cfg(feature = "env")] + #[inline] + #[must_use] + pub fn hide_env_values(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::HideEnvValues) + } else { + self.unset_setting(ArgSettings::HideEnvValues) + } + } + + /// Hides an argument from short help (`-h`). + /// + /// **NOTE:** This does **not** hide the argument from usage strings on error + /// + /// **NOTE:** Setting this option will cause next-line-help output style to be used + /// when long help (`--help`) is called. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("debug") + /// .hide_short_help(true); + /// ``` + /// + /// Setting `hide_short_help(true)` will hide the argument when displaying short help text + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .hide_short_help(true) + /// .help("Some help text describing the --config arg")) + /// .get_matches_from(vec![ + /// "prog", "-h" + /// ]); + /// ``` + /// + /// The above example displays + /// + /// ```text + /// helptest + /// + /// USAGE: + /// helptest [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + /// + /// However, when --help is called + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .hide_short_help(true) + /// .help("Some help text describing the --config arg")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// Then the following would be displayed + /// + /// ```text + /// helptest + /// + /// USAGE: + /// helptest [OPTIONS] + /// + /// OPTIONS: + /// --config Some help text describing the --config arg + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + #[inline] + #[must_use] + pub fn hide_short_help(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::HiddenShortHelp) + } else { + self.unset_setting(ArgSettings::HiddenShortHelp) + } + } + + /// Hides an argument from long help (`--help`). + /// + /// **NOTE:** This does **not** hide the argument from usage strings on error + /// + /// **NOTE:** Setting this option will cause next-line-help output style to be used + /// when long help (`--help`) is called. + /// + /// # Examples + /// + /// Setting `hide_long_help(true)` will hide the argument when displaying long help text + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .hide_long_help(true) + /// .help("Some help text describing the --config arg")) + /// .get_matches_from(vec![ + /// "prog", "--help" + /// ]); + /// ``` + /// + /// The above example displays + /// + /// ```text + /// helptest + /// + /// USAGE: + /// helptest [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + /// + /// However, when -h is called + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .long("config") + /// .hide_long_help(true) + /// .help("Some help text describing the --config arg")) + /// .get_matches_from(vec![ + /// "prog", "-h" + /// ]); + /// ``` + /// + /// Then the following would be displayed + /// + /// ```text + /// helptest + /// + /// USAGE: + /// helptest [OPTIONS] + /// + /// OPTIONS: + /// --config Some help text describing the --config arg + /// -h, --help Print help information + /// -V, --version Print version information + /// ``` + #[inline] + #[must_use] + pub fn hide_long_help(self, yes: bool) -> Self { + if yes { + self.setting(ArgSettings::HiddenLongHelp) + } else { + self.unset_setting(ArgSettings::HiddenLongHelp) + } + } +} + +/// # Advanced Argument Relations +impl<'help> Arg<'help> { + /// The name of the [`ArgGroup`] the argument belongs to. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("debug") + /// .long("debug") + /// .group("mode") + /// # ; + /// ``` + /// + /// Multiple arguments can be a member of a single group and then the group checked as if it + /// was one of said arguments. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("debug") + /// .long("debug") + /// .group("mode")) + /// .arg(Arg::new("verbose") + /// .long("verbose") + /// .group("mode")) + /// .get_matches_from(vec![ + /// "prog", "--debug" + /// ]); + /// assert!(m.contains_id("mode")); + /// ``` + /// + /// [`ArgGroup`]: crate::ArgGroup + #[must_use] + pub fn group(mut self, group_id: T) -> Self { + self.groups.push(group_id.into()); + self + } + + /// The names of [`ArgGroup`]'s the argument belongs to. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Arg::new("debug") + /// .long("debug") + /// .groups(&["mode", "verbosity"]) + /// # ; + /// ``` + /// + /// Arguments can be members of multiple groups and then the group checked as if it + /// was one of said arguments. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("debug") + /// .long("debug") + /// .groups(&["mode", "verbosity"])) + /// .arg(Arg::new("verbose") + /// .long("verbose") + /// .groups(&["mode", "verbosity"])) + /// .get_matches_from(vec![ + /// "prog", "--debug" + /// ]); + /// assert!(m.contains_id("mode")); + /// assert!(m.contains_id("verbosity")); + /// ``` + /// + /// [`ArgGroup`]: crate::ArgGroup + #[must_use] + pub fn groups(mut self, group_ids: &[T]) -> Self { + self.groups.extend(group_ids.iter().map(Id::from)); + self + } + + /// Specifies the value of the argument if `arg` has been used at runtime. + /// + /// If `val` is set to `None`, `arg` only needs to be present. If `val` is set to `"some-val"` + /// then `arg` must be present at runtime **and** have the value `val`. + /// + /// If `default` is set to `None`, `default_value` will be removed. + /// + /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value`] but slightly + /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg + /// at runtime. This setting however only takes effect when the user has not provided a value at + /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value` + /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were + /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied. + /// + /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`]. + /// + /// # Examples + /// + /// First we use the default value only if another arg is present at runtime. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag")) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_if("flag", None, Some("default"))) + /// .get_matches_from(vec![ + /// "prog", "--flag" + /// ]); + /// + /// assert_eq!(m.value_of("other"), Some("default")); + /// ``` + /// + /// Next we run the same test, but without providing `--flag`. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag")) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_if("flag", None, Some("default"))) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert_eq!(m.value_of("other"), None); + /// ``` + /// + /// Now lets only use the default value if `--opt` contains the value `special`. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("opt") + /// .takes_value(true) + /// .long("opt")) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_if("opt", Some("special"), Some("default"))) + /// .get_matches_from(vec![ + /// "prog", "--opt", "special" + /// ]); + /// + /// assert_eq!(m.value_of("other"), Some("default")); + /// ``` + /// + /// We can run the same test and provide any value *other than* `special` and we won't get a + /// default value. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("opt") + /// .takes_value(true) + /// .long("opt")) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_if("opt", Some("special"), Some("default"))) + /// .get_matches_from(vec![ + /// "prog", "--opt", "hahaha" + /// ]); + /// + /// assert_eq!(m.value_of("other"), None); + /// ``` + /// + /// If we want to unset the default value for an Arg based on the presence or + /// value of some other Arg. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag")) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value("default") + /// .default_value_if("flag", None, None)) + /// .get_matches_from(vec![ + /// "prog", "--flag" + /// ]); + /// + /// assert_eq!(m.value_of("other"), None); + /// ``` + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`Arg::default_value`]: Arg::default_value() + #[must_use] + pub fn default_value_if( + self, + arg_id: T, + val: Option<&'help str>, + default: Option<&'help str>, + ) -> Self { + self.default_value_if_os(arg_id, val.map(OsStr::new), default.map(OsStr::new)) + } + + /// Provides a conditional default value in the exact same manner as [`Arg::default_value_if`] + /// only using [`OsStr`]s instead. + /// + /// [`Arg::default_value_if`]: Arg::default_value_if() + /// [`OsStr`]: std::ffi::OsStr + #[must_use] + pub fn default_value_if_os( + mut self, + arg_id: T, + val: Option<&'help OsStr>, + default: Option<&'help OsStr>, + ) -> Self { + self.default_vals_ifs + .push((arg_id.into(), val.into(), default)); + self.takes_value(true) + } + + /// Specifies multiple values and conditions in the same manner as [`Arg::default_value_if`]. + /// + /// The method takes a slice of tuples in the `(arg, Option, default)` format. + /// + /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first + /// if multiple conditions are true, the first one found will be applied and the ultimate value. + /// + /// # Examples + /// + /// First we use the default value only if another arg is present at runtime. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag")) + /// .arg(Arg::new("opt") + /// .long("opt") + /// .takes_value(true)) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_ifs(&[ + /// ("flag", None, Some("default")), + /// ("opt", Some("channal"), Some("chan")), + /// ])) + /// .get_matches_from(vec![ + /// "prog", "--opt", "channal" + /// ]); + /// + /// assert_eq!(m.value_of("other"), Some("chan")); + /// ``` + /// + /// Next we run the same test, but without providing `--flag`. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag")) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_ifs(&[ + /// ("flag", None, Some("default")), + /// ("opt", Some("channal"), Some("chan")), + /// ])) + /// .get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert_eq!(m.value_of("other"), None); + /// ``` + /// + /// We can also see that these values are applied in order, and if more than one condition is + /// true, only the first evaluated "wins" + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .arg(Arg::new("flag") + /// .long("flag")) + /// .arg(Arg::new("opt") + /// .long("opt") + /// .takes_value(true)) + /// .arg(Arg::new("other") + /// .long("other") + /// .default_value_ifs(&[ + /// ("flag", None, Some("default")), + /// ("opt", Some("channal"), Some("chan")), + /// ])) + /// .get_matches_from(vec![ + /// "prog", "--opt", "channal", "--flag" + /// ]); + /// + /// assert_eq!(m.value_of("other"), Some("default")); + /// ``` + /// [`Arg::takes_value(true)`]: Arg::takes_value() + /// [`Arg::default_value_if`]: Arg::default_value_if() + #[must_use] + pub fn default_value_ifs( + mut self, + ifs: &[(T, Option<&'help str>, Option<&'help str>)], + ) -> Self { + for (arg, val, default) in ifs { + self = self.default_value_if_os(arg, val.map(OsStr::new), default.map(OsStr::new)); + } + self + } + + /// Provides multiple conditional default values in the exact same manner as + /// [`Arg::default_value_ifs`] only using [`OsStr`]s instead. + /// + /// [`Arg::default_value_ifs`]: Arg::default_value_ifs() + /// [`OsStr`]: std::ffi::OsStr + #[must_use] + pub fn default_value_ifs_os( + mut self, + ifs: &[(T, Option<&'help OsStr>, Option<&'help OsStr>)], + ) -> Self { + for (arg, val, default) in ifs { + self = self.default_value_if_os(arg, *val, *default); + } + self + } + + /// Set this arg as [required] as long as the specified argument is not present at runtime. + /// + /// **Pro Tip:** Using `Arg::required_unless_present` implies [`Arg::required`] and is therefore not + /// mandatory to also set. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required_unless_present("debug") + /// # ; + /// ``` + /// + /// In the following example, the required argument is *not* provided, + /// but it's not an error because the `unless` arg has been supplied. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_unless_present("dbg") + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("dbg") + /// .long("debug")) + /// .try_get_matches_from(vec![ + /// "prog", "--debug" + /// ]); + /// + /// assert!(res.is_ok()); + /// ``` + /// + /// Setting `Arg::required_unless_present(name)` and *not* supplying `name` or this arg is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_unless_present("dbg") + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("dbg") + /// .long("debug")) + /// .try_get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [required]: Arg::required() + #[must_use] + pub fn required_unless_present(mut self, arg_id: T) -> Self { + self.r_unless.push(arg_id.into()); + self + } + + /// Sets this arg as [required] unless *all* of the specified arguments are present at runtime. + /// + /// In other words, parsing will succeed only if user either + /// * supplies the `self` arg. + /// * supplies *all* of the `names` arguments. + /// + /// **NOTE:** If you wish for this argument to only be required unless *any of* these args are + /// present see [`Arg::required_unless_present_any`] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required_unless_present_all(&["cfg", "dbg"]) + /// # ; + /// ``` + /// + /// In the following example, the required argument is *not* provided, but it's not an error + /// because *all* of the `names` args have been supplied. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_unless_present_all(&["dbg", "infile"]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("dbg") + /// .long("debug")) + /// .arg(Arg::new("infile") + /// .short('i') + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog", "--debug", "-i", "file" + /// ]); + /// + /// assert!(res.is_ok()); + /// ``` + /// + /// Setting [`Arg::required_unless_present_all(names)`] and *not* supplying + /// either *all* of `unless` args or the `self` arg is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_unless_present_all(&["dbg", "infile"]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("dbg") + /// .long("debug")) + /// .arg(Arg::new("infile") + /// .short('i') + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [required]: Arg::required() + /// [`Arg::required_unless_present_any`]: Arg::required_unless_present_any() + /// [`Arg::required_unless_present_all(names)`]: Arg::required_unless_present_all() + #[must_use] + pub fn required_unless_present_all(mut self, names: I) -> Self + where + I: IntoIterator, + T: Key, + { + self.r_unless_all.extend(names.into_iter().map(Id::from)); + self + } + + /// Sets this arg as [required] unless *any* of the specified arguments are present at runtime. + /// + /// In other words, parsing will succeed only if user either + /// * supplies the `self` arg. + /// * supplies *one or more* of the `unless` arguments. + /// + /// **NOTE:** If you wish for this argument to be required unless *all of* these args are + /// present see [`Arg::required_unless_present_all`] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required_unless_present_any(&["cfg", "dbg"]) + /// # ; + /// ``` + /// + /// Setting [`Arg::required_unless_present_any(names)`] requires that the argument be used at runtime + /// *unless* *at least one of* the args in `names` are present. In the following example, the + /// required argument is *not* provided, but it's not an error because one the `unless` args + /// have been supplied. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_unless_present_any(&["dbg", "infile"]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("dbg") + /// .long("debug")) + /// .arg(Arg::new("infile") + /// .short('i') + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog", "--debug" + /// ]); + /// + /// assert!(res.is_ok()); + /// ``` + /// + /// Setting [`Arg::required_unless_present_any(names)`] and *not* supplying *at least one of* `names` + /// or this arg is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_unless_present_any(&["dbg", "infile"]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("dbg") + /// .long("debug")) + /// .arg(Arg::new("infile") + /// .short('i') + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [required]: Arg::required() + /// [`Arg::required_unless_present_any(names)`]: Arg::required_unless_present_any() + /// [`Arg::required_unless_present_all`]: Arg::required_unless_present_all() + #[must_use] + pub fn required_unless_present_any(mut self, names: I) -> Self + where + I: IntoIterator, + T: Key, + { + self.r_unless.extend(names.into_iter().map(Id::from)); + self + } + + /// This argument is [required] only if the specified `arg` is present at runtime and its value + /// equals `val`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required_if_eq("other_arg", "value") + /// # ; + /// ``` + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .required_if_eq("other", "special") + /// .long("config")) + /// .arg(Arg::new("other") + /// .long("other") + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog", "--other", "not-special" + /// ]); + /// + /// assert!(res.is_ok()); // We didn't use --other=special, so "cfg" wasn't required + /// + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .required_if_eq("other", "special") + /// .long("config")) + /// .arg(Arg::new("other") + /// .long("other") + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog", "--other", "special" + /// ]); + /// + /// // We did use --other=special so "cfg" had become required but was missing. + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .required_if_eq("other", "special") + /// .long("config")) + /// .arg(Arg::new("other") + /// .long("other") + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog", "--other", "SPECIAL" + /// ]); + /// + /// // By default, the comparison is case-sensitive, so "cfg" wasn't required + /// assert!(res.is_ok()); + /// + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .required_if_eq("other", "special") + /// .long("config")) + /// .arg(Arg::new("other") + /// .long("other") + /// .ignore_case(true) + /// .takes_value(true)) + /// .try_get_matches_from(vec![ + /// "prog", "--other", "SPECIAL" + /// ]); + /// + /// // However, case-insensitive comparisons can be enabled. This typically occurs when using Arg::possible_values(). + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [`Arg::requires(name)`]: Arg::requires() + /// [Conflicting]: Arg::conflicts_with() + /// [required]: Arg::required() + #[must_use] + pub fn required_if_eq(mut self, arg_id: T, val: &'help str) -> Self { + self.r_ifs.push((arg_id.into(), val)); + self + } + + /// Specify this argument is [required] based on multiple conditions. + /// + /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become + /// valid if one of the specified `arg`'s value equals its corresponding `val`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required_if_eq_any(&[ + /// ("extra", "val"), + /// ("option", "spec") + /// ]) + /// # ; + /// ``` + /// + /// Setting `Arg::required_if_eq_any(&[(arg, val)])` makes this arg required if any of the `arg`s + /// are used at runtime and it's corresponding value is equal to `val`. If the `arg`'s value is + /// anything other than `val`, this argument isn't required. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_if_eq_any(&[ + /// ("extra", "val"), + /// ("option", "spec") + /// ]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("extra") + /// .takes_value(true) + /// .long("extra")) + /// .arg(Arg::new("option") + /// .takes_value(true) + /// .long("option")) + /// .try_get_matches_from(vec![ + /// "prog", "--option", "other" + /// ]); + /// + /// assert!(res.is_ok()); // We didn't use --option=spec, or --extra=val so "cfg" isn't required + /// ``` + /// + /// Setting `Arg::required_if_eq_any(&[(arg, val)])` and having any of the `arg`s used with its + /// value of `val` but *not* using this arg is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_if_eq_any(&[ + /// ("extra", "val"), + /// ("option", "spec") + /// ]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("extra") + /// .takes_value(true) + /// .long("extra")) + /// .arg(Arg::new("option") + /// .takes_value(true) + /// .long("option")) + /// .try_get_matches_from(vec![ + /// "prog", "--option", "spec" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [`Arg::requires(name)`]: Arg::requires() + /// [Conflicting]: Arg::conflicts_with() + /// [required]: Arg::required() + #[must_use] + pub fn required_if_eq_any(mut self, ifs: &[(T, &'help str)]) -> Self { + self.r_ifs + .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val))); + self + } + + /// Specify this argument is [required] based on multiple conditions. + /// + /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become + /// valid if every one of the specified `arg`'s value equals its corresponding `val`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .required_if_eq_all(&[ + /// ("extra", "val"), + /// ("option", "spec") + /// ]) + /// # ; + /// ``` + /// + /// Setting `Arg::required_if_eq_all(&[(arg, val)])` makes this arg required if all of the `arg`s + /// are used at runtime and every value is equal to its corresponding `val`. If the `arg`'s value is + /// anything other than `val`, this argument isn't required. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_if_eq_all(&[ + /// ("extra", "val"), + /// ("option", "spec") + /// ]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("extra") + /// .takes_value(true) + /// .long("extra")) + /// .arg(Arg::new("option") + /// .takes_value(true) + /// .long("option")) + /// .try_get_matches_from(vec![ + /// "prog", "--option", "spec" + /// ]); + /// + /// assert!(res.is_ok()); // We didn't use --option=spec --extra=val so "cfg" isn't required + /// ``` + /// + /// Setting `Arg::required_if_eq_all(&[(arg, val)])` and having all of the `arg`s used with its + /// value of `val` but *not* using this arg is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .required_if_eq_all(&[ + /// ("extra", "val"), + /// ("option", "spec") + /// ]) + /// .takes_value(true) + /// .long("config")) + /// .arg(Arg::new("extra") + /// .takes_value(true) + /// .long("extra")) + /// .arg(Arg::new("option") + /// .takes_value(true) + /// .long("option")) + /// .try_get_matches_from(vec![ + /// "prog", "--extra", "val", "--option", "spec" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [required]: Arg::required() + #[must_use] + pub fn required_if_eq_all(mut self, ifs: &[(T, &'help str)]) -> Self { + self.r_ifs_all + .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val))); + self + } + + /// Require another argument if this arg was present at runtime and its value equals to `val`. + /// + /// This method takes `value, another_arg` pair. At runtime, clap will check + /// if this arg (`self`) is present and its value equals to `val`. + /// If it does, `another_arg` will be marked as required. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .requires_if("val", "arg") + /// # ; + /// ``` + /// + /// Setting `Arg::requires_if(val, arg)` requires that the `arg` be used at runtime if the + /// defining argument's value is equal to `val`. If the defining argument is anything other than + /// `val`, the other argument isn't required. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires_if("my.cfg", "other") + /// .long("config")) + /// .arg(Arg::new("other")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "some.cfg" + /// ]); + /// + /// assert!(res.is_ok()); // We didn't use --config=my.cfg, so other wasn't required + /// ``` + /// + /// Setting `Arg::requires_if(val, arg)` and setting the value to `val` but *not* supplying + /// `arg` is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires_if("my.cfg", "input") + /// .long("config")) + /// .arg(Arg::new("input")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "my.cfg" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [`Arg::requires(name)`]: Arg::requires() + /// [Conflicting]: Arg::conflicts_with() + /// [override]: Arg::overrides_with() + #[must_use] + pub fn requires_if(mut self, val: &'help str, arg_id: T) -> Self { + self.requires + .push((ArgPredicate::Equals(OsStr::new(val)), arg_id.into())); + self + } + + /// Allows multiple conditional requirements. + /// + /// The requirement will only become valid if this arg's value equals `val`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .requires_ifs(&[ + /// ("val", "arg"), + /// ("other_val", "arg2"), + /// ]) + /// # ; + /// ``` + /// + /// Setting `Arg::requires_ifs(&["val", "arg"])` requires that the `arg` be used at runtime if the + /// defining argument's value is equal to `val`. If the defining argument's value is anything other + /// than `val`, `arg` isn't required. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires_ifs(&[ + /// ("special.conf", "opt"), + /// ("other.conf", "other"), + /// ]) + /// .long("config")) + /// .arg(Arg::new("opt") + /// .long("option") + /// .takes_value(true)) + /// .arg(Arg::new("other")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "special.conf" + /// ]); + /// + /// assert!(res.is_err()); // We used --config=special.conf so --option is required + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [`Arg::requires(name)`]: Arg::requires() + /// [Conflicting]: Arg::conflicts_with() + /// [override]: Arg::overrides_with() + #[must_use] + pub fn requires_ifs(mut self, ifs: &[(&'help str, T)]) -> Self { + self.requires.extend( + ifs.iter() + .map(|(val, arg)| (ArgPredicate::Equals(OsStr::new(*val)), Id::from(arg))), + ); + self + } + + /// Require these arguments names when this one is presen + /// + /// i.e. when using this argument, the following arguments *must* be present. + /// + /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required + /// by default. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .requires_all(&["input", "output"]) + /// # ; + /// ``` + /// + /// Setting `Arg::requires_all(&[arg, arg2])` requires that all the arguments be used at + /// runtime if the defining argument is used. If the defining argument isn't used, the other + /// argument isn't required + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires("input") + /// .long("config")) + /// .arg(Arg::new("input")) + /// .arg(Arg::new("output")) + /// .try_get_matches_from(vec![ + /// "prog" + /// ]); + /// + /// assert!(res.is_ok()); // We didn't use cfg, so input and output weren't required + /// ``` + /// + /// Setting `Arg::requires_all(&[arg, arg2])` and *not* supplying all the arguments is an + /// error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .requires_all(&["input", "output"]) + /// .long("config")) + /// .arg(Arg::new("input")) + /// .arg(Arg::new("output")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "file.conf", "in.txt" + /// ]); + /// + /// assert!(res.is_err()); + /// // We didn't use output + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [Conflicting]: Arg::conflicts_with() + /// [override]: Arg::overrides_with() + #[must_use] + pub fn requires_all(mut self, names: &[T]) -> Self { + self.requires + .extend(names.iter().map(|s| (ArgPredicate::IsPresent, s.into()))); + self + } + + /// This argument is mutually exclusive with the specified argument. + /// + /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules + /// only need to be set for one of the two arguments, they do not need to be set for each. + /// + /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments + /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not + /// need to also do B.conflicts_with(A)) + /// + /// **NOTE:** [`Arg::conflicts_with_all(names)`] allows specifying an argument which conflicts with more than one argument. + /// + /// **NOTE** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .conflicts_with("debug") + /// # ; + /// ``` + /// + /// Setting conflicting argument, and having both arguments present at runtime is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .conflicts_with("debug") + /// .long("config")) + /// .arg(Arg::new("debug") + /// .long("debug")) + /// .try_get_matches_from(vec![ + /// "prog", "--debug", "--config", "file.conf" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict); + /// ``` + /// + /// [`Arg::conflicts_with_all(names)`]: Arg::conflicts_with_all() + /// [`Arg::exclusive(true)`]: Arg::exclusive() + #[must_use] + pub fn conflicts_with(mut self, arg_id: T) -> Self { + self.blacklist.push(arg_id.into()); + self + } + + /// This argument is mutually exclusive with the specified arguments. + /// + /// See [`Arg::conflicts_with`]. + /// + /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules + /// only need to be set for one of the two arguments, they do not need to be set for each. + /// + /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments + /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not need + /// need to also do B.conflicts_with(A)) + /// + /// **NOTE:** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// Arg::new("config") + /// .conflicts_with_all(&["debug", "input"]) + /// # ; + /// ``` + /// + /// Setting conflicting argument, and having any of the arguments present at runtime with a + /// conflicting argument is an error. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("cfg") + /// .takes_value(true) + /// .conflicts_with_all(&["debug", "input"]) + /// .long("config")) + /// .arg(Arg::new("debug") + /// .long("debug")) + /// .arg(Arg::new("input")) + /// .try_get_matches_from(vec![ + /// "prog", "--config", "file.conf", "file.txt" + /// ]); + /// + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict); + /// ``` + /// [`Arg::conflicts_with`]: Arg::conflicts_with() + /// [`Arg::exclusive(true)`]: Arg::exclusive() + #[must_use] + pub fn conflicts_with_all(mut self, names: &[&str]) -> Self { + self.blacklist.extend(names.iter().copied().map(Id::from)); + self + } + + /// Sets an overridable argument. + /// + /// i.e. this argument and the following argument + /// will override each other in POSIX style (whichever argument was specified at runtime + /// **last** "wins") + /// + /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any + /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed + /// + /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with`]. + /// + /// **WARNING:** Positional arguments and options which accept + /// [`Arg::multiple_occurrences`] cannot override themselves (or we + /// would never be able to advance to the next positional). If a positional + /// argument or option with one of the [`Arg::multiple_occurrences`] + /// settings lists itself as an override, it is simply ignored. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, arg}; + /// let m = Command::new("prog") + /// .arg(arg!(-f --flag "some flag") + /// .conflicts_with("debug")) + /// .arg(arg!(-d --debug "other flag")) + /// .arg(arg!(-c --color "third flag") + /// .overrides_with("flag")) + /// .get_matches_from(vec![ + /// "prog", "-f", "-d", "-c"]); + /// // ^~~~~~~~~~~~^~~~~ flag is overridden by color + /// + /// assert!(m.is_present("color")); + /// assert!(m.is_present("debug")); // even though flag conflicts with debug, it's as if flag + /// // was never used because it was overridden with color + /// assert!(!m.is_present("flag")); + /// ``` + /// Care must be taken when using this setting, and having an arg override with itself. This + /// is common practice when supporting things like shell aliases, config files, etc. + /// However, when combined with multiple values, it can get dicy. + /// Here is how clap handles such situations: + /// + /// When a flag overrides itself, it's as if the flag was only ever used once (essentially + /// preventing a "Unexpected multiple usage" error): + /// + /// ```rust + /// # use clap::{Command, arg}; + /// let m = Command::new("posix") + /// .arg(arg!(--flag "some flag").overrides_with("flag")) + /// .get_matches_from(vec!["posix", "--flag", "--flag"]); + /// assert!(m.is_present("flag")); + /// ``` + /// + /// Making an arg [`Arg::multiple_occurrences`] and override itself + /// is essentially meaningless. Therefore clap ignores an override of self + /// if it's a flag and it already accepts multiple occurrences. + /// + /// ``` + /// # use clap::{Command, arg}; + /// let m = Command::new("posix") + /// .arg(arg!(--flag ... "some flag").overrides_with("flag")) + /// .get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]); + /// assert!(m.is_present("flag")); + /// ``` + /// + /// Now notice with options (which *do not* set + /// [`Arg::multiple_occurrences`]), it's as if only the last + /// occurrence happened. + /// + /// ``` + /// # use clap::{Command, arg}; + /// let m = Command::new("posix") + /// .arg(arg!(--opt "some option").overrides_with("opt")) + /// .get_matches_from(vec!["", "--opt=some", "--opt=other"]); + /// assert!(m.is_present("opt")); + /// assert_eq!(m.value_of("opt"), Some("other")); + /// ``` + /// + /// This will also work when [`Arg::multiple_values`] is enabled: + /// + /// ``` + /// # use clap::{Command, Arg}; + /// let m = Command::new("posix") + /// .arg( + /// Arg::new("opt") + /// .long("opt") + /// .takes_value(true) + /// .multiple_values(true) + /// .overrides_with("opt") + /// ) + /// .get_matches_from(vec!["", "--opt", "1", "2", "--opt", "3", "4", "5"]); + /// assert!(m.is_present("opt")); + /// assert_eq!(m.values_of("opt").unwrap().collect::>(), &["3", "4", "5"]); + /// ``` + /// + /// Just like flags, options with [`Arg::multiple_occurrences`] set + /// will ignore the "override self" setting. + /// + /// ``` + /// # use clap::{Command, arg}; + /// let m = Command::new("posix") + /// .arg(arg!(--opt ... "some option") + /// .multiple_values(true) + /// .overrides_with("opt")) + /// .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]); + /// assert!(m.is_present("opt")); + /// assert_eq!(m.values_of("opt").unwrap().collect::>(), &["first", "over", "other", "val"]); + /// ``` + #[must_use] + pub fn overrides_with(mut self, arg_id: T) -> Self { + self.overrides.push(arg_id.into()); + self + } + + /// Sets multiple mutually overridable arguments by name. + /// + /// i.e. this argument and the following argument will override each other in POSIX style + /// (whichever argument was specified at runtime **last** "wins") + /// + /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any + /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed + /// + /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with_all`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, arg}; + /// let m = Command::new("prog") + /// .arg(arg!(-f --flag "some flag") + /// .conflicts_with("color")) + /// .arg(arg!(-d --debug "other flag")) + /// .arg(arg!(-c --color "third flag") + /// .overrides_with_all(&["flag", "debug"])) + /// .get_matches_from(vec![ + /// "prog", "-f", "-d", "-c"]); + /// // ^~~~~~^~~~~~~~~ flag and debug are overridden by color + /// + /// assert!(m.is_present("color")); // even though flag conflicts with color, it's as if flag + /// // and debug were never used because they were overridden + /// // with color + /// assert!(!m.is_present("debug")); + /// assert!(!m.is_present("flag")); + /// ``` + #[must_use] + pub fn overrides_with_all(mut self, names: &[T]) -> Self { + self.overrides.extend(names.iter().map(Id::from)); + self + } +} + +/// # Reflection +impl<'help> Arg<'help> { + /// Get the name of the argument + #[inline] + pub fn get_id(&self) -> &'help str { + self.name + } + + /// Deprecated, replaced with [`Arg::get_id`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Arg::get_id`") + )] + pub fn get_name(&self) -> &'help str { + self.get_id() + } + + /// Get the help specified for this argument, if any + #[inline] + pub fn get_help(&self) -> Option<&'help str> { + self.help + } + + /// Get the long help specified for this argument, if any + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// let arg = Arg::new("foo").long_help("long help"); + /// assert_eq!(Some("long help"), arg.get_long_help()); + /// ``` + /// + #[inline] + pub fn get_long_help(&self) -> Option<&'help str> { + self.long_help + } + + /// Get the help heading specified for this argument, if any + #[inline] + pub fn get_help_heading(&self) -> Option<&'help str> { + self.help_heading.unwrap_or_default() + } + + /// Get the short option name for this argument, if any + #[inline] + pub fn get_short(&self) -> Option { + self.short + } + + /// Get visible short aliases for this argument, if any + #[inline] + pub fn get_visible_short_aliases(&self) -> Option> { + if self.short_aliases.is_empty() { + None + } else { + Some( + self.short_aliases + .iter() + .filter_map(|(c, v)| if *v { Some(c) } else { None }) + .copied() + .collect(), + ) + } + } + + /// Get *all* short aliases for this argument, if any, both visible and hidden. + #[inline] + pub fn get_all_short_aliases(&self) -> Option> { + if self.short_aliases.is_empty() { + None + } else { + Some(self.short_aliases.iter().map(|(s, _)| s).copied().collect()) + } + } + + /// Get the short option name and its visible aliases, if any + #[inline] + pub fn get_short_and_visible_aliases(&self) -> Option> { + let mut shorts = match self.short { + Some(short) => vec![short], + None => return None, + }; + if let Some(aliases) = self.get_visible_short_aliases() { + shorts.extend(aliases); + } + Some(shorts) + } + + /// Get the long option name for this argument, if any + #[inline] + pub fn get_long(&self) -> Option<&'help str> { + self.long + } + + /// Get visible aliases for this argument, if any + #[inline] + pub fn get_visible_aliases(&self) -> Option> { + if self.aliases.is_empty() { + None + } else { + Some( + self.aliases + .iter() + .filter_map(|(s, v)| if *v { Some(s) } else { None }) + .copied() + .collect(), + ) + } + } + + /// Get *all* aliases for this argument, if any, both visible and hidden. + #[inline] + pub fn get_all_aliases(&self) -> Option> { + if self.aliases.is_empty() { + None + } else { + Some(self.aliases.iter().map(|(s, _)| s).copied().collect()) + } + } + + /// Get the long option name and its visible aliases, if any + #[inline] + pub fn get_long_and_visible_aliases(&self) -> Option> { + let mut longs = match self.long { + Some(long) => vec![long], + None => return None, + }; + if let Some(aliases) = self.get_visible_aliases() { + longs.extend(aliases); + } + Some(longs) + } + + /// Deprecated, replaced with [`Arg::get_value_parser().possible_values()`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with `Arg::get_value_parser().possible_values()`" + ) + )] + pub fn get_possible_values(&self) -> Option<&[PossibleValue<'help>]> { + if self.possible_vals.is_empty() { + None + } else { + Some(&self.possible_vals) + } + } + + pub(crate) fn get_possible_values2(&self) -> Vec> { + #![allow(deprecated)] + if !self.is_takes_value_set() { + vec![] + } else if let Some(pvs) = self.get_possible_values() { + // Check old first in case the user explicitly set possible values and the derive inferred + // a `ValueParser` with some. + pvs.to_vec() + } else { + self.get_value_parser() + .possible_values() + .map(|pvs| pvs.collect()) + .unwrap_or_default() + } + } + + /// Get the names of values for this argument. + #[inline] + pub fn get_value_names(&self) -> Option<&[&'help str]> { + if self.val_names.is_empty() { + None + } else { + Some(&self.val_names) + } + } + + /// Get the number of values for this argument. + #[inline] + pub fn get_num_vals(&self) -> Option { + self.num_vals + } + + /// Get the delimiter between multiple values + #[inline] + pub fn get_value_delimiter(&self) -> Option { + self.val_delim + } + + /// Get the index of this argument, if any + #[inline] + pub fn get_index(&self) -> Option { + self.index + } + + /// Get the value hint of this argument + pub fn get_value_hint(&self) -> ValueHint { + self.value_hint.unwrap_or_else(|| { + if self.is_takes_value_set() { + let type_id = self.get_value_parser().type_id(); + if type_id == crate::parser::AnyValueId::of::() { + ValueHint::AnyPath + } else { + ValueHint::default() + } + } else { + ValueHint::default() + } + }) + } + + /// Deprecated, replaced with [`Arg::is_global_set`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Arg::is_global_set`") + )] + pub fn get_global(&self) -> bool { + self.is_global_set() + } + + /// Get the environment variable name specified for this argument, if any + /// + /// # Examples + /// + /// ```rust + /// # use std::ffi::OsStr; + /// # use clap::Arg; + /// let arg = Arg::new("foo").env("ENVIRONMENT"); + /// assert_eq!(Some(OsStr::new("ENVIRONMENT")), arg.get_env()); + /// ``` + #[cfg(feature = "env")] + pub fn get_env(&self) -> Option<&OsStr> { + self.env.as_ref().map(|x| x.0) + } + + /// Get the default values specified for this argument, if any + /// + /// # Examples + /// + /// ```rust + /// # use clap::Arg; + /// let arg = Arg::new("foo").default_value("default value"); + /// assert_eq!(&["default value"], arg.get_default_values()); + /// ``` + pub fn get_default_values(&self) -> &[&OsStr] { + &self.default_vals + } + + /// Checks whether this argument is a positional or not. + /// + /// # Examples + /// + /// ``` + /// # use clap::Arg; + /// let arg = Arg::new("foo"); + /// assert_eq!(true, arg.is_positional()); + /// + /// let arg = Arg::new("foo").long("foo"); + /// assert_eq!(false, arg.is_positional()); + /// ``` + pub fn is_positional(&self) -> bool { + self.long.is_none() && self.short.is_none() + } + + /// Reports whether [`Arg::required`] is set + pub fn is_required_set(&self) -> bool { + self.is_set(ArgSettings::Required) + } + + /// Report whether [`Arg::multiple_values`] is set + pub fn is_multiple_values_set(&self) -> bool { + self.is_set(ArgSettings::MultipleValues) + } + + /// [`Arg::multiple_occurrences`] is going away ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "`multiple_occurrences` away (Issue #3772)") + )] + pub fn is_multiple_occurrences_set(&self) -> bool { + self.is_set(ArgSettings::MultipleOccurrences) + } + + /// Report whether [`Arg::is_takes_value_set`] is set + pub fn is_takes_value_set(&self) -> bool { + self.is_set(ArgSettings::TakesValue) + } + + /// Report whether [`Arg::allow_hyphen_values`] is set + pub fn is_allow_hyphen_values_set(&self) -> bool { + self.is_set(ArgSettings::AllowHyphenValues) + } + + /// Deprecated, replaced with [`Arg::get_value_parser()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::get_value_parser()`") + )] + pub fn is_forbid_empty_values_set(&self) -> bool { + self.is_set(ArgSettings::ForbidEmptyValues) + } + + /// Deprecated, replaced with [`Arg::get_value_parser()` + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::get_value_parser()`") + )] + pub fn is_allow_invalid_utf8_set(&self) -> bool { + self.is_set(ArgSettings::AllowInvalidUtf8) + } + + /// Behavior when parsing the argument + pub fn get_action(&self) -> &super::ArgAction { + const DEFAULT: super::ArgAction = super::ArgAction::StoreValue; + self.action.as_ref().unwrap_or(&DEFAULT) + } + + /// Configured parser for argument values + /// + /// # Example + /// + /// ```rust + /// let cmd = clap::Command::new("raw") + /// .arg( + /// clap::Arg::new("port") + /// .value_parser(clap::value_parser!(usize)) + /// ); + /// let value_parser = cmd.get_arguments() + /// .find(|a| a.get_id() == "port").unwrap() + /// .get_value_parser(); + /// println!("{:?}", value_parser); + /// ``` + pub fn get_value_parser(&self) -> &super::ValueParser { + if let Some(value_parser) = self.value_parser.as_ref() { + value_parser + } else if self.is_allow_invalid_utf8_set() { + static DEFAULT: super::ValueParser = super::ValueParser::os_string(); + &DEFAULT + } else { + static DEFAULT: super::ValueParser = super::ValueParser::string(); + &DEFAULT + } + } + + /// Report whether [`Arg::global`] is set + pub fn is_global_set(&self) -> bool { + self.is_set(ArgSettings::Global) + } + + /// Report whether [`Arg::next_line_help`] is set + pub fn is_next_line_help_set(&self) -> bool { + self.is_set(ArgSettings::NextLineHelp) + } + + /// Report whether [`Arg::hide`] is set + pub fn is_hide_set(&self) -> bool { + self.is_set(ArgSettings::Hidden) + } + + /// Report whether [`Arg::hide_default_value`] is set + pub fn is_hide_default_value_set(&self) -> bool { + self.is_set(ArgSettings::HideDefaultValue) + } + + /// Report whether [`Arg::hide_possible_values`] is set + pub fn is_hide_possible_values_set(&self) -> bool { + self.is_set(ArgSettings::HidePossibleValues) + } + + /// Report whether [`Arg::hide_env`] is set + #[cfg(feature = "env")] + pub fn is_hide_env_set(&self) -> bool { + self.is_set(ArgSettings::HideEnv) + } + + /// Report whether [`Arg::hide_env_values`] is set + #[cfg(feature = "env")] + pub fn is_hide_env_values_set(&self) -> bool { + self.is_set(ArgSettings::HideEnvValues) + } + + /// Report whether [`Arg::hide_short_help`] is set + pub fn is_hide_short_help_set(&self) -> bool { + self.is_set(ArgSettings::HiddenShortHelp) + } + + /// Report whether [`Arg::hide_long_help`] is set + pub fn is_hide_long_help_set(&self) -> bool { + self.is_set(ArgSettings::HiddenLongHelp) + } + + /// Report whether [`Arg::use_value_delimiter`] is set + pub fn is_use_value_delimiter_set(&self) -> bool { + self.is_set(ArgSettings::UseValueDelimiter) + } + + /// Report whether [`Arg::require_value_delimiter`] is set + pub fn is_require_value_delimiter_set(&self) -> bool { + self.is_set(ArgSettings::RequireDelimiter) + } + + /// Report whether [`Arg::require_equals`] is set + pub fn is_require_equals_set(&self) -> bool { + self.is_set(ArgSettings::RequireEquals) + } + + /// Reports whether [`Arg::exclusive`] is set + pub fn is_exclusive_set(&self) -> bool { + self.is_set(ArgSettings::Exclusive) + } + + /// Reports whether [`Arg::last`] is set + pub fn is_last_set(&self) -> bool { + self.is_set(ArgSettings::Last) + } + + /// Reports whether [`Arg::ignore_case`] is set + pub fn is_ignore_case_set(&self) -> bool { + self.is_set(ArgSettings::IgnoreCase) + } +} + +/// # Deprecated +impl<'help> Arg<'help> { + /// Deprecated, replaced with [`Arg::new`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::new`") + )] + #[doc(hidden)] + pub fn with_name>(n: S) -> Self { + Self::new(n) + } + + /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? + #[cfg(feature = "yaml")] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" + ) + )] + #[doc(hidden)] + pub fn from_yaml(y: &'help Yaml) -> Self { + #![allow(deprecated)] + let yaml_file_hash = y.as_hash().expect("YAML file must be a hash"); + // We WANT this to panic on error...so expect() is good. + let (name_yaml, yaml) = yaml_file_hash + .iter() + .next() + .expect("There must be one arg in the YAML file"); + let name_str = name_yaml.as_str().expect("Arg name must be a string"); + let mut a = Arg::new(name_str); + + for (k, v) in yaml.as_hash().expect("Arg must be a hash") { + a = match k.as_str().expect("Arg fields must be strings") { + "short" => yaml_to_char!(a, v, short), + "long" => yaml_to_str!(a, v, long), + "aliases" => yaml_vec_or_str!(a, v, alias), + "help" => yaml_to_str!(a, v, help), + "long_help" => yaml_to_str!(a, v, long_help), + "required" => yaml_to_bool!(a, v, required), + "required_if" => yaml_tuple2!(a, v, required_if_eq), + "required_ifs" => yaml_tuple2!(a, v, required_if_eq), + "takes_value" => yaml_to_bool!(a, v, takes_value), + "index" => yaml_to_usize!(a, v, index), + "global" => yaml_to_bool!(a, v, global), + "multiple" => yaml_to_bool!(a, v, multiple), + "hidden" => yaml_to_bool!(a, v, hide), + "next_line_help" => yaml_to_bool!(a, v, next_line_help), + "group" => yaml_to_str!(a, v, group), + "number_of_values" => yaml_to_usize!(a, v, number_of_values), + "max_values" => yaml_to_usize!(a, v, max_values), + "min_values" => yaml_to_usize!(a, v, min_values), + "value_name" => yaml_to_str!(a, v, value_name), + "use_delimiter" => yaml_to_bool!(a, v, use_delimiter), + "allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values), + "last" => yaml_to_bool!(a, v, last), + "require_delimiter" => yaml_to_bool!(a, v, require_delimiter), + "value_delimiter" => yaml_to_char!(a, v, value_delimiter), + "required_unless" => yaml_to_str!(a, v, required_unless_present), + "display_order" => yaml_to_usize!(a, v, display_order), + "default_value" => yaml_to_str!(a, v, default_value), + "default_value_if" => yaml_tuple3!(a, v, default_value_if), + "default_value_ifs" => yaml_tuple3!(a, v, default_value_if), + #[cfg(feature = "env")] + "env" => yaml_to_str!(a, v, env), + "value_names" => yaml_vec_or_str!(a, v, value_name), + "groups" => yaml_vec_or_str!(a, v, group), + "requires" => yaml_vec_or_str!(a, v, requires), + "requires_if" => yaml_tuple2!(a, v, requires_if), + "requires_ifs" => yaml_tuple2!(a, v, requires_if), + "conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with), + "overrides_with" => yaml_to_str!(a, v, overrides_with), + "possible_values" => yaml_vec_or_str!(a, v, possible_value), + "case_insensitive" => yaml_to_bool!(a, v, ignore_case), + "required_unless_one" => yaml_vec!(a, v, required_unless_present_any), + "required_unless_all" => yaml_vec!(a, v, required_unless_present_all), + s => { + panic!( + "Unknown setting '{}' in YAML file for arg '{}'", + s, name_str + ) + } + } + } + + a + } + + /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!]. + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!") + )] + #[doc(hidden)] + pub fn from_usage(u: &'help str) -> Self { + UsageParser::from_usage(u).parse() + } + + /// Deprecated, replaced with [`Arg::required_unless_present`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::required_unless_present`") + )] + #[doc(hidden)] + #[must_use] + pub fn required_unless(self, arg_id: T) -> Self { + self.required_unless_present(arg_id) + } + + /// Deprecated, replaced with [`Arg::required_unless_present_all`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Arg::required_unless_present_all`" + ) + )] + #[doc(hidden)] + #[must_use] + pub fn required_unless_all(self, names: I) -> Self + where + I: IntoIterator, + T: Key, + { + self.required_unless_present_all(names) + } + + /// Deprecated, replaced with [`Arg::required_unless_present_any`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Arg::required_unless_present_any`" + ) + )] + #[doc(hidden)] + #[must_use] + pub fn required_unless_one(self, names: I) -> Self + where + I: IntoIterator, + T: Key, + { + self.required_unless_present_any(names) + } + + /// Deprecated, replaced with [`Arg::required_if_eq`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq`") + )] + #[doc(hidden)] + #[must_use] + pub fn required_if(self, arg_id: T, val: &'help str) -> Self { + self.required_if_eq(arg_id, val) + } + + /// Deprecated, replaced with [`Arg::required_if_eq_any`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq_any`") + )] + #[doc(hidden)] + #[must_use] + pub fn required_ifs(self, ifs: &[(T, &'help str)]) -> Self { + self.required_if_eq_any(ifs) + } + + /// Deprecated, replaced with [`Arg::hide`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::hide`") + )] + #[doc(hidden)] + #[inline] + #[must_use] + pub fn hidden(self, yes: bool) -> Self { + self.hide(yes) + } + + /// Deprecated, replaced with [`Arg::ignore_case`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::ignore_case`") + )] + #[doc(hidden)] + #[inline] + #[must_use] + pub fn case_insensitive(self, yes: bool) -> Self { + self.ignore_case(yes) + } + + /// Deprecated, replaced with [`Arg::forbid_empty_values`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::forbid_empty_values`") + )] + #[doc(hidden)] + #[must_use] + pub fn empty_values(self, yes: bool) -> Self { + self.forbid_empty_values(!yes) + } + + /// Deprecated, replaced with [`Arg::multiple_occurrences`] (most likely what you want) and + /// [`Arg::multiple_values`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Split into `Arg::multiple_occurrences` (most likely what you want) and `Arg::multiple_values`" + ) + )] + #[doc(hidden)] + #[must_use] + pub fn multiple(self, yes: bool) -> Self { + self.multiple_occurrences(yes).multiple_values(yes) + } + + /// Deprecated, replaced with [`Arg::hide_short_help`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::hide_short_help`") + )] + #[doc(hidden)] + #[inline] + #[must_use] + pub fn hidden_short_help(self, yes: bool) -> Self { + self.hide_short_help(yes) + } + + /// Deprecated, replaced with [`Arg::hide_long_help`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::hide_long_help`") + )] + #[doc(hidden)] + #[inline] + #[must_use] + pub fn hidden_long_help(self, yes: bool) -> Self { + self.hide_long_help(yes) + } + + /// Deprecated, replaced with [`Arg::setting`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::setting`") + )] + #[doc(hidden)] + #[must_use] + pub fn set(self, s: ArgSettings) -> Self { + self.setting(s) + } + + /// Deprecated, replaced with [`Arg::unset_setting`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Arg::unset_setting`") + )] + #[doc(hidden)] + #[must_use] + pub fn unset(self, s: ArgSettings) -> Self { + self.unset_setting(s) + } +} + +/// # Internally used only +impl<'help> Arg<'help> { + pub(crate) fn _build(&mut self) { + if self.is_positional() { + self.settings.set(ArgSettings::TakesValue); + } + if let Some(action) = self.action.as_ref() { + if let Some(default_value) = action.default_value() { + if self.default_vals.is_empty() { + self.default_vals = vec![default_value]; + } + } + if action.takes_values() { + self.settings.set(ArgSettings::TakesValue); + } else { + self.settings.unset(ArgSettings::TakesValue); + } + match action { + ArgAction::StoreValue + | ArgAction::IncOccurrence + | ArgAction::Help + | ArgAction::Version => {} + ArgAction::Set + | ArgAction::Append + | ArgAction::SetTrue + | ArgAction::SetFalse + | ArgAction::Count => { + if !self.is_positional() { + self.settings.set(ArgSettings::MultipleOccurrences); + } + } + } + } + + if self.value_parser.is_none() { + if let Some(default) = self.action.as_ref().and_then(|a| a.default_value_parser()) { + self.value_parser = Some(default); + } else if self.is_allow_invalid_utf8_set() { + self.value_parser = Some(super::ValueParser::os_string()); + } else { + self.value_parser = Some(super::ValueParser::string()); + } + } + + if (self.is_use_value_delimiter_set() || self.is_require_value_delimiter_set()) + && self.val_delim.is_none() + { + self.val_delim = Some(','); + } + + let val_names_len = self.val_names.len(); + + if val_names_len > 1 { + self.settings.set(ArgSettings::MultipleValues); + + if self.num_vals.is_none() { + self.num_vals = Some(val_names_len); + } + } + + let self_id = self.id.clone(); + if self.is_positional() || self.is_multiple_occurrences_set() { + // Remove self-overrides where they don't make sense. + // + // We can evaluate switching this to a debug assert at a later time (though it will + // require changing propagation of `AllArgsOverrideSelf`). Being conservative for now + // due to where we are at in the release. + self.overrides.retain(|e| *e != self_id); + } + } + + pub(crate) fn generated(mut self) -> Self { + self.provider = ArgProvider::Generated; + self + } + + pub(crate) fn longest_filter(&self) -> bool { + self.is_takes_value_set() || self.long.is_some() || self.short.is_none() + } + + // Used for positionals when printing + pub(crate) fn multiple_str(&self) -> &str { + let mult_vals = self.val_names.len() > 1; + if (self.is_multiple_values_set() || self.is_multiple_occurrences_set()) && !mult_vals { + "..." + } else { + "" + } + } + + // Used for positionals when printing + pub(crate) fn name_no_brackets(&self) -> Cow { + debug!("Arg::name_no_brackets:{}", self.name); + let delim = if self.is_require_value_delimiter_set() { + self.val_delim.expect(INTERNAL_ERROR_MSG) + } else { + ' ' + } + .to_string(); + if !self.val_names.is_empty() { + debug!("Arg::name_no_brackets: val_names={:#?}", self.val_names); + + if self.val_names.len() > 1 { + Cow::Owned( + self.val_names + .iter() + .map(|n| format!("<{}>", n)) + .collect::>() + .join(&*delim), + ) + } else { + Cow::Borrowed(self.val_names.get(0).expect(INTERNAL_ERROR_MSG)) + } + } else { + debug!("Arg::name_no_brackets: just name"); + Cow::Borrowed(self.name) + } + } + + /// Either multiple values or occurrences + pub(crate) fn is_multiple(&self) -> bool { + self.is_multiple_values_set() | self.is_multiple_occurrences_set() + } + + pub(crate) fn get_display_order(&self) -> usize { + self.disp_ord.get_explicit() + } +} + +impl<'help> From<&'_ Arg<'help>> for Arg<'help> { + fn from(a: &Arg<'help>) -> Self { + a.clone() + } +} + +impl<'help> PartialEq for Arg<'help> { + fn eq(&self, other: &Arg<'help>) -> bool { + self.name == other.name + } +} + +impl<'help> PartialOrd for Arg<'help> { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl<'help> Ord for Arg<'help> { + fn cmp(&self, other: &Arg) -> Ordering { + self.name.cmp(other.name) + } +} + +impl<'help> Eq for Arg<'help> {} + +impl<'help> Display for Arg<'help> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // Write the name such --long or -l + if let Some(l) = self.long { + write!(f, "--{}", l)?; + } else if let Some(s) = self.short { + write!(f, "-{}", s)?; + } + let mut need_closing_bracket = false; + if !self.is_positional() && self.is_takes_value_set() { + let is_optional_val = self.min_vals == Some(0); + let sep = if self.is_require_equals_set() { + if is_optional_val { + need_closing_bracket = true; + "[=" + } else { + "=" + } + } else if is_optional_val { + need_closing_bracket = true; + " [" + } else { + " " + }; + f.write_str(sep)?; + } + if self.is_takes_value_set() || self.is_positional() { + display_arg_val(self, |s, _| f.write_str(s))?; + } + if need_closing_bracket { + f.write_str("]")?; + } + + Ok(()) + } +} + +impl<'help> fmt::Debug for Arg<'help> { + fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { + let mut ds = f.debug_struct("Arg"); + + #[allow(unused_mut)] + let mut ds = ds + .field("id", &self.id) + .field("provider", &self.provider) + .field("name", &self.name) + .field("help", &self.help) + .field("long_help", &self.long_help) + .field("action", &self.action) + .field("value_parser", &self.value_parser) + .field("blacklist", &self.blacklist) + .field("settings", &self.settings) + .field("overrides", &self.overrides) + .field("groups", &self.groups) + .field("requires", &self.requires) + .field("r_ifs", &self.r_ifs) + .field("r_unless", &self.r_unless) + .field("short", &self.short) + .field("long", &self.long) + .field("aliases", &self.aliases) + .field("short_aliases", &self.short_aliases) + .field("disp_ord", &self.disp_ord) + .field("possible_vals", &self.possible_vals) + .field("val_names", &self.val_names) + .field("num_vals", &self.num_vals) + .field("max_vals", &self.max_vals) + .field("min_vals", &self.min_vals) + .field( + "validator", + &self.validator.as_ref().map_or("None", |_| "Some(FnMut)"), + ) + .field( + "validator_os", + &self.validator_os.as_ref().map_or("None", |_| "Some(FnMut)"), + ) + .field("val_delim", &self.val_delim) + .field("default_vals", &self.default_vals) + .field("default_vals_ifs", &self.default_vals_ifs) + .field("terminator", &self.terminator) + .field("index", &self.index) + .field("help_heading", &self.help_heading) + .field("value_hint", &self.value_hint) + .field("default_missing_vals", &self.default_missing_vals); + + #[cfg(feature = "env")] + { + ds = ds.field("env", &self.env); + } + + ds.finish() + } +} + +type Validator<'a> = dyn FnMut(&str) -> Result<(), Box> + Send + 'a; +type ValidatorOs<'a> = dyn FnMut(&OsStr) -> Result<(), Box> + Send + 'a; + +#[derive(Debug, Clone, Eq, PartialEq)] +pub(crate) enum ArgProvider { + Generated, + GeneratedMutated, + User, +} + +impl Default for ArgProvider { + fn default() -> Self { + ArgProvider::User + } +} + +/// Write the values such as +pub(crate) fn display_arg_val(arg: &Arg, mut write: F) -> Result<(), E> +where + F: FnMut(&str, bool) -> Result, +{ + let mult_val = arg.is_multiple_values_set(); + let mult_occ = arg.is_multiple_occurrences_set(); + let delim = if arg.is_require_value_delimiter_set() { + arg.val_delim.expect(INTERNAL_ERROR_MSG) + } else { + ' ' + } + .to_string(); + if !arg.val_names.is_empty() { + // If have val_name. + match (arg.val_names.len(), arg.num_vals) { + (1, Some(num_vals)) => { + // If single value name with multiple num_of_vals, display all + // the values with the single value name. + let arg_name = format!("<{}>", arg.val_names.get(0).unwrap()); + for n in 1..=num_vals { + write(&arg_name, true)?; + if n != num_vals { + write(&delim, false)?; + } + } + } + (num_val_names, _) => { + // If multiple value names, display them sequentially(ignore num of vals). + let mut it = arg.val_names.iter().peekable(); + while let Some(val) = it.next() { + write(&format!("<{}>", val), true)?; + if it.peek().is_some() { + write(&delim, false)?; + } + } + if (num_val_names == 1 && mult_val) + || (arg.is_positional() && mult_occ) + || num_val_names < arg.num_vals.unwrap_or(0) + { + write("...", true)?; + } + } + } + } else if let Some(num_vals) = arg.num_vals { + // If number_of_values is specified, display the value multiple times. + let arg_name = format!("<{}>", arg.name); + for n in 1..=num_vals { + write(&arg_name, true)?; + if n != num_vals { + write(&delim, false)?; + } + } + } else if arg.is_positional() { + // Value of positional argument with no num_vals and val_names. + write(&format!("<{}>", arg.name), true)?; + + if mult_val || mult_occ { + write("...", true)?; + } + } else { + // value of flag argument with no num_vals and val_names. + write(&format!("<{}>", arg.name), true)?; + if mult_val { + write("...", true)?; + } + } + Ok(()) +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub(crate) enum DisplayOrder { + None, + Implicit(usize), + Explicit(usize), +} + +impl DisplayOrder { + pub(crate) fn set_explicit(&mut self, explicit: usize) { + *self = Self::Explicit(explicit) + } + + pub(crate) fn set_implicit(&mut self, implicit: usize) { + *self = (*self).max(Self::Implicit(implicit)) + } + + pub(crate) fn make_explicit(&mut self) { + match *self { + Self::None | Self::Explicit(_) => {} + Self::Implicit(disp) => self.set_explicit(disp), + } + } + + pub(crate) fn get_explicit(self) -> usize { + match self { + Self::None | Self::Implicit(_) => 999, + Self::Explicit(disp) => disp, + } + } +} + +impl Default for DisplayOrder { + fn default() -> Self { + Self::None + } +} + +// Flags +#[cfg(test)] +mod test { + use super::Arg; + + #[test] + fn flag_display() { + let mut f = Arg::new("flg").multiple_occurrences(true); + f.long = Some("flag"); + + assert_eq!(f.to_string(), "--flag"); + + let mut f2 = Arg::new("flg"); + f2.short = Some('f'); + + assert_eq!(f2.to_string(), "-f"); + } + + #[test] + fn flag_display_single_alias() { + let mut f = Arg::new("flg"); + f.long = Some("flag"); + f.aliases = vec![("als", true)]; + + assert_eq!(f.to_string(), "--flag") + } + + #[test] + fn flag_display_multiple_aliases() { + let mut f = Arg::new("flg"); + f.short = Some('f'); + f.aliases = vec![ + ("alias_not_visible", false), + ("f2", true), + ("f3", true), + ("f4", true), + ]; + assert_eq!(f.to_string(), "-f"); + } + + #[test] + fn flag_display_single_short_alias() { + let mut f = Arg::new("flg"); + f.short = Some('a'); + f.short_aliases = vec![('b', true)]; + + assert_eq!(f.to_string(), "-a") + } + + #[test] + fn flag_display_multiple_short_aliases() { + let mut f = Arg::new("flg"); + f.short = Some('a'); + f.short_aliases = vec![('b', false), ('c', true), ('d', true), ('e', true)]; + assert_eq!(f.to_string(), "-a"); + } + + // Options + + #[test] + fn option_display_multiple_occurrences() { + let o = Arg::new("opt") + .long("option") + .takes_value(true) + .multiple_occurrences(true); + + assert_eq!(o.to_string(), "--option "); + } + + #[test] + fn option_display_multiple_values() { + let o = Arg::new("opt") + .long("option") + .takes_value(true) + .multiple_values(true); + + assert_eq!(o.to_string(), "--option ..."); + } + + #[test] + fn option_display2() { + let o2 = Arg::new("opt").short('o').value_names(&["file", "name"]); + + assert_eq!(o2.to_string(), "-o "); + } + + #[test] + fn option_display3() { + let o2 = Arg::new("opt") + .short('o') + .takes_value(true) + .multiple_values(true) + .value_names(&["file", "name"]); + + assert_eq!(o2.to_string(), "-o "); + } + + #[test] + fn option_display_single_alias() { + let o = Arg::new("opt") + .takes_value(true) + .long("option") + .visible_alias("als"); + + assert_eq!(o.to_string(), "--option "); + } + + #[test] + fn option_display_multiple_aliases() { + let o = Arg::new("opt") + .long("option") + .takes_value(true) + .visible_aliases(&["als2", "als3", "als4"]) + .alias("als_not_visible"); + + assert_eq!(o.to_string(), "--option "); + } + + #[test] + fn option_display_single_short_alias() { + let o = Arg::new("opt") + .takes_value(true) + .short('a') + .visible_short_alias('b'); + + assert_eq!(o.to_string(), "-a "); + } + + #[test] + fn option_display_multiple_short_aliases() { + let o = Arg::new("opt") + .short('a') + .takes_value(true) + .visible_short_aliases(&['b', 'c', 'd']) + .short_alias('e'); + + assert_eq!(o.to_string(), "-a "); + } + + // Positionals + + #[test] + fn positional_display_multiple_values() { + let p = Arg::new("pos") + .index(1) + .takes_value(true) + .multiple_values(true); + + assert_eq!(p.to_string(), "..."); + } + + #[test] + fn positional_display_multiple_occurrences() { + let p = Arg::new("pos") + .index(1) + .takes_value(true) + .multiple_occurrences(true); + + assert_eq!(p.to_string(), "..."); + } + + #[test] + fn positional_display_required() { + let p2 = Arg::new("pos").index(1).required(true); + + assert_eq!(p2.to_string(), ""); + } + + #[test] + fn positional_display_val_names() { + let p2 = Arg::new("pos").index(1).value_names(&["file1", "file2"]); + + assert_eq!(p2.to_string(), " "); + } + + #[test] + fn positional_display_val_names_req() { + let p2 = Arg::new("pos") + .index(1) + .required(true) + .value_names(&["file1", "file2"]); + + assert_eq!(p2.to_string(), " "); + } +} diff --git a/vendor/clap-3.2.20/src/builder/arg_group.rs b/vendor/clap-3.2.20/src/builder/arg_group.rs new file mode 100644 index 000000000..0fe317109 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/arg_group.rs @@ -0,0 +1,633 @@ +// Internal +use crate::util::{Id, Key}; + +#[cfg(feature = "yaml")] +use yaml_rust::Yaml; + +/// Family of related [arguments]. +/// +/// By placing arguments in a logical group, you can create easier requirement and +/// exclusion rules instead of having to list each argument individually, or when you want a rule +/// to apply "any but not all" arguments. +/// +/// For instance, you can make an entire `ArgGroup` required. If [`ArgGroup::multiple(true)`] is +/// set, this means that at least one argument from that group must be present. If +/// [`ArgGroup::multiple(false)`] is set (the default), one and *only* one must be present. +/// +/// You can also do things such as name an entire `ArgGroup` as a [conflict] or [requirement] for +/// another argument, meaning any of the arguments that belong to that group will cause a failure +/// if present, or must be present respectively. +/// +/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be +/// present out of a given set. Imagine that you had multiple arguments, and you want one of them +/// to be required, but making all of them required isn't feasible because perhaps they conflict +/// with each other. For example, lets say that you were building an application where one could +/// set a given version number by supplying a string with an option argument, i.e. +/// `--set-ver v1.2.3`, you also wanted to support automatically using a previous version number +/// and simply incrementing one of the three numbers. So you create three flags `--major`, +/// `--minor`, and `--patch`. All of these arguments shouldn't be used at one time but you want to +/// specify that *at least one* of them is used. For this, you can create a group. +/// +/// Finally, you may use `ArgGroup`s to pull a value from a group of arguments when you don't care +/// exactly which argument was actually used at runtime. +/// +/// # Examples +/// +/// The following example demonstrates using an `ArgGroup` to ensure that one, and only one, of +/// the arguments from the specified group is present at runtime. +/// +/// ```rust +/// # use clap::{Command, arg, ArgGroup, ErrorKind}; +/// let result = Command::new("cmd") +/// .arg(arg!(--"set-ver" "set the version manually").required(false)) +/// .arg(arg!(--major "auto increase major")) +/// .arg(arg!(--minor "auto increase minor")) +/// .arg(arg!(--patch "auto increase patch")) +/// .group(ArgGroup::new("vers") +/// .args(&["set-ver", "major", "minor", "patch"]) +/// .required(true)) +/// .try_get_matches_from(vec!["cmd", "--major", "--patch"]); +/// // Because we used two args in the group it's an error +/// assert!(result.is_err()); +/// let err = result.unwrap_err(); +/// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); +/// ``` +/// This next example shows a passing parse of the same scenario +/// +/// ```rust +/// # use clap::{Command, arg, ArgGroup}; +/// let result = Command::new("cmd") +/// .arg(arg!(--"set-ver" "set the version manually").required(false)) +/// .arg(arg!(--major "auto increase major")) +/// .arg(arg!(--minor "auto increase minor")) +/// .arg(arg!(--patch "auto increase patch")) +/// .group(ArgGroup::new("vers") +/// .args(&["set-ver", "major", "minor","patch"]) +/// .required(true)) +/// .try_get_matches_from(vec!["cmd", "--major"]); +/// assert!(result.is_ok()); +/// let matches = result.unwrap(); +/// // We may not know which of the args was used, so we can test for the group... +/// assert!(matches.contains_id("vers")); +/// // we could also alternatively check each arg individually (not shown here) +/// ``` +/// [`ArgGroup::multiple(true)`]: ArgGroup::multiple() +/// +/// [`ArgGroup::multiple(false)`]: ArgGroup::multiple() +/// [arguments]: crate::Arg +/// [conflict]: crate::Arg::conflicts_with() +/// [requirement]: crate::Arg::requires() +#[derive(Default, Debug, PartialEq, Eq)] +pub struct ArgGroup<'help> { + pub(crate) id: Id, + pub(crate) name: &'help str, + pub(crate) args: Vec, + pub(crate) required: bool, + pub(crate) requires: Vec, + pub(crate) conflicts: Vec, + pub(crate) multiple: bool, +} + +impl<'help> ArgGroup<'help> { + pub(crate) fn with_id(id: Id) -> Self { + ArgGroup { + id, + ..ArgGroup::default() + } + } + + /// Create a `ArgGroup` using a unique name. + /// + /// The name will be used to get values from the group or refer to the group inside of conflict + /// and requirement rules. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ArgGroup}; + /// ArgGroup::new("config") + /// # ; + /// ``` + pub fn new>(n: S) -> Self { + ArgGroup::default().id(n) + } + + /// Sets the group name. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ArgGroup}; + /// ArgGroup::default().name("config") + /// # ; + /// ``` + #[must_use] + pub fn id>(mut self, n: S) -> Self { + self.name = n.into(); + self.id = Id::from(self.name); + self + } + + /// Deprecated, replaced with [`ArgGroup::id`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `ArgGroup::id`") + )] + pub fn name>(self, n: S) -> Self { + self.id(n) + } + + /// Adds an [argument] to this group by name + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .group(ArgGroup::new("req_flags") + /// .arg("flag") + /// .arg("color")) + /// .get_matches_from(vec!["myprog", "-f"]); + /// // maybe we don't know which of the two flags was used... + /// assert!(m.contains_id("req_flags")); + /// // but we can also check individually if needed + /// assert!(m.contains_id("flag")); + /// ``` + /// [argument]: crate::Arg + #[must_use] + pub fn arg(mut self, arg_id: T) -> Self { + self.args.push(arg_id.into()); + self + } + + /// Adds multiple [arguments] to this group by name + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"])) + /// .get_matches_from(vec!["myprog", "-f"]); + /// // maybe we don't know which of the two flags was used... + /// assert!(m.contains_id("req_flags")); + /// // but we can also check individually if needed + /// assert!(m.contains_id("flag")); + /// ``` + /// [arguments]: crate::Arg + #[must_use] + pub fn args(mut self, ns: &[T]) -> Self { + for n in ns { + self = self.arg(n); + } + self + } + + /// Allows more than one of the [`Arg`]s in this group to be used. (Default: `false`) + /// + /// # Examples + /// + /// Notice in this example we use *both* the `-f` and `-c` flags which are both part of the + /// group + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"]) + /// .multiple(true)) + /// .get_matches_from(vec!["myprog", "-f", "-c"]); + /// // maybe we don't know which of the two flags was used... + /// assert!(m.contains_id("req_flags")); + /// ``` + /// In this next example, we show the default behavior (i.e. `multiple(false)) which will throw + /// an error if more than one of the args in the group was used. + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; + /// let result = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"])) + /// .try_get_matches_from(vec!["myprog", "-f", "-c"]); + /// // Because we used both args in the group it's an error + /// assert!(result.is_err()); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); + /// ``` + /// + /// [`Arg`]: crate::Arg + #[inline] + #[must_use] + pub fn multiple(mut self, yes: bool) -> Self { + self.multiple = yes; + self + } + + /// Require an argument from the group to be present when parsing. + /// + /// This is unless conflicting with another argument. A required group will be displayed in + /// the usage string of the application in the format ``. + /// + /// **NOTE:** This setting only applies to the current [`Command`] / [`Subcommand`]s, and not + /// globally. + /// + /// **NOTE:** By default, [`ArgGroup::multiple`] is set to `false` which when combined with + /// `ArgGroup::required(true)` states, "One and *only one* arg must be used from this group. + /// Use of more than one arg is an error." Vice setting `ArgGroup::multiple(true)` which + /// states, '*At least* one arg from this group must be used. Using multiple is OK." + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; + /// let result = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"]) + /// .required(true)) + /// .try_get_matches_from(vec!["myprog"]); + /// // Because we didn't use any of the args in the group, it's an error + /// assert!(result.is_err()); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// + /// [`Subcommand`]: crate::Subcommand + /// [`ArgGroup::multiple`]: ArgGroup::multiple() + /// [`Command`]: crate::Command + #[inline] + #[must_use] + pub fn required(mut self, yes: bool) -> Self { + self.required = yes; + self + } + + /// Specify an argument or group that must be present when this group is. + /// + /// This is not to be confused with a [required group]. Requirement rules function just like + /// [argument requirement rules], you can name other arguments or groups that must be present + /// when any one of the arguments from this group is used. + /// + /// **NOTE:** The name provided may be an argument or group name + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; + /// let result = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .arg(Arg::new("debug") + /// .short('d')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"]) + /// .requires("debug")) + /// .try_get_matches_from(vec!["myprog", "-c"]); + /// // because we used an arg from the group, and the group requires "-d" to be used, it's an + /// // error + /// assert!(result.is_err()); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [required group]: ArgGroup::required() + /// [argument requirement rules]: crate::Arg::requires() + #[must_use] + pub fn requires(mut self, id: T) -> Self { + self.requires.push(id.into()); + self + } + + /// Specify arguments or groups that must be present when this group is. + /// + /// This is not to be confused with a [required group]. Requirement rules function just like + /// [argument requirement rules], you can name other arguments or groups that must be present + /// when one of the arguments from this group is used. + /// + /// **NOTE:** The names provided may be an argument or group name + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; + /// let result = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .arg(Arg::new("debug") + /// .short('d')) + /// .arg(Arg::new("verb") + /// .short('v')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"]) + /// .requires_all(&["debug", "verb"])) + /// .try_get_matches_from(vec!["myprog", "-c", "-d"]); + /// // because we used an arg from the group, and the group requires "-d" and "-v" to be used, + /// // yet we only used "-d" it's an error + /// assert!(result.is_err()); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); + /// ``` + /// [required group]: ArgGroup::required() + /// [argument requirement rules]: crate::Arg::requires_all() + #[must_use] + pub fn requires_all(mut self, ns: &[&'help str]) -> Self { + for n in ns { + self = self.requires(n); + } + self + } + + /// Specify an argument or group that must **not** be present when this group is. + /// + /// Exclusion (aka conflict) rules function just like [argument exclusion rules], you can name + /// other arguments or groups that must *not* be present when one of the arguments from this + /// group are used. + /// + /// **NOTE:** The name provided may be an argument, or group name + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; + /// let result = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .arg(Arg::new("debug") + /// .short('d')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"]) + /// .conflicts_with("debug")) + /// .try_get_matches_from(vec!["myprog", "-c", "-d"]); + /// // because we used an arg from the group, and the group conflicts with "-d", it's an error + /// assert!(result.is_err()); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); + /// ``` + /// [argument exclusion rules]: crate::Arg::conflicts_with() + #[must_use] + pub fn conflicts_with(mut self, id: T) -> Self { + self.conflicts.push(id.into()); + self + } + + /// Specify arguments or groups that must **not** be present when this group is. + /// + /// Exclusion rules function just like [argument exclusion rules], you can name other arguments + /// or groups that must *not* be present when one of the arguments from this group are used. + /// + /// **NOTE:** The names provided may be an argument, or group name + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; + /// let result = Command::new("myprog") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("color") + /// .short('c')) + /// .arg(Arg::new("debug") + /// .short('d')) + /// .arg(Arg::new("verb") + /// .short('v')) + /// .group(ArgGroup::new("req_flags") + /// .args(&["flag", "color"]) + /// .conflicts_with_all(&["debug", "verb"])) + /// .try_get_matches_from(vec!["myprog", "-c", "-v"]); + /// // because we used an arg from the group, and the group conflicts with either "-v" or "-d" + /// // it's an error + /// assert!(result.is_err()); + /// let err = result.unwrap_err(); + /// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); + /// ``` + /// + /// [argument exclusion rules]: crate::Arg::conflicts_with_all() + #[must_use] + pub fn conflicts_with_all(mut self, ns: &[&'help str]) -> Self { + for n in ns { + self = self.conflicts_with(n); + } + self + } + + /// Deprecated, replaced with [`ArgGroup::new`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ArgGroup::new`") + )] + #[doc(hidden)] + pub fn with_name>(n: S) -> Self { + Self::new(n) + } + + /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? + #[cfg(feature = "yaml")] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Maybe clap::Parser would fit your use case? (Issue #3087)" + ) + )] + #[doc(hidden)] + pub fn from_yaml(yaml: &'help Yaml) -> Self { + Self::from(yaml) + } +} + +impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> { + fn from(g: &ArgGroup<'help>) -> Self { + ArgGroup { + id: g.id.clone(), + name: g.name, + required: g.required, + args: g.args.clone(), + requires: g.requires.clone(), + conflicts: g.conflicts.clone(), + multiple: g.multiple, + } + } +} + +/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? +#[cfg(feature = "yaml")] +impl<'help> From<&'help Yaml> for ArgGroup<'help> { + /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? + fn from(y: &'help Yaml) -> Self { + let b = y.as_hash().expect("ArgGroup::from:: expects a table"); + // We WANT this to panic on error...so expect() is good. + let mut a = ArgGroup::default(); + let group_settings = if b.len() == 1 { + let name_yaml = b.keys().next().expect("failed to get name"); + let name_str = name_yaml + .as_str() + .expect("failed to convert arg YAML name to str"); + a.name = name_str; + a.id = Id::from(&a.name); + b.get(name_yaml) + .expect("failed to get name_str") + .as_hash() + .expect("failed to convert to a hash") + } else { + b + }; + + for (k, v) in group_settings { + a = match k.as_str().unwrap() { + "required" => a.required(v.as_bool().unwrap()), + "multiple" => a.multiple(v.as_bool().unwrap()), + "args" => yaml_vec_or_str!(a, v, arg), + "arg" => { + if let Some(ys) = v.as_str() { + a = a.arg(ys); + } + a + } + "requires" => yaml_vec_or_str!(a, v, requires), + "conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with), + "name" => { + if let Some(ys) = v.as_str() { + a = a.id(ys); + } + a + } + s => panic!( + "Unknown ArgGroup setting '{}' in YAML file for \ + ArgGroup '{}'", + s, a.name + ), + } + } + + a + } +} + +#[cfg(test)] +mod test { + use super::ArgGroup; + #[cfg(feature = "yaml")] + use yaml_rust::YamlLoader; + + #[test] + fn groups() { + let g = ArgGroup::new("test") + .arg("a1") + .arg("a4") + .args(&["a2", "a3"]) + .required(true) + .conflicts_with("c1") + .conflicts_with_all(&["c2", "c3"]) + .conflicts_with("c4") + .requires("r1") + .requires_all(&["r2", "r3"]) + .requires("r4"); + + let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()]; + let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()]; + let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()]; + + assert_eq!(g.args, args); + assert_eq!(g.requires, reqs); + assert_eq!(g.conflicts, confs); + } + + #[test] + fn test_from() { + let g = ArgGroup::new("test") + .arg("a1") + .arg("a4") + .args(&["a2", "a3"]) + .required(true) + .conflicts_with("c1") + .conflicts_with_all(&["c2", "c3"]) + .conflicts_with("c4") + .requires("r1") + .requires_all(&["r2", "r3"]) + .requires("r4"); + + let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()]; + let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()]; + let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()]; + + let g2 = ArgGroup::from(&g); + assert_eq!(g2.args, args); + assert_eq!(g2.requires, reqs); + assert_eq!(g2.conflicts, confs); + } + + #[cfg(feature = "yaml")] + #[test] + fn test_yaml() { + let g_yaml = "name: test +args: +- a1 +- a4 +- a2 +- a3 +conflicts_with: +- c1 +- c2 +- c3 +- c4 +requires: +- r1 +- r2 +- r3 +- r4"; + let yaml = &YamlLoader::load_from_str(g_yaml).expect("failed to load YAML file")[0]; + let g = ArgGroup::from(yaml); + let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()]; + let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()]; + let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()]; + assert_eq!(g.args, args); + assert_eq!(g.requires, reqs); + assert_eq!(g.conflicts, confs); + } + + // This test will *fail to compile* if ArgGroup is not Send + Sync + #[test] + fn arg_group_send_sync() { + fn foo(_: T) {} + foo(ArgGroup::new("test")) + } +} + +impl Clone for ArgGroup<'_> { + fn clone(&self) -> Self { + ArgGroup { + id: self.id.clone(), + name: self.name, + required: self.required, + args: self.args.clone(), + requires: self.requires.clone(), + conflicts: self.conflicts.clone(), + multiple: self.multiple, + } + } +} diff --git a/vendor/clap-3.2.20/src/builder/arg_predicate.rs b/vendor/clap-3.2.20/src/builder/arg_predicate.rs new file mode 100644 index 000000000..58eb5494c --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/arg_predicate.rs @@ -0,0 +1,14 @@ +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) enum ArgPredicate<'help> { + IsPresent, + Equals(&'help std::ffi::OsStr), +} + +impl<'help> From> for ArgPredicate<'help> { + fn from(other: Option<&'help std::ffi::OsStr>) -> Self { + match other { + Some(other) => Self::Equals(other), + None => Self::IsPresent, + } + } +} diff --git a/vendor/clap-3.2.20/src/builder/arg_settings.rs b/vendor/clap-3.2.20/src/builder/arg_settings.rs new file mode 100644 index 000000000..ecc064caa --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/arg_settings.rs @@ -0,0 +1,456 @@ +#![allow(deprecated)] + +// Std +use std::ops::BitOr; +#[cfg(feature = "yaml")] +use std::str::FromStr; + +// Third party +use bitflags::bitflags; + +#[allow(unused)] +use crate::Arg; + +#[doc(hidden)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ArgFlags(Flags); + +impl Default for ArgFlags { + fn default() -> Self { + Self::empty() + } +} + +/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter +/// methods [`Arg::setting`], [`Arg::unset_setting`], and [`Arg::is_set`]. This is what the +/// [`Arg`] methods which accept a `bool` use internally. +/// +/// [`Arg`]: crate::Arg +/// [`Arg::setting`]: crate::Arg::setting() +/// [`Arg::unset_setting`]: crate::Arg::unset_setting() +/// [`Arg::is_set`]: crate::Arg::is_set() +#[derive(Debug, PartialEq, Copy, Clone)] +#[non_exhaustive] +pub enum ArgSettings { + /// Deprecated, replaced with [`Arg::required`] and [`Arg::is_required_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::required` and `Arg::is_required_set`" + ) + )] + Required, + /// Deprecated, replaced with [`Arg::multiple_values`] and [`Arg::is_multiple_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::multiple_values` and `Arg::`is_multiple_values_set`" + ) + )] + MultipleValues, + /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Arg::action` (Issue #3772)") + )] + MultipleOccurrences, + /// Deprecated, see [`ArgSettings::MultipleOccurrences`] (most likely what you want) and + /// [`ArgSettings::MultipleValues`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Split into `Arg::multiple_occurrences` (most likely what you want) and `Arg::multiple_values`" + ) + )] + #[doc(hidden)] + Multiple, + /// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`" + ) + )] + ForbidEmptyValues, + /// Deprecated, replaced with [`Arg::global`] and [`Arg::is_global_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::global` and `Arg::is_global_set`" + ) + )] + Global, + /// Deprecated, replaced with [`Arg::hide`] and [`Arg::is_hide_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide` and `Arg::is_hide_set`" + ) + )] + Hidden, + /// Deprecated, replaced with [`Arg::takes_value`] and [`Arg::is_takes_value_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::takes_value` and `Arg::is_takes_value_set`" + ) + )] + TakesValue, + /// Deprecated, replaced with [`Arg::use_value_delimiter`] and + /// [`Arg::is_use_value_delimiter_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::use_value_delimiter` and `Arg::is_use_value_delimiter_set`" + ) + )] + UseValueDelimiter, + /// Deprecated, replaced with [`Arg::next_line_help`] and [`Arg::is_next_line_help_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::next_line_help` and `Arg::is_next_line_help_set`" + ) + )] + NextLineHelp, + /// Deprecated, replaced with [`Arg::require_value_delimiter`] and + /// [`Arg::is_require_value_delimiter_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::require_value_delimiter` and `Arg::is_require_value_delimiter_set`" + ) + )] + RequireDelimiter, + /// Deprecated, replaced with [`Arg::hide_possible_values`] and + /// [`Arg::is_hide_possible_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide_possible_values` and `Arg::is_hide_possible_values_set`" + ) + )] + HidePossibleValues, + /// Deprecated, replaced with [`Arg::allow_hyphen_values`] and + /// [`Arg::is_allow_hyphen_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`" + ) + )] + AllowHyphenValues, + /// Deprecated, replaced with [`Arg::allow_hyphen_values`] and + /// [`Arg::is_allow_hyphen_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`" + ) + )] + #[doc(hidden)] + AllowLeadingHyphen, + /// Deprecated, replaced with [`Arg::require_equals`] and [`Arg::is_require_equals_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::require_equals` and `Arg::is_require_equals_set`" + ) + )] + RequireEquals, + /// Deprecated, replaced with [`Arg::last`] and [`Arg::is_last_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::last` and `Arg::is_last_set`" + ) + )] + Last, + /// Deprecated, replaced with [`Arg::hide_default_value`] and [`Arg::is_hide_default_value_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide_default_value` and `Arg::is_hide_default_value_set`" + ) + )] + HideDefaultValue, + /// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`" + ) + )] + IgnoreCase, + /// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`" + ) + )] + #[doc(hidden)] + CaseInsensitive, + /// Deprecated, replaced with [`Arg::hide_env`] and [`Arg::is_hide_env_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide_env` and `Arg::is_hide_env_set`" + ) + )] + #[cfg(feature = "env")] + HideEnv, + /// Deprecated, replaced with [`Arg::hide_env_values`] and [`Arg::is_hide_env_values_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide_env_values` and `Arg::is_hide_env_values_set`" + ) + )] + #[cfg(feature = "env")] + HideEnvValues, + /// Deprecated, replaced with [`Arg::hide_short_help`] and [`Arg::is_hide_short_help_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide_short_help` and `Arg::is_hide_short_help_set`" + ) + )] + HiddenShortHelp, + /// Deprecated, replaced with [`Arg::hide_long_help`] and [`Arg::is_hide_long_help_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::hide_long_help` and `Arg::is_hide_long_help_set`" + ) + )] + HiddenLongHelp, + /// Deprecated, replaced with [`Arg::allow_invalid_utf8`] and [`Arg::is_allow_invalid_utf8_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::allow_invalid_utf8` and `Arg::is_allow_invalid_utf8_set`" + ) + )] + AllowInvalidUtf8, + /// Deprecated, replaced with [`Arg::exclusive`] and [`Arg::is_exclusive_set`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `Arg::exclusive` and `Arg::is_exclusive_set`" + ) + )] + Exclusive, +} + +bitflags! { + struct Flags: u32 { + const REQUIRED = 1; + const MULTIPLE_OCC = 1 << 1; + const NO_EMPTY_VALS = 1 << 2; + const GLOBAL = 1 << 3; + const HIDDEN = 1 << 4; + const TAKES_VAL = 1 << 5; + const USE_DELIM = 1 << 6; + const NEXT_LINE_HELP = 1 << 7; + const REQ_DELIM = 1 << 9; + const DELIM_NOT_SET = 1 << 10; + const HIDE_POS_VALS = 1 << 11; + const ALLOW_TAC_VALS = 1 << 12; + const REQUIRE_EQUALS = 1 << 13; + const LAST = 1 << 14; + const HIDE_DEFAULT_VAL = 1 << 15; + const CASE_INSENSITIVE = 1 << 16; + #[cfg(feature = "env")] + const HIDE_ENV_VALS = 1 << 17; + const HIDDEN_SHORT_H = 1 << 18; + const HIDDEN_LONG_H = 1 << 19; + const MULTIPLE_VALS = 1 << 20; + const MULTIPLE = Self::MULTIPLE_OCC.bits | Self::MULTIPLE_VALS.bits; + #[cfg(feature = "env")] + const HIDE_ENV = 1 << 21; + const UTF8_NONE = 1 << 22; + const EXCLUSIVE = 1 << 23; + const NO_OP = 0; + } +} + +impl_settings! { ArgSettings, ArgFlags, + Required => Flags::REQUIRED, + MultipleOccurrences => Flags::MULTIPLE_OCC, + MultipleValues => Flags::MULTIPLE_VALS, + Multiple => Flags::MULTIPLE, + ForbidEmptyValues => Flags::NO_EMPTY_VALS, + Global => Flags::GLOBAL, + Hidden => Flags::HIDDEN, + TakesValue => Flags::TAKES_VAL, + UseValueDelimiter => Flags::USE_DELIM, + NextLineHelp => Flags::NEXT_LINE_HELP, + RequireDelimiter => Flags::REQ_DELIM, + HidePossibleValues => Flags::HIDE_POS_VALS, + AllowHyphenValues => Flags::ALLOW_TAC_VALS, + AllowLeadingHyphen => Flags::ALLOW_TAC_VALS, + RequireEquals => Flags::REQUIRE_EQUALS, + Last => Flags::LAST, + IgnoreCase => Flags::CASE_INSENSITIVE, + CaseInsensitive => Flags::CASE_INSENSITIVE, + #[cfg(feature = "env")] + HideEnv => Flags::HIDE_ENV, + #[cfg(feature = "env")] + HideEnvValues => Flags::HIDE_ENV_VALS, + HideDefaultValue => Flags::HIDE_DEFAULT_VAL, + HiddenShortHelp => Flags::HIDDEN_SHORT_H, + HiddenLongHelp => Flags::HIDDEN_LONG_H, + AllowInvalidUtf8 => Flags::UTF8_NONE, + Exclusive => Flags::EXCLUSIVE +} + +/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? +#[cfg(feature = "yaml")] +impl FromStr for ArgSettings { + type Err = String; + fn from_str(s: &str) -> Result::Err> { + #[allow(deprecated)] + #[allow(unreachable_patterns)] + match &*s.to_ascii_lowercase() { + "required" => Ok(ArgSettings::Required), + "multipleoccurrences" => Ok(ArgSettings::MultipleOccurrences), + "multiplevalues" => Ok(ArgSettings::MultipleValues), + "multiple" => Ok(ArgSettings::Multiple), + "forbidemptyvalues" => Ok(ArgSettings::ForbidEmptyValues), + "global" => Ok(ArgSettings::Global), + "hidden" => Ok(ArgSettings::Hidden), + "takesvalue" => Ok(ArgSettings::TakesValue), + "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter), + "nextlinehelp" => Ok(ArgSettings::NextLineHelp), + "requiredelimiter" => Ok(ArgSettings::RequireDelimiter), + "hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues), + "allowhyphenvalues" => Ok(ArgSettings::AllowHyphenValues), + "allowleadinghypyhen" => Ok(ArgSettings::AllowLeadingHyphen), + "requireequals" => Ok(ArgSettings::RequireEquals), + "last" => Ok(ArgSettings::Last), + "ignorecase" => Ok(ArgSettings::IgnoreCase), + "caseinsensitive" => Ok(ArgSettings::CaseInsensitive), + #[cfg(feature = "env")] + "hideenv" => Ok(ArgSettings::HideEnv), + #[cfg(feature = "env")] + "hideenvvalues" => Ok(ArgSettings::HideEnvValues), + "hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue), + "hiddenshorthelp" => Ok(ArgSettings::HiddenShortHelp), + "hiddenlonghelp" => Ok(ArgSettings::HiddenLongHelp), + "allowinvalidutf8" => Ok(ArgSettings::AllowInvalidUtf8), + "exclusive" => Ok(ArgSettings::Exclusive), + _ => Err(format!("unknown AppSetting: `{}`", s)), + } + } +} + +#[cfg(test)] +mod test { + #[test] + #[cfg(feature = "yaml")] + fn arg_settings_fromstr() { + use super::ArgSettings; + + assert_eq!( + "allowhyphenvalues".parse::().unwrap(), + ArgSettings::AllowHyphenValues + ); + assert_eq!( + "forbidemptyvalues".parse::().unwrap(), + ArgSettings::ForbidEmptyValues + ); + assert_eq!( + "hidepossiblevalues".parse::().unwrap(), + ArgSettings::HidePossibleValues + ); + assert_eq!( + "hidden".parse::().unwrap(), + ArgSettings::Hidden + ); + assert_eq!( + "nextlinehelp".parse::().unwrap(), + ArgSettings::NextLineHelp + ); + assert_eq!( + "requiredelimiter".parse::().unwrap(), + ArgSettings::RequireDelimiter + ); + assert_eq!( + "required".parse::().unwrap(), + ArgSettings::Required + ); + assert_eq!( + "takesvalue".parse::().unwrap(), + ArgSettings::TakesValue + ); + assert_eq!( + "usevaluedelimiter".parse::().unwrap(), + ArgSettings::UseValueDelimiter + ); + assert_eq!( + "requireequals".parse::().unwrap(), + ArgSettings::RequireEquals + ); + assert_eq!("last".parse::().unwrap(), ArgSettings::Last); + assert_eq!( + "hidedefaultvalue".parse::().unwrap(), + ArgSettings::HideDefaultValue + ); + assert_eq!( + "ignorecase".parse::().unwrap(), + ArgSettings::IgnoreCase + ); + #[cfg(feature = "env")] + assert_eq!( + "hideenv".parse::().unwrap(), + ArgSettings::HideEnv + ); + #[cfg(feature = "env")] + assert_eq!( + "hideenvvalues".parse::().unwrap(), + ArgSettings::HideEnvValues + ); + assert_eq!( + "hiddenshorthelp".parse::().unwrap(), + ArgSettings::HiddenShortHelp + ); + assert_eq!( + "hiddenlonghelp".parse::().unwrap(), + ArgSettings::HiddenLongHelp + ); + assert_eq!( + "allowinvalidutf8".parse::().unwrap(), + ArgSettings::AllowInvalidUtf8 + ); + assert_eq!( + "exclusive".parse::().unwrap(), + ArgSettings::Exclusive + ); + assert!("hahahaha".parse::().is_err()); + } +} diff --git a/vendor/clap-3.2.20/src/builder/command.rs b/vendor/clap-3.2.20/src/builder/command.rs new file mode 100644 index 000000000..de59ad8cd --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/command.rs @@ -0,0 +1,5189 @@ +#![allow(deprecated)] + +// Std +use std::collections::HashMap; +use std::env; +use std::ffi::OsString; +use std::fmt; +use std::io; +use std::ops::Index; +use std::path::Path; + +// Third Party +#[cfg(feature = "yaml")] +use yaml_rust::Yaml; + +// Internal +use crate::builder::app_settings::{AppFlags, AppSettings}; +use crate::builder::arg_settings::ArgSettings; +use crate::builder::{arg::ArgProvider, Arg, ArgGroup, ArgPredicate}; +use crate::error::ErrorKind; +use crate::error::Result as ClapResult; +use crate::mkeymap::MKeyMap; +use crate::output::fmt::Stream; +use crate::output::{fmt::Colorizer, Help, HelpWriter, Usage}; +use crate::parser::{ArgMatcher, ArgMatches, Parser}; +use crate::util::ChildGraph; +use crate::util::{color::ColorChoice, Id, Key}; +use crate::PossibleValue; +use crate::{Error, INTERNAL_ERROR_MSG}; + +#[cfg(debug_assertions)] +use crate::builder::debug_asserts::assert_app; + +/// Build a command-line interface. +/// +/// This includes defining arguments, subcommands, parser behavior, and help output. +/// Once all configuration is complete, +/// the [`Command::get_matches`] family of methods starts the runtime-parsing +/// process. These methods then return information about the user supplied +/// arguments (or lack thereof). +/// +/// When deriving a [`Parser`][crate::Parser], you can use +/// [`CommandFactory::command`][crate::CommandFactory::command] to access the +/// `Command`. +/// +/// - [Basic API][crate::App#basic-api] +/// - [Application-wide Settings][crate::App#application-wide-settings] +/// - [Command-specific Settings][crate::App#command-specific-settings] +/// - [Subcommand-specific Settings][crate::App#subcommand-specific-settings] +/// - [Reflection][crate::App#reflection] +/// +/// # Examples +/// +/// ```no_run +/// # use clap::{Command, Arg}; +/// let m = Command::new("My Program") +/// .author("Me, me@mail.com") +/// .version("1.0.2") +/// .about("Explains in brief what the program does") +/// .arg( +/// Arg::new("in_file") +/// ) +/// .after_help("Longer explanation to appear after the options when \ +/// displaying the help information from --help or -h") +/// .get_matches(); +/// +/// // Your program logic starts here... +/// ``` +/// [`App::get_matches`]: Command::get_matches() +pub type Command<'help> = App<'help>; + +/// Deprecated, replaced with [`Command`] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Command`") +)] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct App<'help> { + id: Id, + name: String, + long_flag: Option<&'help str>, + short_flag: Option, + display_name: Option, + bin_name: Option, + author: Option<&'help str>, + version: Option<&'help str>, + long_version: Option<&'help str>, + about: Option<&'help str>, + long_about: Option<&'help str>, + before_help: Option<&'help str>, + before_long_help: Option<&'help str>, + after_help: Option<&'help str>, + after_long_help: Option<&'help str>, + aliases: Vec<(&'help str, bool)>, // (name, visible) + short_flag_aliases: Vec<(char, bool)>, // (name, visible) + long_flag_aliases: Vec<(&'help str, bool)>, // (name, visible) + usage_str: Option<&'help str>, + usage_name: Option, + help_str: Option<&'help str>, + disp_ord: Option, + term_w: Option, + max_w: Option, + template: Option<&'help str>, + settings: AppFlags, + g_settings: AppFlags, + args: MKeyMap<'help>, + subcommands: Vec>, + replacers: HashMap<&'help str, &'help [&'help str]>, + groups: Vec>, + current_help_heading: Option<&'help str>, + current_disp_ord: Option, + subcommand_value_name: Option<&'help str>, + subcommand_heading: Option<&'help str>, +} + +/// # Basic API +impl<'help> App<'help> { + /// Creates a new instance of an `Command`. + /// + /// It is common, but not required, to use binary name as the `name`. This + /// name will only be displayed to the user when they request to print + /// version or help and usage information. + /// + /// See also [`command!`](crate::command!) and [`crate_name!`](crate::crate_name!). + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("My Program") + /// # ; + /// ``` + pub fn new>(name: S) -> Self { + /// The actual implementation of `new`, non-generic to save code size. + /// + /// If we don't do this rustc will unnecessarily generate multiple versions + /// of this code. + fn new_inner<'help>(name: String) -> App<'help> { + App { + id: Id::from(&*name), + name, + ..Default::default() + } + .arg( + Arg::new("help") + .long("help") + .help("Print help information") + .global(true) + .generated(), + ) + .arg( + Arg::new("version") + .long("version") + .help("Print version information") + .global(true) + .generated(), + ) + } + + new_inner(name.into()) + } + + /// Adds an [argument] to the list of valid possibilities. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, arg, Arg}; + /// Command::new("myprog") + /// // Adding a single "flag" argument with a short and help text, using Arg::new() + /// .arg( + /// Arg::new("debug") + /// .short('d') + /// .help("turns on debugging mode") + /// ) + /// // Adding a single "option" argument with a short, a long, and help text using the less + /// // verbose Arg::from() + /// .arg( + /// arg!(-c --config "Optionally sets a config file to use") + /// ) + /// # ; + /// ``` + /// [argument]: Arg + #[must_use] + pub fn arg>>(mut self, a: A) -> Self { + let mut arg = a.into(); + if let Some(current_disp_ord) = self.current_disp_ord.as_mut() { + if !arg.is_positional() && arg.provider != ArgProvider::Generated { + let current = *current_disp_ord; + arg.disp_ord.set_implicit(current); + *current_disp_ord = current + 1; + } + } + + arg.help_heading.get_or_insert(self.current_help_heading); + self.args.push(arg); + self + } + + /// Adds multiple [arguments] to the list of valid possibilities. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, arg, Arg}; + /// Command::new("myprog") + /// .args(&[ + /// arg!("[debug] -d 'turns on debugging info'"), + /// Arg::new("input").help("the input file to use") + /// ]) + /// # ; + /// ``` + /// [arguments]: Arg + #[must_use] + pub fn args(mut self, args: I) -> Self + where + I: IntoIterator, + T: Into>, + { + let args = args.into_iter(); + let (lower, _) = args.size_hint(); + self.args.reserve(lower); + + for arg in args { + self = self.arg(arg); + } + self + } + + /// Allows one to mutate an [`Arg`] after it's been added to a [`Command`]. + /// + /// This can be useful for modifying the auto-generated help or version arguments. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// + /// let mut cmd = Command::new("foo") + /// .arg(Arg::new("bar") + /// .short('b')) + /// .mut_arg("bar", |a| a.short('B')); + /// + /// let res = cmd.try_get_matches_from_mut(vec!["foo", "-b"]); + /// + /// // Since we changed `bar`'s short to "B" this should err as there + /// // is no `-b` anymore, only `-B` + /// + /// assert!(res.is_err()); + /// + /// let res = cmd.try_get_matches_from_mut(vec!["foo", "-B"]); + /// assert!(res.is_ok()); + /// ``` + #[must_use] + pub fn mut_arg(mut self, arg_id: T, f: F) -> Self + where + F: FnOnce(Arg<'help>) -> Arg<'help>, + T: Key + Into<&'help str>, + { + let arg_id: &str = arg_id.into(); + let id = Id::from(arg_id); + + let mut a = self.args.remove_by_name(&id).unwrap_or_else(|| Arg { + id, + name: arg_id, + ..Arg::default() + }); + + if a.provider == ArgProvider::Generated { + a.provider = ArgProvider::GeneratedMutated; + } + + self.args.push(f(a)); + self + } + + /// Allows one to mutate a [`Command`] after it's been added as a subcommand. + /// + /// This can be useful for modifying auto-generated arguments of nested subcommands with + /// [`Command::mut_arg`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// + /// let mut cmd = Command::new("foo") + /// .subcommand(Command::new("bar")) + /// .mut_subcommand("bar", |subcmd| subcmd.disable_help_flag(true)); + /// + /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar", "--help"]); + /// + /// // Since we disabled the help flag on the "bar" subcommand, this should err. + /// + /// assert!(res.is_err()); + /// + /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar"]); + /// assert!(res.is_ok()); + /// ``` + #[must_use] + pub fn mut_subcommand<'a, T, F>(mut self, subcmd_id: T, f: F) -> Self + where + F: FnOnce(App<'help>) -> App<'help>, + T: Into<&'a str>, + { + let subcmd_id: &str = subcmd_id.into(); + let id = Id::from(subcmd_id); + + let pos = self.subcommands.iter().position(|s| s.id == id); + + let subcmd = if let Some(idx) = pos { + self.subcommands.remove(idx) + } else { + App::new(subcmd_id) + }; + + self.subcommands.push(f(subcmd)); + self + } + + /// Adds an [`ArgGroup`] to the application. + /// + /// [`ArgGroup`]s are a family of related arguments. + /// By placing them in a logical group, you can build easier requirement and exclusion rules. + /// + /// Example use cases: + /// - Make an entire [`ArgGroup`] required, meaning that one (and *only* + /// one) argument from that group must be present at runtime. + /// - Name an [`ArgGroup`] as a conflict to another argument. + /// Meaning any of the arguments that belong to that group will cause a failure if present with + /// the conflicting argument. + /// - Ensure exclusion between arguments. + /// - Extract a value from a group instead of determining exactly which argument was used. + /// + /// # Examples + /// + /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one, + /// of the arguments from the specified group is present at runtime. + /// + /// ```no_run + /// # use clap::{Command, arg, ArgGroup}; + /// Command::new("cmd") + /// .arg(arg!("--set-ver [ver] 'set the version manually'")) + /// .arg(arg!("--major 'auto increase major'")) + /// .arg(arg!("--minor 'auto increase minor'")) + /// .arg(arg!("--patch 'auto increase patch'")) + /// .group(ArgGroup::new("vers") + /// .args(&["set-ver", "major", "minor","patch"]) + /// .required(true)) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn group>>(mut self, group: G) -> Self { + self.groups.push(group.into()); + self + } + + /// Adds multiple [`ArgGroup`]s to the [`Command`] at once. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, arg, ArgGroup}; + /// Command::new("cmd") + /// .arg(arg!("--set-ver [ver] 'set the version manually'")) + /// .arg(arg!("--major 'auto increase major'")) + /// .arg(arg!("--minor 'auto increase minor'")) + /// .arg(arg!("--patch 'auto increase patch'")) + /// .arg(arg!("-c [FILE] 'a config file'")) + /// .arg(arg!("-i [IFACE] 'an interface'")) + /// .groups(&[ + /// ArgGroup::new("vers") + /// .args(&["set-ver", "major", "minor","patch"]) + /// .required(true), + /// ArgGroup::new("input") + /// .args(&["c", "i"]) + /// ]) + /// # ; + /// ``` + #[must_use] + pub fn groups(mut self, groups: I) -> Self + where + I: IntoIterator, + T: Into>, + { + for g in groups.into_iter() { + self = self.group(g.into()); + } + self + } + + /// Adds a subcommand to the list of valid possibilities. + /// + /// Subcommands are effectively sub-[`Command`]s, because they can contain their own arguments, + /// subcommands, version, usage, etc. They also function just like [`Command`]s, in that they get + /// their own auto generated help, version, and usage. + /// + /// A subcommand's [`Command::name`] will be used for: + /// - The argument the user passes in + /// - Programmatically looking up the subcommand + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, arg}; + /// Command::new("myprog") + /// .subcommand(Command::new("config") + /// .about("Controls configuration features") + /// .arg(arg!(" 'Required configuration file to use'"))) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn subcommand>>(mut self, subcmd: S) -> Self { + self.subcommands.push(subcmd.into()); + self + } + + /// Adds multiple subcommands to the list of valid possibilities. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, }; + /// # Command::new("myprog") + /// .subcommands( vec![ + /// Command::new("config").about("Controls configuration functionality") + /// .arg(Arg::new("config_file")), + /// Command::new("debug").about("Controls debug functionality")]) + /// # ; + /// ``` + /// [`IntoIterator`]: std::iter::IntoIterator + #[must_use] + pub fn subcommands(mut self, subcmds: I) -> Self + where + I: IntoIterator, + T: Into>, + { + for subcmd in subcmds.into_iter() { + self.subcommands.push(subcmd.into()); + } + self + } + + /// Catch problems earlier in the development cycle. + /// + /// Most error states are handled as asserts under the assumption they are programming mistake + /// and not something to handle at runtime. Rather than relying on tests (manual or automated) + /// that exhaustively test your CLI to ensure the asserts are evaluated, this will run those + /// asserts in a way convenient for running as a test. + /// + /// **Note::** This will not help with asserts in [`ArgMatches`], those will need exhaustive + /// testing of your CLI. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// fn cmd() -> Command<'static> { + /// Command::new("foo") + /// .arg( + /// Arg::new("bar").short('b').action(ArgAction::SetTrue) + /// ) + /// } + /// + /// #[test] + /// fn verify_app() { + /// cmd().debug_assert(); + /// } + /// + /// fn main() { + /// let m = cmd().get_matches_from(vec!["foo", "-b"]); + /// println!("{}", *m.get_one::("bar").expect("defaulted by clap")); + /// } + /// ``` + pub fn debug_assert(mut self) { + self._build_all(); + } + + /// Custom error message for post-parsing validation + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let mut cmd = Command::new("myprog"); + /// let err = cmd.error(ErrorKind::InvalidValue, "Some failure case"); + /// ``` + pub fn error(&mut self, kind: ErrorKind, message: impl std::fmt::Display) -> Error { + Error::raw(kind, message).format(self) + } + + /// Parse [`env::args_os`], exiting on failure. + /// + /// # Panics + /// + /// If contradictory arguments or settings exist. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let matches = Command::new("myprog") + /// // Args and options go here... + /// .get_matches(); + /// ``` + /// [`env::args_os`]: std::env::args_os() + /// [`App::try_get_matches_from_mut`]: Command::try_get_matches_from_mut() + #[inline] + pub fn get_matches(self) -> ArgMatches { + self.get_matches_from(&mut env::args_os()) + } + + /// Parse [`env::args_os`], exiting on failure. + /// + /// Like [`App::get_matches`] but doesn't consume the `Command`. + /// + /// # Panics + /// + /// If contradictory arguments or settings exist. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let mut cmd = Command::new("myprog") + /// // Args and options go here... + /// ; + /// let matches = cmd.get_matches_mut(); + /// ``` + /// [`env::args_os`]: std::env::args_os() + /// [`App::get_matches`]: Command::get_matches() + pub fn get_matches_mut(&mut self) -> ArgMatches { + self.try_get_matches_from_mut(&mut env::args_os()) + .unwrap_or_else(|e| e.exit()) + } + + /// Parse [`env::args_os`], returning a [`clap::Result`] on failure. + /// + /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are + /// used. It will return a [`clap::Error`], where the [`kind`] is a + /// [`ErrorKind::DisplayHelp`] or [`ErrorKind::DisplayVersion`] respectively. You must call + /// [`Error::exit`] or perform a [`std::process::exit`]. + /// + /// # Panics + /// + /// If contradictory arguments or settings exist. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let matches = Command::new("myprog") + /// // Args and options go here... + /// .try_get_matches() + /// .unwrap_or_else(|e| e.exit()); + /// ``` + /// [`env::args_os`]: std::env::args_os() + /// [`Error::exit`]: crate::Error::exit() + /// [`std::process::exit`]: std::process::exit() + /// [`clap::Result`]: Result + /// [`clap::Error`]: crate::Error + /// [`kind`]: crate::Error + /// [`ErrorKind::DisplayHelp`]: crate::ErrorKind::DisplayHelp + /// [`ErrorKind::DisplayVersion`]: crate::ErrorKind::DisplayVersion + #[inline] + pub fn try_get_matches(self) -> ClapResult { + // Start the parsing + self.try_get_matches_from(&mut env::args_os()) + } + + /// Parse the specified arguments, exiting on failure. + /// + /// **NOTE:** The first argument will be parsed as the binary name unless + /// [`Command::no_binary_name`] is used. + /// + /// # Panics + /// + /// If contradictory arguments or settings exist. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; + /// + /// let matches = Command::new("myprog") + /// // Args and options go here... + /// .get_matches_from(arg_vec); + /// ``` + /// [`App::get_matches`]: Command::get_matches() + /// [`clap::Result`]: Result + /// [`Vec`]: std::vec::Vec + pub fn get_matches_from(mut self, itr: I) -> ArgMatches + where + I: IntoIterator, + T: Into + Clone, + { + self.try_get_matches_from_mut(itr).unwrap_or_else(|e| { + drop(self); + e.exit() + }) + } + + /// Parse the specified arguments, returning a [`clap::Result`] on failure. + /// + /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are + /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`] + /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or + /// perform a [`std::process::exit`] yourself. + /// + /// **NOTE:** The first argument will be parsed as the binary name unless + /// [`Command::no_binary_name`] is used. + /// + /// # Panics + /// + /// If contradictory arguments or settings exist. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; + /// + /// let matches = Command::new("myprog") + /// // Args and options go here... + /// .try_get_matches_from(arg_vec) + /// .unwrap_or_else(|e| e.exit()); + /// ``` + /// [`App::get_matches_from`]: Command::get_matches_from() + /// [`App::try_get_matches`]: Command::try_get_matches() + /// [`Error::exit`]: crate::Error::exit() + /// [`std::process::exit`]: std::process::exit() + /// [`clap::Error`]: crate::Error + /// [`Error::exit`]: crate::Error::exit() + /// [`kind`]: crate::Error + /// [`ErrorKind::DisplayHelp`]: crate::ErrorKind::DisplayHelp + /// [`ErrorKind::DisplayVersion`]: crate::ErrorKind::DisplayVersion + /// [`clap::Result`]: Result + pub fn try_get_matches_from(mut self, itr: I) -> ClapResult + where + I: IntoIterator, + T: Into + Clone, + { + self.try_get_matches_from_mut(itr) + } + + /// Parse the specified arguments, returning a [`clap::Result`] on failure. + /// + /// Like [`App::try_get_matches_from`] but doesn't consume the `Command`. + /// + /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are + /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`] + /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or + /// perform a [`std::process::exit`] yourself. + /// + /// **NOTE:** The first argument will be parsed as the binary name unless + /// [`Command::no_binary_name`] is used. + /// + /// # Panics + /// + /// If contradictory arguments or settings exist. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; + /// + /// let mut cmd = Command::new("myprog"); + /// // Args and options go here... + /// let matches = cmd.try_get_matches_from_mut(arg_vec) + /// .unwrap_or_else(|e| e.exit()); + /// ``` + /// [`App::try_get_matches_from`]: Command::try_get_matches_from() + /// [`clap::Result`]: Result + /// [`clap::Error`]: crate::Error + /// [`kind`]: crate::Error + pub fn try_get_matches_from_mut(&mut self, itr: I) -> ClapResult + where + I: IntoIterator, + T: Into + Clone, + { + let mut raw_args = clap_lex::RawArgs::new(itr.into_iter()); + let mut cursor = raw_args.cursor(); + + if self.settings.is_set(AppSettings::Multicall) { + if let Some(argv0) = raw_args.next_os(&mut cursor) { + let argv0 = Path::new(&argv0); + if let Some(command) = argv0.file_stem().and_then(|f| f.to_str()) { + // Stop borrowing command so we can get another mut ref to it. + let command = command.to_owned(); + debug!( + "Command::try_get_matches_from_mut: Parsed command {} from argv", + command + ); + + debug!("Command::try_get_matches_from_mut: Reinserting command into arguments so subcommand parser matches it"); + raw_args.insert(&cursor, &[&command]); + debug!("Command::try_get_matches_from_mut: Clearing name and bin_name so that displayed command name starts with applet name"); + self.name.clear(); + self.bin_name = None; + return self._do_parse(&mut raw_args, cursor); + } + } + }; + + // Get the name of the program (argument 1 of env::args()) and determine the + // actual file + // that was used to execute the program. This is because a program called + // ./target/release/my_prog -a + // will have two arguments, './target/release/my_prog', '-a' but we don't want + // to display + // the full path when displaying help messages and such + if !self.settings.is_set(AppSettings::NoBinaryName) { + if let Some(name) = raw_args.next_os(&mut cursor) { + let p = Path::new(name); + + if let Some(f) = p.file_name() { + if let Some(s) = f.to_str() { + if self.bin_name.is_none() { + self.bin_name = Some(s.to_owned()); + } + } + } + } + } + + self._do_parse(&mut raw_args, cursor) + } + + /// Prints the short help message (`-h`) to [`io::stdout()`]. + /// + /// See also [`Command::print_long_help`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// let mut cmd = Command::new("myprog"); + /// cmd.print_help(); + /// ``` + /// [`io::stdout()`]: std::io::stdout() + pub fn print_help(&mut self) -> io::Result<()> { + self._build_self(); + let color = self.color_help(); + + let mut c = Colorizer::new(Stream::Stdout, color); + let usage = Usage::new(self); + Help::new(HelpWriter::Buffer(&mut c), self, &usage, false).write_help()?; + c.print() + } + + /// Prints the long help message (`--help`) to [`io::stdout()`]. + /// + /// See also [`Command::print_help`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// let mut cmd = Command::new("myprog"); + /// cmd.print_long_help(); + /// ``` + /// [`io::stdout()`]: std::io::stdout() + /// [`BufWriter`]: std::io::BufWriter + /// [`-h` (short)]: Arg::help() + /// [`--help` (long)]: Arg::long_help() + pub fn print_long_help(&mut self) -> io::Result<()> { + self._build_self(); + let color = self.color_help(); + + let mut c = Colorizer::new(Stream::Stdout, color); + let usage = Usage::new(self); + Help::new(HelpWriter::Buffer(&mut c), self, &usage, true).write_help()?; + c.print() + } + + /// Writes the short help message (`-h`) to a [`io::Write`] object. + /// + /// See also [`Command::write_long_help`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// use std::io; + /// let mut cmd = Command::new("myprog"); + /// let mut out = io::stdout(); + /// cmd.write_help(&mut out).expect("failed to write to stdout"); + /// ``` + /// [`io::Write`]: std::io::Write + /// [`-h` (short)]: Arg::help() + /// [`--help` (long)]: Arg::long_help() + pub fn write_help(&mut self, w: &mut W) -> io::Result<()> { + self._build_self(); + + let usage = Usage::new(self); + Help::new(HelpWriter::Normal(w), self, &usage, false).write_help()?; + w.flush() + } + + /// Writes the long help message (`--help`) to a [`io::Write`] object. + /// + /// See also [`Command::write_help`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// use std::io; + /// let mut cmd = Command::new("myprog"); + /// let mut out = io::stdout(); + /// cmd.write_long_help(&mut out).expect("failed to write to stdout"); + /// ``` + /// [`io::Write`]: std::io::Write + /// [`-h` (short)]: Arg::help() + /// [`--help` (long)]: Arg::long_help() + pub fn write_long_help(&mut self, w: &mut W) -> io::Result<()> { + self._build_self(); + + let usage = Usage::new(self); + Help::new(HelpWriter::Normal(w), self, &usage, true).write_help()?; + w.flush() + } + + /// Version message rendered as if the user ran `-V`. + /// + /// See also [`Command::render_long_version`]. + /// + /// ### Coloring + /// + /// This function does not try to color the message nor it inserts any [ANSI escape codes]. + /// + /// ### Examples + /// + /// ```rust + /// # use clap::Command; + /// use std::io; + /// let cmd = Command::new("myprog"); + /// println!("{}", cmd.render_version()); + /// ``` + /// [`io::Write`]: std::io::Write + /// [`-V` (short)]: Command::version() + /// [`--version` (long)]: Command::long_version() + /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code + pub fn render_version(&self) -> String { + self._render_version(false) + } + + /// Version message rendered as if the user ran `--version`. + /// + /// See also [`Command::render_version`]. + /// + /// ### Coloring + /// + /// This function does not try to color the message nor it inserts any [ANSI escape codes]. + /// + /// ### Examples + /// + /// ```rust + /// # use clap::Command; + /// use std::io; + /// let cmd = Command::new("myprog"); + /// println!("{}", cmd.render_long_version()); + /// ``` + /// [`io::Write`]: std::io::Write + /// [`-V` (short)]: Command::version() + /// [`--version` (long)]: Command::long_version() + /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code + pub fn render_long_version(&self) -> String { + self._render_version(true) + } + + /// Usage statement + /// + /// ### Examples + /// + /// ```rust + /// # use clap::Command; + /// use std::io; + /// let mut cmd = Command::new("myprog"); + /// println!("{}", cmd.render_usage()); + /// ``` + pub fn render_usage(&mut self) -> String { + // If there are global arguments, or settings we need to propagate them down to subcommands + // before parsing incase we run into a subcommand + self._build_self(); + + Usage::new(self).create_usage_with_title(&[]) + } +} + +/// # Application-wide Settings +/// +/// These settings will apply to the top-level command and all subcommands, by default. Some +/// settings can be overridden in subcommands. +impl<'help> App<'help> { + /// Specifies that the parser should not assume the first argument passed is the binary name. + /// + /// This is normally the case when using a "daemon" style mode. For shells / REPLs, see + /// [`Command::multicall`][App::multicall]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, arg}; + /// let m = Command::new("myprog") + /// .no_binary_name(true) + /// .arg(arg!( ... "commands to run")) + /// .get_matches_from(vec!["command", "set"]); + /// + /// let cmds: Vec<&str> = m.values_of("cmd").unwrap().collect(); + /// assert_eq!(cmds, ["command", "set"]); + /// ``` + /// [`try_get_matches_from_mut`]: crate::Command::try_get_matches_from_mut() + #[inline] + pub fn no_binary_name(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::NoBinaryName) + } else { + self.unset_global_setting(AppSettings::NoBinaryName) + } + } + + /// Try not to fail on parse errors, like missing option values. + /// + /// **Note:** Make sure you apply it as `global_setting` if you want this setting + /// to be propagated to subcommands and sub-subcommands! + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, arg}; + /// let cmd = Command::new("cmd") + /// .ignore_errors(true) + /// .arg(arg!(-c --config "Sets a custom config file").required(false)) + /// .arg(arg!(-x --stuff "Sets a custom stuff file").required(false)) + /// .arg(arg!(f: -f "Flag")); + /// + /// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]); + /// + /// assert!(r.is_ok(), "unexpected error: {:?}", r); + /// let m = r.unwrap(); + /// assert_eq!(m.value_of("config"), Some("file")); + /// assert!(m.is_present("f")); + /// assert_eq!(m.value_of("stuff"), None); + /// ``` + #[inline] + pub fn ignore_errors(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::IgnoreErrors) + } else { + self.unset_global_setting(AppSettings::IgnoreErrors) + } + } + + /// Deprecated, replaced with [`ArgAction::Set`][super::ArgAction::Set] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `Arg::action(ArgAction::Set)`") + )] + pub fn args_override_self(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::AllArgsOverrideSelf) + } else { + self.unset_global_setting(AppSettings::AllArgsOverrideSelf) + } + } + + /// Disables the automatic delimiting of values after `--` or when [`Command::trailing_var_arg`] + /// was used. + /// + /// **NOTE:** The same thing can be done manually by setting the final positional argument to + /// [`Arg::use_value_delimiter(false)`]. Using this setting is safer, because it's easier to locate + /// when making changes. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .dont_delimit_trailing_values(true) + /// .get_matches(); + /// ``` + /// + /// [`Arg::use_value_delimiter(false)`]: crate::Arg::use_value_delimiter() + #[inline] + pub fn dont_delimit_trailing_values(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::DontDelimitTrailingValues) + } else { + self.unset_global_setting(AppSettings::DontDelimitTrailingValues) + } + } + + /// Sets when to color output. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// **NOTE:** Default behaviour is [`ColorChoice::Auto`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, ColorChoice}; + /// Command::new("myprog") + /// .color(ColorChoice::Never) + /// .get_matches(); + /// ``` + /// [`ColorChoice::Auto`]: crate::ColorChoice::Auto + #[cfg(feature = "color")] + #[inline] + #[must_use] + pub fn color(self, color: ColorChoice) -> Self { + #![allow(deprecated)] + let cmd = self + .unset_global_setting(AppSettings::ColorAuto) + .unset_global_setting(AppSettings::ColorAlways) + .unset_global_setting(AppSettings::ColorNever); + match color { + ColorChoice::Auto => cmd.global_setting(AppSettings::ColorAuto), + ColorChoice::Always => cmd.global_setting(AppSettings::ColorAlways), + ColorChoice::Never => cmd.global_setting(AppSettings::ColorNever), + } + } + + /// Sets the terminal width at which to wrap help messages. + /// + /// Using `0` will ignore terminal widths and use source formatting. + /// + /// Defaults to current terminal width when `wrap_help` feature flag is enabled. If the flag + /// is disabled or it cannot be determined, the default is 100. + /// + /// **NOTE:** This setting applies globally and *not* on a per-command basis. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .term_width(80) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn term_width(mut self, width: usize) -> Self { + self.term_w = Some(width); + self + } + + /// Sets the maximum terminal width at which to wrap help messages. + /// + /// This only applies when setting the current terminal width. See [`Command::term_width`] for + /// more details. + /// + /// Using `0` will ignore terminal widths and use source formatting. + /// + /// **NOTE:** This setting applies globally and *not* on a per-command basis. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .max_term_width(100) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn max_term_width(mut self, w: usize) -> Self { + self.max_w = Some(w); + self + } + + /// Disables `-V` and `--version` flag. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let res = Command::new("myprog") + /// .disable_version_flag(true) + /// .try_get_matches_from(vec![ + /// "myprog", "-V" + /// ]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + #[inline] + pub fn disable_version_flag(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::DisableVersionFlag) + } else { + self.unset_global_setting(AppSettings::DisableVersionFlag) + } + } + + /// Specifies to use the version of the current command for all [`subcommands`]. + /// + /// Defaults to `false`; subcommands have independent version strings from their parents. + /// + /// **Note:** Make sure you apply it as `global_setting` if you want this setting + /// to be propagated to subcommands and sub-subcommands! + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .version("v1.1") + /// .propagate_version(true) + /// .subcommand(Command::new("test")) + /// .get_matches(); + /// // running `$ myprog test --version` will display + /// // "myprog-test v1.1" + /// ``` + /// + /// [`subcommands`]: crate::Command::subcommand() + #[inline] + pub fn propagate_version(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::PropagateVersion) + } else { + self.unset_global_setting(AppSettings::PropagateVersion) + } + } + + /// Places the help string for all arguments and subcommands on the line after them. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .next_line_help(true) + /// .get_matches(); + /// ``` + #[inline] + pub fn next_line_help(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::NextLineHelp) + } else { + self.unset_global_setting(AppSettings::NextLineHelp) + } + } + + /// Disables `-h` and `--help` flag. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let res = Command::new("myprog") + /// .disable_help_flag(true) + /// .try_get_matches_from(vec![ + /// "myprog", "-h" + /// ]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + #[inline] + pub fn disable_help_flag(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::DisableHelpFlag) + } else { + self.unset_global_setting(AppSettings::DisableHelpFlag) + } + } + + /// Disables the `help` [`subcommand`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let res = Command::new("myprog") + /// .disable_help_subcommand(true) + /// // Normally, creating a subcommand causes a `help` subcommand to automatically + /// // be generated as well + /// .subcommand(Command::new("test")) + /// .try_get_matches_from(vec![ + /// "myprog", "help" + /// ]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + /// + /// [`subcommand`]: crate::Command::subcommand() + #[inline] + pub fn disable_help_subcommand(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::DisableHelpSubcommand) + } else { + self.unset_global_setting(AppSettings::DisableHelpSubcommand) + } + } + + /// Disables colorized help messages. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .disable_colored_help(true) + /// .get_matches(); + /// ``` + #[inline] + pub fn disable_colored_help(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::DisableColoredHelp) + } else { + self.unset_global_setting(AppSettings::DisableColoredHelp) + } + } + + /// Panic if help descriptions are omitted. + /// + /// **NOTE:** When deriving [`Parser`][crate::Parser], you could instead check this at + /// compile-time with `#![deny(missing_docs)]` + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .help_expected(true) + /// .arg( + /// Arg::new("foo").help("It does foo stuff") + /// // As required via `help_expected`, a help message was supplied + /// ) + /// # .get_matches(); + /// ``` + /// + /// # Panics + /// + /// ```rust,no_run + /// # use clap::{Command, Arg}; + /// Command::new("myapp") + /// .help_expected(true) + /// .arg( + /// Arg::new("foo") + /// // Someone forgot to put .about("...") here + /// // Since the setting `help_expected` is activated, this will lead to + /// // a panic (if you are in debug mode) + /// ) + /// # .get_matches(); + ///``` + #[inline] + pub fn help_expected(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::HelpExpected) + } else { + self.unset_global_setting(AppSettings::HelpExpected) + } + } + + /// Disables the automatic collapsing of positional args into `[ARGS]` inside the usage string. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .dont_collapse_args_in_usage(true) + /// .get_matches(); + /// ``` + #[inline] + pub fn dont_collapse_args_in_usage(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::DontCollapseArgsInUsage) + } else { + self.unset_global_setting(AppSettings::DontCollapseArgsInUsage) + } + } + + /// Tells `clap` *not* to print possible values when displaying help information. + /// + /// This can be useful if there are many values, or they are explained elsewhere. + /// + /// To set this per argument, see + /// [`Arg::hide_possible_values`][crate::Arg::hide_possible_values]. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + #[inline] + pub fn hide_possible_values(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::HidePossibleValues) + } else { + self.unset_global_setting(AppSettings::HidePossibleValues) + } + } + + /// Allow partial matches of long arguments or their [aliases]. + /// + /// For example, to match an argument named `--test`, one could use `--t`, `--te`, `--tes`, and + /// `--test`. + /// + /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match + /// `--te` to `--test` there could not also be another argument or alias `--temp` because both + /// start with `--te` + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// [aliases]: crate::Command::aliases() + #[inline] + pub fn infer_long_args(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::InferLongArgs) + } else { + self.unset_global_setting(AppSettings::InferLongArgs) + } + } + + /// Allow partial matches of [subcommand] names and their [aliases]. + /// + /// For example, to match a subcommand named `test`, one could use `t`, `te`, `tes`, and + /// `test`. + /// + /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match `te` + /// to `test` there could not also be a subcommand or alias `temp` because both start with `te` + /// + /// **CAUTION:** This setting can interfere with [positional/free arguments], take care when + /// designing CLIs which allow inferred subcommands and have potential positional/free + /// arguments whose values could start with the same characters as subcommands. If this is the + /// case, it's recommended to use settings such as [`Command::args_conflicts_with_subcommands`] in + /// conjunction with this setting. + /// + /// **NOTE:** This choice is propagated to all child subcommands. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let m = Command::new("prog") + /// .infer_subcommands(true) + /// .subcommand(Command::new("test")) + /// .get_matches_from(vec![ + /// "prog", "te" + /// ]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// + /// [subcommand]: crate::Command::subcommand() + /// [positional/free arguments]: crate::Arg::index() + /// [aliases]: crate::Command::aliases() + #[inline] + pub fn infer_subcommands(self, yes: bool) -> Self { + if yes { + self.global_setting(AppSettings::InferSubcommands) + } else { + self.unset_global_setting(AppSettings::InferSubcommands) + } + } +} + +/// # Command-specific Settings +/// +/// These apply only to the current command and are not inherited by subcommands. +impl<'help> App<'help> { + /// (Re)Sets the program's name. + /// + /// See [`Command::new`] for more details. + /// + /// # Examples + /// + /// ```ignore + /// # use clap::{Command, load_yaml}; + /// let yaml = load_yaml!("cmd.yaml"); + /// let cmd = Command::from(yaml) + /// .name(crate_name!()); + /// + /// // continued logic goes here, such as `cmd.get_matches()` etc. + /// ``` + #[must_use] + pub fn name>(mut self, name: S) -> Self { + self.name = name.into(); + self + } + + /// Overrides the runtime-determined name of the binary for help and error messages. + /// + /// This should only be used when absolutely necessary, such as when the binary name for your + /// application is misleading, or perhaps *not* how the user should invoke your program. + /// + /// **Pro-tip:** When building things such as third party `cargo` + /// subcommands, this setting **should** be used! + /// + /// **NOTE:** This *does not* change or set the name of the binary file on + /// disk. It only changes what clap thinks the name is for the purposes of + /// error or help messages. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("My Program") + /// .bin_name("my_binary") + /// # ; + /// ``` + #[must_use] + pub fn bin_name>(mut self, name: S) -> Self { + self.bin_name = Some(name.into()); + self + } + + /// Overrides the runtime-determined display name of the program for help and error messages. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("My Program") + /// .display_name("my_program") + /// # ; + /// ``` + #[must_use] + pub fn display_name>(mut self, name: S) -> Self { + self.display_name = Some(name.into()); + self + } + + /// Sets the author(s) for the help message. + /// + /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to + /// automatically set your application's author(s) to the same thing as your + /// crate at compile time. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .author("Me, me@mymain.com") + /// # ; + /// ``` + /// [`crate_authors!`]: ./macro.crate_authors!.html + #[must_use] + pub fn author>(mut self, author: S) -> Self { + self.author = Some(author.into()); + self + } + + /// Sets the program's description for the short help (`-h`). + /// + /// If [`Command::long_about`] is not specified, this message will be displayed for `--help`. + /// + /// **NOTE:** Only `Command::about` (short format) is used in completion + /// script generation in order to be concise. + /// + /// See also [`crate_description!`](crate::crate_description!). + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .about("Does really amazing things for great people") + /// # ; + /// ``` + #[must_use] + pub fn about>>(mut self, about: O) -> Self { + self.about = about.into(); + self + } + + /// Sets the program's description for the long help (`--help`). + /// + /// If [`Command::about`] is not specified, this message will be displayed for `-h`. + /// + /// **NOTE:** Only [`Command::about`] (short format) is used in completion + /// script generation in order to be concise. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .long_about( + /// "Does really amazing things to great people. Now let's talk a little + /// more in depth about how this subcommand really works. It may take about + /// a few lines of text, but that's ok!") + /// # ; + /// ``` + /// [`App::about`]: Command::about() + #[must_use] + pub fn long_about>>(mut self, long_about: O) -> Self { + self.long_about = long_about.into(); + self + } + + /// Free-form help text for after auto-generated short help (`-h`). + /// + /// This is often used to describe how to use the arguments, caveats to be noted, or license + /// and contact information. + /// + /// If [`Command::after_long_help`] is not specified, this message will be displayed for `--help`. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .after_help("Does really amazing things for great people... but be careful with -R!") + /// # ; + /// ``` + /// + #[must_use] + pub fn after_help>(mut self, help: S) -> Self { + self.after_help = Some(help.into()); + self + } + + /// Free-form help text for after auto-generated long help (`--help`). + /// + /// This is often used to describe how to use the arguments, caveats to be noted, or license + /// and contact information. + /// + /// If [`Command::after_help`] is not specified, this message will be displayed for `-h`. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .after_long_help("Does really amazing things to great people... but be careful with -R, \ + /// like, for real, be careful with this!") + /// # ; + /// ``` + #[must_use] + pub fn after_long_help>(mut self, help: S) -> Self { + self.after_long_help = Some(help.into()); + self + } + + /// Free-form help text for before auto-generated short help (`-h`). + /// + /// This is often used for header, copyright, or license information. + /// + /// If [`Command::before_long_help`] is not specified, this message will be displayed for `--help`. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .before_help("Some info I'd like to appear before the help info") + /// # ; + /// ``` + #[must_use] + pub fn before_help>(mut self, help: S) -> Self { + self.before_help = Some(help.into()); + self + } + + /// Free-form help text for before auto-generated long help (`--help`). + /// + /// This is often used for header, copyright, or license information. + /// + /// If [`Command::before_help`] is not specified, this message will be displayed for `-h`. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .before_long_help("Some verbose and long info I'd like to appear before the help info") + /// # ; + /// ``` + #[must_use] + pub fn before_long_help>(mut self, help: S) -> Self { + self.before_long_help = Some(help.into()); + self + } + + /// Sets the version for the short version (`-V`) and help messages. + /// + /// If [`Command::long_version`] is not specified, this message will be displayed for `--version`. + /// + /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to + /// automatically set your application's version to the same thing as your + /// crate at compile time. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .version("v0.1.24") + /// # ; + /// ``` + /// [`crate_version!`]: ./macro.crate_version!.html + #[must_use] + pub fn version>(mut self, ver: S) -> Self { + self.version = Some(ver.into()); + self + } + + /// Sets the version for the long version (`--version`) and help messages. + /// + /// If [`Command::version`] is not specified, this message will be displayed for `-V`. + /// + /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to + /// automatically set your application's version to the same thing as your + /// crate at compile time. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .long_version( + /// "v0.1.24 + /// commit: abcdef89726d + /// revision: 123 + /// release: 2 + /// binary: myprog") + /// # ; + /// ``` + /// [`crate_version!`]: ./macro.crate_version!.html + #[must_use] + pub fn long_version>(mut self, ver: S) -> Self { + self.long_version = Some(ver.into()); + self + } + + /// Overrides the `clap` generated usage string for help and error messages. + /// + /// **NOTE:** Using this setting disables `clap`s "context-aware" usage + /// strings. After this setting is set, this will be *the only* usage string + /// displayed to the user! + /// + /// **NOTE:** Multiple usage lines may be present in the usage argument, but + /// some rules need to be followed to ensure the usage lines are formatted + /// correctly by the default help formatter: + /// + /// - Do not indent the first usage line. + /// - Indent all subsequent usage lines with four spaces. + /// - The last line must not end with a newline. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .override_usage("myapp [-clDas] ") + /// # ; + /// ``` + /// + /// Or for multiple usage lines: + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .override_usage( + /// "myapp -X [-a] [-b] \n \ + /// myapp -Y [-c] \n \ + /// myapp -Z [-d|-e]" + /// ) + /// # ; + /// ``` + /// + /// [`ArgMatches::usage`]: ArgMatches::usage() + #[must_use] + pub fn override_usage>(mut self, usage: S) -> Self { + self.usage_str = Some(usage.into()); + self + } + + /// Overrides the `clap` generated help message (both `-h` and `--help`). + /// + /// This should only be used when the auto-generated message does not suffice. + /// + /// **NOTE:** This **only** replaces the help message for the current + /// command, meaning if you are using subcommands, those help messages will + /// still be auto-generated unless you specify a [`Command::override_help`] for + /// them as well. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myapp") + /// .override_help("myapp v1.0\n\ + /// Does awesome things\n\ + /// (C) me@mail.com\n\n\ + /// + /// USAGE: myapp \n\n\ + /// + /// Options:\n\ + /// -h, --help Display this message\n\ + /// -V, --version Display version info\n\ + /// -s Do something with stuff\n\ + /// -v Be verbose\n\n\ + /// + /// Commands:\n\ + /// help Print this message\n\ + /// work Do some work") + /// # ; + /// ``` + #[must_use] + pub fn override_help>(mut self, help: S) -> Self { + self.help_str = Some(help.into()); + self + } + + /// Sets the help template to be used, overriding the default format. + /// + /// **NOTE:** The template system is by design very simple. Therefore, the + /// tags have to be written in the lowercase and without spacing. + /// + /// Tags are given inside curly brackets. + /// + /// Valid tags are: + /// + /// * `{name}` - Display name for the (sub-)command. + /// * `{bin}` - Binary name. + /// * `{version}` - Version number. + /// * `{author}` - Author information. + /// * `{author-with-newline}` - Author followed by `\n`. + /// * `{author-section}` - Author preceded and followed by `\n`. + /// * `{about}` - General description (from [`Command::about`] or + /// [`Command::long_about`]). + /// * `{about-with-newline}` - About followed by `\n`. + /// * `{about-section}` - About preceded and followed by '\n'. + /// * `{usage-heading}` - Automatically generated usage heading. + /// * `{usage}` - Automatically generated or given usage string. + /// * `{all-args}` - Help for all arguments (options, flags, positional + /// arguments, and subcommands) including titles. + /// * `{options}` - Help for options. + /// * `{positionals}` - Help for positional arguments. + /// * `{subcommands}` - Help for subcommands. + /// * `{after-help}` - Help from [`App::after_help`] or [`Command::after_long_help`]. + /// * `{before-help}` - Help from [`App::before_help`] or [`Command::before_long_help`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::Command; + /// Command::new("myprog") + /// .version("1.0") + /// .help_template("{bin} ({version}) - {usage}") + /// # ; + /// ``` + /// [`App::about`]: Command::about() + /// [`App::long_about`]: Command::long_about() + /// [`App::after_help`]: Command::after_help() + /// [`App::after_long_help`]: Command::after_long_help() + /// [`App::before_help`]: Command::before_help() + /// [`App::before_long_help`]: Command::before_long_help() + #[must_use] + pub fn help_template>(mut self, s: S) -> Self { + self.template = Some(s.into()); + self + } + + /// Apply a setting for the current command or subcommand. + /// + /// See [`Command::global_setting`] to apply a setting to this command and all subcommands. + /// + /// See [`AppSettings`] for a full list of possibilities and examples. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, AppSettings}; + /// Command::new("myprog") + /// .setting(AppSettings::SubcommandRequired) + /// .setting(AppSettings::AllowLeadingHyphen) + /// # ; + /// ``` + /// or + /// ```no_run + /// # use clap::{Command, AppSettings}; + /// Command::new("myprog") + /// .setting(AppSettings::SubcommandRequired | AppSettings::AllowLeadingHyphen) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn setting(mut self, setting: F) -> Self + where + F: Into, + { + self.settings.insert(setting.into()); + self + } + + /// Remove a setting for the current command or subcommand. + /// + /// See [`AppSettings`] for a full list of possibilities and examples. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, AppSettings}; + /// Command::new("myprog") + /// .unset_setting(AppSettings::SubcommandRequired) + /// .setting(AppSettings::AllowLeadingHyphen) + /// # ; + /// ``` + /// or + /// ```no_run + /// # use clap::{Command, AppSettings}; + /// Command::new("myprog") + /// .unset_setting(AppSettings::SubcommandRequired | AppSettings::AllowLeadingHyphen) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn unset_setting(mut self, setting: F) -> Self + where + F: Into, + { + self.settings.remove(setting.into()); + self + } + + /// Apply a setting for the current command and all subcommands. + /// + /// See [`Command::setting`] to apply a setting only to this command. + /// + /// See [`AppSettings`] for a full list of possibilities and examples. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, AppSettings}; + /// Command::new("myprog") + /// .global_setting(AppSettings::AllowNegativeNumbers) + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn global_setting(mut self, setting: AppSettings) -> Self { + self.settings.set(setting); + self.g_settings.set(setting); + self + } + + /// Remove a setting and stop propagating down to subcommands. + /// + /// See [`AppSettings`] for a full list of possibilities and examples. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, AppSettings}; + /// Command::new("myprog") + /// .unset_global_setting(AppSettings::AllowNegativeNumbers) + /// # ; + /// ``` + /// [global]: Command::global_setting() + #[inline] + #[must_use] + pub fn unset_global_setting(mut self, setting: AppSettings) -> Self { + self.settings.unset(setting); + self.g_settings.unset(setting); + self + } + + /// Deprecated, replaced with [`Command::next_help_heading`] + #[inline] + #[must_use] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `App::next_help_heading`") + )] + pub fn help_heading(self, heading: O) -> Self + where + O: Into>, + { + self.next_help_heading(heading) + } + + /// Set the default section heading for future args. + /// + /// This will be used for any arg that hasn't had [`Arg::help_heading`] called. + /// + /// This is useful if the default `OPTIONS` or `ARGS` headings are + /// not specific enough for one's use case. + /// + /// For subcommands, see [`Command::subcommand_help_heading`] + /// + /// [`App::arg`]: Command::arg() + /// [`Arg::help_heading`]: crate::Arg::help_heading() + #[inline] + #[must_use] + pub fn next_help_heading(mut self, heading: O) -> Self + where + O: Into>, + { + self.current_help_heading = heading.into(); + self + } + + /// Change the starting value for assigning future display orders for ags. + /// + /// This will be used for any arg that hasn't had [`Arg::display_order`] called. + #[inline] + #[must_use] + pub fn next_display_order(mut self, disp_ord: impl Into>) -> Self { + self.current_disp_ord = disp_ord.into(); + self + } + + /// Replaces an argument or subcommand used on the CLI at runtime with other arguments or subcommands. + /// + /// **Note:** This is gated behind [`unstable-replace`](https://github.com/clap-rs/clap/issues/2836) + /// + /// When this method is used, `name` is removed from the CLI, and `target` + /// is inserted in its place. Parsing continues as if the user typed + /// `target` instead of `name`. + /// + /// This can be used to create "shortcuts" for subcommands, or if a + /// particular argument has the semantic meaning of several other specific + /// arguments and values. + /// + /// # Examples + /// + /// We'll start with the "subcommand short" example. In this example, let's + /// assume we have a program with a subcommand `module` which can be invoked + /// via `cmd module`. Now let's also assume `module` also has a subcommand + /// called `install` which can be invoked `cmd module install`. If for some + /// reason users needed to be able to reach `cmd module install` via the + /// short-hand `cmd install`, we'd have several options. + /// + /// We *could* create another sibling subcommand to `module` called + /// `install`, but then we would need to manage another subcommand and manually + /// dispatch to `cmd module install` handling code. This is error prone and + /// tedious. + /// + /// We could instead use [`Command::replace`] so that, when the user types `cmd + /// install`, `clap` will replace `install` with `module install` which will + /// end up getting parsed as if the user typed the entire incantation. + /// + /// ```rust + /// # use clap::Command; + /// let m = Command::new("cmd") + /// .subcommand(Command::new("module") + /// .subcommand(Command::new("install"))) + /// .replace("install", &["module", "install"]) + /// .get_matches_from(vec!["cmd", "install"]); + /// + /// assert!(m.subcommand_matches("module").is_some()); + /// assert!(m.subcommand_matches("module").unwrap().subcommand_matches("install").is_some()); + /// ``` + /// + /// Now let's show an argument example! + /// + /// Let's assume we have an application with two flags `--save-context` and + /// `--save-runtime`. But often users end up needing to do *both* at the + /// same time. We can add a third flag `--save-all` which semantically means + /// the same thing as `cmd --save-context --save-runtime`. To implement that, + /// we have several options. + /// + /// We could create this third argument and manually check if that argument + /// and in our own consumer code handle the fact that both `--save-context` + /// and `--save-runtime` *should* have been used. But again this is error + /// prone and tedious. If we had code relying on checking `--save-context` + /// and we forgot to update that code to *also* check `--save-all` it'd mean + /// an error! + /// + /// Luckily we can use [`Command::replace`] so that when the user types + /// `--save-all`, `clap` will replace that argument with `--save-context + /// --save-runtime`, and parsing will continue like normal. Now all our code + /// that was originally checking for things like `--save-context` doesn't + /// need to change! + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("cmd") + /// .arg(Arg::new("save-context") + /// .long("save-context") + /// .action(ArgAction::SetTrue)) + /// .arg(Arg::new("save-runtime") + /// .long("save-runtime") + /// .action(ArgAction::SetTrue)) + /// .replace("--save-all", &["--save-context", "--save-runtime"]) + /// .get_matches_from(vec!["cmd", "--save-all"]); + /// + /// assert!(*m.get_one::("save-context").expect("defaulted by clap")); + /// assert!(*m.get_one::("save-runtime").expect("defaulted by clap")); + /// ``` + /// + /// This can also be used with options, for example if our application with + /// `--save-*` above also had a `--format=TYPE` option. Let's say it + /// accepted `txt` or `json` values. However, when `--save-all` is used, + /// only `--format=json` is allowed, or valid. We could change the example + /// above to enforce this: + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("cmd") + /// .arg(Arg::new("save-context") + /// .long("save-context") + /// .action(ArgAction::SetTrue)) + /// .arg(Arg::new("save-runtime") + /// .long("save-runtime") + /// .action(ArgAction::SetTrue)) + /// .arg(Arg::new("format") + /// .long("format") + /// .takes_value(true) + /// .value_parser(["txt", "json"])) + /// .replace("--save-all", &["--save-context", "--save-runtime", "--format=json"]) + /// .get_matches_from(vec!["cmd", "--save-all"]); + /// + /// assert!(*m.get_one::("save-context").expect("defaulted by clap")); + /// assert!(*m.get_one::("save-runtime").expect("defaulted by clap")); + /// assert_eq!(m.value_of("format"), Some("json")); + /// ``` + /// + /// [`App::replace`]: Command::replace() + #[inline] + #[cfg(feature = "unstable-replace")] + #[must_use] + pub fn replace(mut self, name: &'help str, target: &'help [&'help str]) -> Self { + self.replacers.insert(name, target); + self + } + + /// Exit gracefully if no arguments are present (e.g. `$ myprog`). + /// + /// **NOTE:** [`subcommands`] count as arguments + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command}; + /// Command::new("myprog") + /// .arg_required_else_help(true); + /// ``` + /// + /// [`subcommands`]: crate::Command::subcommand() + /// [`Arg::default_value`]: crate::Arg::default_value() + #[inline] + pub fn arg_required_else_help(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::ArgRequiredElseHelp) + } else { + self.unset_setting(AppSettings::ArgRequiredElseHelp) + } + } + + /// Specifies that leading hyphens are allowed in all argument *values* (e.g. `-10`). + /// + /// Otherwise they will be parsed as another flag or option. See also + /// [`Command::allow_negative_numbers`]. + /// + /// **NOTE:** Use this setting with caution as it silences certain circumstances which would + /// otherwise be an error (such as accidentally forgetting to specify a value for leading + /// option). It is preferred to set this on a per argument basis, via [`Arg::allow_hyphen_values`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Arg, Command}; + /// // Imagine you needed to represent negative numbers as well, such as -10 + /// let m = Command::new("nums") + /// .allow_hyphen_values(true) + /// .arg(Arg::new("neg")) + /// .get_matches_from(vec![ + /// "nums", "-20" + /// ]); + /// + /// assert_eq!(m.value_of("neg"), Some("-20")); + /// # ; + /// ``` + /// [`Arg::allow_hyphen_values`]: crate::Arg::allow_hyphen_values() + #[inline] + pub fn allow_hyphen_values(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::AllowHyphenValues) + } else { + self.unset_setting(AppSettings::AllowHyphenValues) + } + } + + /// Allows negative numbers to pass as values. + /// + /// This is similar to [`Command::allow_hyphen_values`] except that it only allows numbers, + /// all other undefined leading hyphens will fail to parse. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let res = Command::new("myprog") + /// .allow_negative_numbers(true) + /// .arg(Arg::new("num")) + /// .try_get_matches_from(vec![ + /// "myprog", "-20" + /// ]); + /// assert!(res.is_ok()); + /// let m = res.unwrap(); + /// assert_eq!(m.value_of("num").unwrap(), "-20"); + /// ``` + #[inline] + pub fn allow_negative_numbers(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::AllowNegativeNumbers) + } else { + self.unset_setting(AppSettings::AllowNegativeNumbers) + } + } + + /// Specifies that the final positional argument is a "VarArg" and that `clap` should not + /// attempt to parse any further args. + /// + /// The values of the trailing positional argument will contain all args from itself on. + /// + /// **NOTE:** The final positional argument **must** have [`Arg::multiple_values(true)`] or the usage + /// string equivalent. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, arg}; + /// let m = Command::new("myprog") + /// .trailing_var_arg(true) + /// .arg(arg!( ... "commands to run")) + /// .get_matches_from(vec!["myprog", "arg1", "-r", "val1"]); + /// + /// let trail: Vec<&str> = m.values_of("cmd").unwrap().collect(); + /// assert_eq!(trail, ["arg1", "-r", "val1"]); + /// ``` + /// [`Arg::multiple_values(true)`]: crate::Arg::multiple_values() + pub fn trailing_var_arg(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::TrailingVarArg) + } else { + self.unset_setting(AppSettings::TrailingVarArg) + } + } + + /// Allows one to implement two styles of CLIs where positionals can be used out of order. + /// + /// The first example is a CLI where the second to last positional argument is optional, but + /// the final positional argument is required. Such as `$ prog [optional] ` where one + /// of the two following usages is allowed: + /// + /// * `$ prog [optional] ` + /// * `$ prog ` + /// + /// This would otherwise not be allowed. This is useful when `[optional]` has a default value. + /// + /// **Note:** when using this style of "missing positionals" the final positional *must* be + /// [required] if `--` will not be used to skip to the final positional argument. + /// + /// **Note:** This style also only allows a single positional argument to be "skipped" without + /// the use of `--`. To skip more than one, see the second example. + /// + /// The second example is when one wants to skip multiple optional positional arguments, and use + /// of the `--` operator is OK (but not required if all arguments will be specified anyways). + /// + /// For example, imagine a CLI which has three positional arguments `[foo] [bar] [baz]...` where + /// `baz` accepts multiple values (similar to man `ARGS...` style training arguments). + /// + /// With this setting the following invocations are posisble: + /// + /// * `$ prog foo bar baz1 baz2 baz3` + /// * `$ prog foo -- baz1 baz2 baz3` + /// * `$ prog -- baz1 baz2 baz3` + /// + /// # Examples + /// + /// Style number one from above: + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// // Assume there is an external subcommand named "subcmd" + /// let m = Command::new("myprog") + /// .allow_missing_positional(true) + /// .arg(Arg::new("arg1")) + /// .arg(Arg::new("arg2") + /// .required(true)) + /// .get_matches_from(vec![ + /// "prog", "other" + /// ]); + /// + /// assert_eq!(m.value_of("arg1"), None); + /// assert_eq!(m.value_of("arg2"), Some("other")); + /// ``` + /// + /// Now the same example, but using a default value for the first optional positional argument + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// // Assume there is an external subcommand named "subcmd" + /// let m = Command::new("myprog") + /// .allow_missing_positional(true) + /// .arg(Arg::new("arg1") + /// .default_value("something")) + /// .arg(Arg::new("arg2") + /// .required(true)) + /// .get_matches_from(vec![ + /// "prog", "other" + /// ]); + /// + /// assert_eq!(m.value_of("arg1"), Some("something")); + /// assert_eq!(m.value_of("arg2"), Some("other")); + /// ``` + /// + /// Style number two from above: + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// // Assume there is an external subcommand named "subcmd" + /// let m = Command::new("myprog") + /// .allow_missing_positional(true) + /// .arg(Arg::new("foo")) + /// .arg(Arg::new("bar")) + /// .arg(Arg::new("baz").takes_value(true).multiple_values(true)) + /// .get_matches_from(vec![ + /// "prog", "foo", "bar", "baz1", "baz2", "baz3" + /// ]); + /// + /// assert_eq!(m.value_of("foo"), Some("foo")); + /// assert_eq!(m.value_of("bar"), Some("bar")); + /// assert_eq!(m.values_of("baz").unwrap().collect::>(), &["baz1", "baz2", "baz3"]); + /// ``` + /// + /// Now nofice if we don't specify `foo` or `baz` but use the `--` operator. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// // Assume there is an external subcommand named "subcmd" + /// let m = Command::new("myprog") + /// .allow_missing_positional(true) + /// .arg(Arg::new("foo")) + /// .arg(Arg::new("bar")) + /// .arg(Arg::new("baz").takes_value(true).multiple_values(true)) + /// .get_matches_from(vec![ + /// "prog", "--", "baz1", "baz2", "baz3" + /// ]); + /// + /// assert_eq!(m.value_of("foo"), None); + /// assert_eq!(m.value_of("bar"), None); + /// assert_eq!(m.values_of("baz").unwrap().collect::>(), &["baz1", "baz2", "baz3"]); + /// ``` + /// + /// [required]: crate::Arg::required() + #[inline] + pub fn allow_missing_positional(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::AllowMissingPositional) + } else { + self.unset_setting(AppSettings::AllowMissingPositional) + } + } +} + +/// # Subcommand-specific Settings +impl<'help> App<'help> { + /// Sets the short version of the subcommand flag without the preceding `-`. + /// + /// Allows the subcommand to be used as if it were an [`Arg::short`]. + /// + /// # Examples + /// + /// ``` + /// # use clap::{Command, Arg, ArgAction}; + /// let matches = Command::new("pacman") + /// .subcommand( + /// Command::new("sync").short_flag('S').arg( + /// Arg::new("search") + /// .short('s') + /// .long("search") + /// .action(ArgAction::SetTrue) + /// .help("search remote repositories for matching strings"), + /// ), + /// ) + /// .get_matches_from(vec!["pacman", "-Ss"]); + /// + /// assert_eq!(matches.subcommand_name().unwrap(), "sync"); + /// let sync_matches = matches.subcommand_matches("sync").unwrap(); + /// assert!(*sync_matches.get_one::("search").expect("defaulted by clap")); + /// ``` + /// [`Arg::short`]: Arg::short() + #[must_use] + pub fn short_flag(mut self, short: char) -> Self { + self.short_flag = Some(short); + self + } + + /// Sets the long version of the subcommand flag without the preceding `--`. + /// + /// Allows the subcommand to be used as if it were an [`Arg::long`]. + /// + /// **NOTE:** Any leading `-` characters will be stripped. + /// + /// # Examples + /// + /// To set `long_flag` use a word containing valid UTF-8 codepoints. If you supply a double leading + /// `--` such as `--sync` they will be stripped. Hyphens in the middle of the word; however, + /// will *not* be stripped (i.e. `sync-file` is allowed). + /// + /// ``` + /// # use clap::{Command, Arg, ArgAction}; + /// let matches = Command::new("pacman") + /// .subcommand( + /// Command::new("sync").long_flag("sync").arg( + /// Arg::new("search") + /// .short('s') + /// .long("search") + /// .action(ArgAction::SetTrue) + /// .help("search remote repositories for matching strings"), + /// ), + /// ) + /// .get_matches_from(vec!["pacman", "--sync", "--search"]); + /// + /// assert_eq!(matches.subcommand_name().unwrap(), "sync"); + /// let sync_matches = matches.subcommand_matches("sync").unwrap(); + /// assert!(*sync_matches.get_one::("search").expect("defaulted by clap")); + /// ``` + /// + /// [`Arg::long`]: Arg::long() + #[must_use] + pub fn long_flag(mut self, long: &'help str) -> Self { + #[cfg(feature = "unstable-v4")] + { + self.long_flag = Some(long); + } + #[cfg(not(feature = "unstable-v4"))] + { + self.long_flag = Some(long.trim_start_matches(|c| c == '-')); + } + self + } + + /// Sets a hidden alias to this subcommand. + /// + /// This allows the subcommand to be accessed via *either* the original name, or this given + /// alias. This is more efficient and easier than creating multiple hidden subcommands as one + /// only needs to check for the existence of this command, and not all aliased variants. + /// + /// **NOTE:** Aliases defined with this method are *hidden* from the help + /// message. If you're looking for aliases that will be displayed in the help + /// message, see [`Command::visible_alias`]. + /// + /// **NOTE:** When using aliases and checking for the existence of a + /// particular subcommand within an [`ArgMatches`] struct, one only needs to + /// search for the original name and not all aliases. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test") + /// .alias("do-stuff")) + /// .get_matches_from(vec!["myprog", "do-stuff"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::visible_alias`]: Command::visible_alias() + #[must_use] + pub fn alias>(mut self, name: S) -> Self { + self.aliases.push((name.into(), false)); + self + } + + /// Add an alias, which functions as "hidden" short flag subcommand + /// + /// This will automatically dispatch as if this subcommand was used. This is more efficient, + /// and easier than creating multiple hidden subcommands as one only needs to check for the + /// existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").short_flag('t') + /// .short_flag_alias('d')) + /// .get_matches_from(vec!["myprog", "-d"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + #[must_use] + pub fn short_flag_alias(mut self, name: char) -> Self { + assert!(name != '-', "short alias name cannot be `-`"); + self.short_flag_aliases.push((name, false)); + self + } + + /// Add an alias, which functions as a "hidden" long flag subcommand. + /// + /// This will automatically dispatch as if this subcommand was used. This is more efficient, + /// and easier than creating multiple hidden subcommands as one only needs to check for the + /// existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").long_flag("test") + /// .long_flag_alias("testing")) + /// .get_matches_from(vec!["myprog", "--testing"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + #[must_use] + pub fn long_flag_alias(mut self, name: &'help str) -> Self { + self.long_flag_aliases.push((name, false)); + self + } + + /// Sets multiple hidden aliases to this subcommand. + /// + /// This allows the subcommand to be accessed via *either* the original name or any of the + /// given aliases. This is more efficient, and easier than creating multiple hidden subcommands + /// as one only needs to check for the existence of this command and not all aliased variants. + /// + /// **NOTE:** Aliases defined with this method are *hidden* from the help + /// message. If looking for aliases that will be displayed in the help + /// message, see [`Command::visible_aliases`]. + /// + /// **NOTE:** When using aliases and checking for the existence of a + /// particular subcommand within an [`ArgMatches`] struct, one only needs to + /// search for the original name and not all aliases. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test") + /// .aliases(&["do-stuff", "do-tests", "tests"])) + /// .arg(Arg::new("input") + /// .help("the file to add") + /// .required(false)) + /// .get_matches_from(vec!["myprog", "do-tests"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::visible_aliases`]: Command::visible_aliases() + #[must_use] + pub fn aliases(mut self, names: &[&'help str]) -> Self { + self.aliases.extend(names.iter().map(|n| (*n, false))); + self + } + + /// Add aliases, which function as "hidden" short flag subcommands. + /// + /// These will automatically dispatch as if this subcommand was used. This is more efficient, + /// and easier than creating multiple hidden subcommands as one only needs to check for the + /// existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").short_flag('t') + /// .short_flag_aliases(&['a', 'b', 'c'])) + /// .arg(Arg::new("input") + /// .help("the file to add") + /// .required(false)) + /// .get_matches_from(vec!["myprog", "-a"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + #[must_use] + pub fn short_flag_aliases(mut self, names: &[char]) -> Self { + for s in names { + assert!(s != &'-', "short alias name cannot be `-`"); + self.short_flag_aliases.push((*s, false)); + } + self + } + + /// Add aliases, which function as "hidden" long flag subcommands. + /// + /// These will automatically dispatch as if this subcommand was used. This is more efficient, + /// and easier than creating multiple hidden subcommands as one only needs to check for the + /// existence of this command, and not all variants. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").long_flag("test") + /// .long_flag_aliases(&["testing", "testall", "test_all"])) + /// .arg(Arg::new("input") + /// .help("the file to add") + /// .required(false)) + /// .get_matches_from(vec!["myprog", "--testing"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + #[must_use] + pub fn long_flag_aliases(mut self, names: &[&'help str]) -> Self { + for s in names { + self.long_flag_aliases.push((s, false)); + } + self + } + + /// Sets a visible alias to this subcommand. + /// + /// This allows the subcommand to be accessed via *either* the + /// original name or the given alias. This is more efficient and easier + /// than creating hidden subcommands as one only needs to check for + /// the existence of this command and not all aliased variants. + /// + /// **NOTE:** The alias defined with this method is *visible* from the help + /// message and displayed as if it were just another regular subcommand. If + /// looking for an alias that will not be displayed in the help message, see + /// [`Command::alias`]. + /// + /// **NOTE:** When using aliases and checking for the existence of a + /// particular subcommand within an [`ArgMatches`] struct, one only needs to + /// search for the original name and not all aliases. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test") + /// .visible_alias("do-stuff")) + /// .get_matches_from(vec!["myprog", "do-stuff"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::alias`]: Command::alias() + #[must_use] + pub fn visible_alias>(mut self, name: S) -> Self { + self.aliases.push((name.into(), true)); + self + } + + /// Add an alias, which functions as "visible" short flag subcommand + /// + /// This will automatically dispatch as if this subcommand was used. This is more efficient, + /// and easier than creating multiple hidden subcommands as one only needs to check for the + /// existence of this command, and not all variants. + /// + /// See also [`Command::short_flag_alias`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").short_flag('t') + /// .visible_short_flag_alias('d')) + /// .get_matches_from(vec!["myprog", "-d"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::short_flag_alias`]: Command::short_flag_alias() + #[must_use] + pub fn visible_short_flag_alias(mut self, name: char) -> Self { + assert!(name != '-', "short alias name cannot be `-`"); + self.short_flag_aliases.push((name, true)); + self + } + + /// Add an alias, which functions as a "visible" long flag subcommand. + /// + /// This will automatically dispatch as if this subcommand was used. This is more efficient, + /// and easier than creating multiple hidden subcommands as one only needs to check for the + /// existence of this command, and not all variants. + /// + /// See also [`Command::long_flag_alias`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").long_flag("test") + /// .visible_long_flag_alias("testing")) + /// .get_matches_from(vec!["myprog", "--testing"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::long_flag_alias`]: Command::long_flag_alias() + #[must_use] + pub fn visible_long_flag_alias(mut self, name: &'help str) -> Self { + self.long_flag_aliases.push((name, true)); + self + } + + /// Sets multiple visible aliases to this subcommand. + /// + /// This allows the subcommand to be accessed via *either* the + /// original name or any of the given aliases. This is more efficient and easier + /// than creating multiple hidden subcommands as one only needs to check for + /// the existence of this command and not all aliased variants. + /// + /// **NOTE:** The alias defined with this method is *visible* from the help + /// message and displayed as if it were just another regular subcommand. If + /// looking for an alias that will not be displayed in the help message, see + /// [`Command::alias`]. + /// + /// **NOTE:** When using aliases, and checking for the existence of a + /// particular subcommand within an [`ArgMatches`] struct, one only needs to + /// search for the original name and not all aliases. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test") + /// .visible_aliases(&["do-stuff", "tests"])) + /// .get_matches_from(vec!["myprog", "do-stuff"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::alias`]: Command::alias() + #[must_use] + pub fn visible_aliases(mut self, names: &[&'help str]) -> Self { + self.aliases.extend(names.iter().map(|n| (*n, true))); + self + } + + /// Add aliases, which function as *visible* short flag subcommands. + /// + /// See [`Command::short_flag_aliases`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").short_flag('b') + /// .visible_short_flag_aliases(&['t'])) + /// .get_matches_from(vec!["myprog", "-t"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::short_flag_aliases`]: Command::short_flag_aliases() + #[must_use] + pub fn visible_short_flag_aliases(mut self, names: &[char]) -> Self { + for s in names { + assert!(s != &'-', "short alias name cannot be `-`"); + self.short_flag_aliases.push((*s, true)); + } + self + } + + /// Add aliases, which function as *visible* long flag subcommands. + /// + /// See [`Command::long_flag_aliases`]. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let m = Command::new("myprog") + /// .subcommand(Command::new("test").long_flag("test") + /// .visible_long_flag_aliases(&["testing", "testall", "test_all"])) + /// .get_matches_from(vec!["myprog", "--testing"]); + /// assert_eq!(m.subcommand_name(), Some("test")); + /// ``` + /// [`App::long_flag_aliases`]: Command::long_flag_aliases() + #[must_use] + pub fn visible_long_flag_aliases(mut self, names: &[&'help str]) -> Self { + for s in names { + self.long_flag_aliases.push((s, true)); + } + self + } + + /// Set the placement of this subcommand within the help. + /// + /// Subcommands with a lower value will be displayed first in the help message. Subcommands + /// with duplicate display orders will be displayed in alphabetical order. + /// + /// This is helpful when one would like to emphasize frequently used subcommands, or prioritize + /// those towards the top of the list. + /// + /// **NOTE:** The default is 999 for all subcommands. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, }; + /// let m = Command::new("cust-ord") + /// .subcommand(Command::new("alpha") // typically subcommands are grouped + /// // alphabetically by name. Subcommands + /// // without a display_order have a value of + /// // 999 and are displayed alphabetically with + /// // all other 999 subcommands + /// .about("Some help and text")) + /// .subcommand(Command::new("beta") + /// .display_order(1) // In order to force this subcommand to appear *first* + /// // all we have to do is give it a value lower than 999. + /// // Any other subcommands with a value of 1 will be displayed + /// // alphabetically with this one...then 2 values, then 3, etc. + /// .about("I should be first!")) + /// .get_matches_from(vec![ + /// "cust-ord", "--help" + /// ]); + /// ``` + /// + /// The above example displays the following help message + /// + /// ```text + /// cust-ord + /// + /// USAGE: + /// cust-ord [OPTIONS] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// + /// SUBCOMMANDS: + /// beta I should be first! + /// alpha Some help and text + /// ``` + #[inline] + #[must_use] + pub fn display_order(mut self, ord: usize) -> Self { + self.disp_ord = Some(ord); + self + } + + /// Specifies that this [`subcommand`] should be hidden from help messages + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .subcommand( + /// Command::new("test").hide(true) + /// ) + /// # ; + /// ``` + /// + /// [`subcommand`]: crate::Command::subcommand() + #[inline] + pub fn hide(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::Hidden) + } else { + self.unset_setting(AppSettings::Hidden) + } + } + + /// If no [`subcommand`] is present at runtime, error and exit gracefully. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let err = Command::new("myprog") + /// .subcommand_required(true) + /// .subcommand(Command::new("test")) + /// .try_get_matches_from(vec![ + /// "myprog", + /// ]); + /// assert!(err.is_err()); + /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand); + /// # ; + /// ``` + /// + /// [`subcommand`]: crate::Command::subcommand() + pub fn subcommand_required(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::SubcommandRequired) + } else { + self.unset_setting(AppSettings::SubcommandRequired) + } + } + + /// Assume unexpected positional arguments are a [`subcommand`]. + /// + /// Arguments will be stored in the `""` argument in the [`ArgMatches`] + /// + /// **NOTE:** Use this setting with caution, + /// as a truly unexpected argument (i.e. one that is *NOT* an external subcommand) + /// will **not** cause an error and instead be treated as a potential subcommand. + /// One should check for such cases manually and inform the user appropriately. + /// + /// **NOTE:** A built-in subcommand will be parsed as an external subcommand when escaped with + /// `--`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// // Assume there is an external subcommand named "subcmd" + /// let m = Command::new("myprog") + /// .allow_external_subcommands(true) + /// .get_matches_from(vec![ + /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" + /// ]); + /// + /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty + /// // string argument name + /// match m.subcommand() { + /// Some((external, ext_m)) => { + /// let ext_args: Vec<&str> = ext_m.values_of("").unwrap().collect(); + /// assert_eq!(external, "subcmd"); + /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); + /// }, + /// _ => {}, + /// } + /// ``` + /// + /// [`subcommand`]: crate::Command::subcommand() + /// [`ArgMatches`]: crate::ArgMatches + /// [`ErrorKind::UnknownArgument`]: crate::ErrorKind::UnknownArgument + pub fn allow_external_subcommands(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::AllowExternalSubcommands) + } else { + self.unset_setting(AppSettings::AllowExternalSubcommands) + } + } + + /// Specifies that external subcommands that are invalid UTF-8 should *not* be treated as an error. + /// + /// **NOTE:** Using external subcommand argument values with invalid UTF-8 requires using + /// [`ArgMatches::values_of_os`] or [`ArgMatches::values_of_lossy`] for those particular + /// arguments which may contain invalid UTF-8 values + /// + /// **NOTE:** Setting this requires [`Command::allow_external_subcommands`] + /// + /// # Platform Specific + /// + /// Non Windows systems only + /// + /// # Examples + /// + #[cfg_attr(not(unix), doc = " ```ignore")] + #[cfg_attr(unix, doc = " ```")] + /// # use clap::Command; + /// // Assume there is an external subcommand named "subcmd" + /// let m = Command::new("myprog") + /// .allow_invalid_utf8_for_external_subcommands(true) + /// .allow_external_subcommands(true) + /// .get_matches_from(vec![ + /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" + /// ]); + /// + /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty + /// // string argument name + /// match m.subcommand() { + /// Some((external, ext_m)) => { + /// let ext_args: Vec<&std::ffi::OsStr> = ext_m.values_of_os("").unwrap().collect(); + /// assert_eq!(external, "subcmd"); + /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); + /// }, + /// _ => {}, + /// } + /// ``` + /// + /// [`ArgMatches::values_of_os`]: crate::ArgMatches::values_of_os() + /// [`ArgMatches::values_of_lossy`]: crate::ArgMatches::values_of_lossy() + /// [`subcommands`]: crate::Command::subcommand() + pub fn allow_invalid_utf8_for_external_subcommands(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::AllowInvalidUtf8ForExternalSubcommands) + } else { + self.unset_setting(AppSettings::AllowInvalidUtf8ForExternalSubcommands) + } + } + + /// Specifies that use of an argument prevents the use of [`subcommands`]. + /// + /// By default `clap` allows arguments between subcommands such + /// as ` [cmd_args] [subcmd_args] [subsubcmd_args]`. + /// + /// This setting disables that functionality and says that arguments can + /// only follow the *final* subcommand. For instance using this setting + /// makes only the following invocations possible: + /// + /// * ` [subsubcmd_args]` + /// * ` [subcmd_args]` + /// * ` [cmd_args]` + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// Command::new("myprog") + /// .args_conflicts_with_subcommands(true); + /// ``` + /// + /// [`subcommands`]: crate::Command::subcommand() + pub fn args_conflicts_with_subcommands(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::ArgsNegateSubcommands) + } else { + self.unset_setting(AppSettings::ArgsNegateSubcommands) + } + } + + /// Prevent subcommands from being consumed as an arguments value. + /// + /// By default, if an option taking multiple values is followed by a subcommand, the + /// subcommand will be parsed as another value. + /// + /// ```text + /// cmd --foo val1 val2 subcommand + /// --------- ---------- + /// values another value + /// ``` + /// + /// This setting instructs the parser to stop when encountering a subcommand instead of + /// greedily consuming arguments. + /// + /// ```text + /// cmd --foo val1 val2 subcommand + /// --------- ---------- + /// values subcommand + /// ``` + /// + /// **Note:** Make sure you apply it as `global_setting` if you want this setting + /// to be propagated to subcommands and sub-subcommands! + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let cmd = Command::new("cmd").subcommand(Command::new("sub")).arg( + /// Arg::new("arg") + /// .long("arg") + /// .multiple_values(true) + /// .takes_value(true), + /// ); + /// + /// let matches = cmd + /// .clone() + /// .try_get_matches_from(&["cmd", "--arg", "1", "2", "3", "sub"]) + /// .unwrap(); + /// assert_eq!( + /// matches.values_of("arg").unwrap().collect::>(), + /// &["1", "2", "3", "sub"] + /// ); + /// assert!(matches.subcommand_matches("sub").is_none()); + /// + /// let matches = cmd + /// .subcommand_precedence_over_arg(true) + /// .try_get_matches_from(&["cmd", "--arg", "1", "2", "3", "sub"]) + /// .unwrap(); + /// assert_eq!( + /// matches.values_of("arg").unwrap().collect::>(), + /// &["1", "2", "3"] + /// ); + /// assert!(matches.subcommand_matches("sub").is_some()); + /// ``` + pub fn subcommand_precedence_over_arg(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::SubcommandPrecedenceOverArg) + } else { + self.unset_setting(AppSettings::SubcommandPrecedenceOverArg) + } + } + + /// Allows [`subcommands`] to override all requirements of the parent command. + /// + /// For example, if you had a subcommand or top level application with a required argument + /// that is only required as long as there is no subcommand present, + /// using this setting would allow you to set those arguments to [`Arg::required(true)`] + /// and yet receive no error so long as the user uses a valid subcommand instead. + /// + /// **NOTE:** This defaults to false (using subcommand does *not* negate requirements) + /// + /// # Examples + /// + /// This first example shows that it is an error to not use a required argument + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let err = Command::new("myprog") + /// .subcommand_negates_reqs(true) + /// .arg(Arg::new("opt").required(true)) + /// .subcommand(Command::new("test")) + /// .try_get_matches_from(vec![ + /// "myprog" + /// ]); + /// assert!(err.is_err()); + /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// # ; + /// ``` + /// + /// This next example shows that it is no longer error to not use a required argument if a + /// valid subcommand is used. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let noerr = Command::new("myprog") + /// .subcommand_negates_reqs(true) + /// .arg(Arg::new("opt").required(true)) + /// .subcommand(Command::new("test")) + /// .try_get_matches_from(vec![ + /// "myprog", "test" + /// ]); + /// assert!(noerr.is_ok()); + /// # ; + /// ``` + /// + /// [`Arg::required(true)`]: crate::Arg::required() + /// [`subcommands`]: crate::Command::subcommand() + pub fn subcommand_negates_reqs(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::SubcommandsNegateReqs) + } else { + self.unset_setting(AppSettings::SubcommandsNegateReqs) + } + } + + /// Multiple-personality program dispatched on the binary name (`argv[0]`) + /// + /// A "multicall" executable is a single executable + /// that contains a variety of applets, + /// and decides which applet to run based on the name of the file. + /// The executable can be called from different names by creating hard links + /// or symbolic links to it. + /// + /// This is desirable for: + /// - Easy distribution, a single binary that can install hardlinks to access the different + /// personalities. + /// - Minimal binary size by sharing common code (e.g. standard library, clap) + /// - Custom shells or REPLs where there isn't a single top-level command + /// + /// Setting `multicall` will cause + /// - `argv[0]` to be stripped to the base name and parsed as the first argument, as if + /// [`Command::no_binary_name`][App::no_binary_name] was set. + /// - Help and errors to report subcommands as if they were the top-level command + /// + /// When the subcommand is not present, there are several strategies you may employ, depending + /// on your needs: + /// - Let the error percolate up normally + /// - Print a specialized error message using the + /// [`Error::context`][crate::Error::context] + /// - Print the [help][App::write_help] but this might be ambiguous + /// - Disable `multicall` and re-parse it + /// - Disable `multicall` and re-parse it with a specific subcommand + /// + /// When detecting the error condition, the [`ErrorKind`] isn't sufficient as a sub-subcommand + /// might report the same error. Enable + /// [`allow_external_subcommands`][App::allow_external_subcommands] if you want to specifically + /// get the unrecognized binary name. + /// + /// **NOTE:** Multicall can't be used with [`no_binary_name`] since they interpret + /// the command name in incompatible ways. + /// + /// **NOTE:** The multicall command cannot have arguments. + /// + /// **NOTE:** Applets are slightly semantically different from subcommands, + /// so it's recommended to use [`Command::subcommand_help_heading`] and + /// [`Command::subcommand_value_name`] to change the descriptive text as above. + /// + /// # Examples + /// + /// `hostname` is an example of a multicall executable. + /// Both `hostname` and `dnsdomainname` are provided by the same executable + /// and which behaviour to use is based on the executable file name. + /// + /// This is desirable when the executable has a primary purpose + /// but there is related functionality that would be convenient to provide + /// and implement it to be in the same executable. + /// + /// The name of the cmd is essentially unused + /// and may be the same as the name of a subcommand. + /// + /// The names of the immediate subcommands of the Command + /// are matched against the basename of the first argument, + /// which is conventionally the path of the executable. + /// + /// This does not allow the subcommand to be passed as the first non-path argument. + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let mut cmd = Command::new("hostname") + /// .multicall(true) + /// .subcommand(Command::new("hostname")) + /// .subcommand(Command::new("dnsdomainname")); + /// let m = cmd.try_get_matches_from_mut(&["/usr/bin/hostname", "dnsdomainname"]); + /// assert!(m.is_err()); + /// assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// let m = cmd.get_matches_from(&["/usr/bin/dnsdomainname"]); + /// assert_eq!(m.subcommand_name(), Some("dnsdomainname")); + /// ``` + /// + /// Busybox is another common example of a multicall executable + /// with a subcommmand for each applet that can be run directly, + /// e.g. with the `cat` applet being run by running `busybox cat`, + /// or with `cat` as a link to the `busybox` binary. + /// + /// This is desirable when the launcher program has additional options + /// or it is useful to run the applet without installing a symlink + /// e.g. to test the applet without installing it + /// or there may already be a command of that name installed. + /// + /// To make an applet usable as both a multicall link and a subcommand + /// the subcommands must be defined both in the top-level Command + /// and as subcommands of the "main" applet. + /// + /// ```rust + /// # use clap::Command; + /// fn applet_commands() -> [Command<'static>; 2] { + /// [Command::new("true"), Command::new("false")] + /// } + /// let mut cmd = Command::new("busybox") + /// .multicall(true) + /// .subcommand( + /// Command::new("busybox") + /// .subcommand_value_name("APPLET") + /// .subcommand_help_heading("APPLETS") + /// .subcommands(applet_commands()), + /// ) + /// .subcommands(applet_commands()); + /// // When called from the executable's canonical name + /// // its applets can be matched as subcommands. + /// let m = cmd.try_get_matches_from_mut(&["/usr/bin/busybox", "true"]).unwrap(); + /// assert_eq!(m.subcommand_name(), Some("busybox")); + /// assert_eq!(m.subcommand().unwrap().1.subcommand_name(), Some("true")); + /// // When called from a link named after an applet that applet is matched. + /// let m = cmd.get_matches_from(&["/usr/bin/true"]); + /// assert_eq!(m.subcommand_name(), Some("true")); + /// ``` + /// + /// [`no_binary_name`]: crate::Command::no_binary_name + /// [`App::subcommand_value_name`]: crate::Command::subcommand_value_name + /// [`App::subcommand_help_heading`]: crate::Command::subcommand_help_heading + #[inline] + pub fn multicall(self, yes: bool) -> Self { + if yes { + self.setting(AppSettings::Multicall) + } else { + self.unset_setting(AppSettings::Multicall) + } + } + + /// Sets the value name used for subcommands when printing usage and help. + /// + /// By default, this is "SUBCOMMAND". + /// + /// See also [`Command::subcommand_help_heading`] + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .subcommand(Command::new("sub1")) + /// .print_help() + /// # ; + /// ``` + /// + /// will produce + /// + /// ```text + /// myprog + /// + /// USAGE: + /// myprog [SUBCOMMAND] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// + /// SUBCOMMANDS: + /// help Print this message or the help of the given subcommand(s) + /// sub1 + /// ``` + /// + /// but usage of `subcommand_value_name` + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .subcommand(Command::new("sub1")) + /// .subcommand_value_name("THING") + /// .print_help() + /// # ; + /// ``` + /// + /// will produce + /// + /// ```text + /// myprog + /// + /// USAGE: + /// myprog [THING] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// + /// SUBCOMMANDS: + /// help Print this message or the help of the given subcommand(s) + /// sub1 + /// ``` + #[must_use] + pub fn subcommand_value_name(mut self, value_name: S) -> Self + where + S: Into<&'help str>, + { + self.subcommand_value_name = Some(value_name.into()); + self + } + + /// Sets the help heading used for subcommands when printing usage and help. + /// + /// By default, this is "SUBCOMMANDS". + /// + /// See also [`Command::subcommand_value_name`] + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .subcommand(Command::new("sub1")) + /// .print_help() + /// # ; + /// ``` + /// + /// will produce + /// + /// ```text + /// myprog + /// + /// USAGE: + /// myprog [SUBCOMMAND] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// + /// SUBCOMMANDS: + /// help Print this message or the help of the given subcommand(s) + /// sub1 + /// ``` + /// + /// but usage of `subcommand_help_heading` + /// + /// ```no_run + /// # use clap::{Command, Arg}; + /// Command::new("myprog") + /// .subcommand(Command::new("sub1")) + /// .subcommand_help_heading("THINGS") + /// .print_help() + /// # ; + /// ``` + /// + /// will produce + /// + /// ```text + /// myprog + /// + /// USAGE: + /// myprog [SUBCOMMAND] + /// + /// OPTIONS: + /// -h, --help Print help information + /// -V, --version Print version information + /// + /// THINGS: + /// help Print this message or the help of the given subcommand(s) + /// sub1 + /// ``` + #[must_use] + pub fn subcommand_help_heading(mut self, heading: T) -> Self + where + T: Into<&'help str>, + { + self.subcommand_heading = Some(heading.into()); + self + } +} + +/// # Reflection +impl<'help> App<'help> { + #[inline] + pub(crate) fn get_usage_name(&self) -> Option<&str> { + self.usage_name.as_deref() + } + + /// Get the name of the binary. + #[inline] + pub fn get_display_name(&self) -> Option<&str> { + self.display_name.as_deref() + } + + /// Get the name of the binary. + #[inline] + pub fn get_bin_name(&self) -> Option<&str> { + self.bin_name.as_deref() + } + + /// Set binary name. Uses `&mut self` instead of `self`. + pub fn set_bin_name>(&mut self, name: S) { + self.bin_name = Some(name.into()); + } + + /// Get the name of the cmd. + #[inline] + pub fn get_name(&self) -> &str { + &self.name + } + + /// Get the version of the cmd. + #[inline] + pub fn get_version(&self) -> Option<&'help str> { + self.version + } + + /// Get the long version of the cmd. + #[inline] + pub fn get_long_version(&self) -> Option<&'help str> { + self.long_version + } + + /// Get the authors of the cmd. + #[inline] + pub fn get_author(&self) -> Option<&'help str> { + self.author + } + + /// Get the short flag of the subcommand. + #[inline] + pub fn get_short_flag(&self) -> Option { + self.short_flag + } + + /// Get the long flag of the subcommand. + #[inline] + pub fn get_long_flag(&self) -> Option<&'help str> { + self.long_flag + } + + /// Get the help message specified via [`Command::about`]. + /// + /// [`App::about`]: Command::about() + #[inline] + pub fn get_about(&self) -> Option<&'help str> { + self.about + } + + /// Get the help message specified via [`Command::long_about`]. + /// + /// [`App::long_about`]: Command::long_about() + #[inline] + pub fn get_long_about(&self) -> Option<&'help str> { + self.long_about + } + + /// Deprecated, replaced with [`Command::get_next_help_heading`] + #[inline] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `App::get_next_help_heading`") + )] + pub fn get_help_heading(&self) -> Option<&'help str> { + self.get_next_help_heading() + } + + /// Get the custom section heading specified via [`Command::help_heading`]. + /// + /// [`App::help_heading`]: Command::help_heading() + #[inline] + pub fn get_next_help_heading(&self) -> Option<&'help str> { + self.current_help_heading + } + + /// Iterate through the *visible* aliases for this subcommand. + #[inline] + pub fn get_visible_aliases(&self) -> impl Iterator + '_ { + self.aliases.iter().filter(|(_, vis)| *vis).map(|a| a.0) + } + + /// Iterate through the *visible* short aliases for this subcommand. + #[inline] + pub fn get_visible_short_flag_aliases(&self) -> impl Iterator + '_ { + self.short_flag_aliases + .iter() + .filter(|(_, vis)| *vis) + .map(|a| a.0) + } + + /// Iterate through the *visible* long aliases for this subcommand. + #[inline] + pub fn get_visible_long_flag_aliases(&self) -> impl Iterator + '_ { + self.long_flag_aliases + .iter() + .filter(|(_, vis)| *vis) + .map(|a| a.0) + } + + /// Iterate through the set of *all* the aliases for this subcommand, both visible and hidden. + #[inline] + pub fn get_all_aliases(&self) -> impl Iterator + '_ { + self.aliases.iter().map(|a| a.0) + } + + /// Iterate through the set of *all* the short aliases for this subcommand, both visible and hidden. + #[inline] + pub fn get_all_short_flag_aliases(&self) -> impl Iterator + '_ { + self.short_flag_aliases.iter().map(|a| a.0) + } + + /// Iterate through the set of *all* the long aliases for this subcommand, both visible and hidden. + #[inline] + pub fn get_all_long_flag_aliases(&self) -> impl Iterator + '_ { + self.long_flag_aliases.iter().map(|a| a.0) + } + + /// Check if the given [`AppSettings`] variant is currently set on the `Command`. + /// + /// This checks both [local] and [global settings]. + /// + /// [local]: Command::setting() + /// [global settings]: Command::global_setting() + #[inline] + pub fn is_set(&self, s: AppSettings) -> bool { + self.settings.is_set(s) || self.g_settings.is_set(s) + } + + /// Should we color the output? + #[inline(never)] + pub fn get_color(&self) -> ColorChoice { + debug!("Command::color: Color setting..."); + + if cfg!(feature = "color") { + #[allow(deprecated)] + if self.is_set(AppSettings::ColorNever) { + debug!("Never"); + ColorChoice::Never + } else if self.is_set(AppSettings::ColorAlways) { + debug!("Always"); + ColorChoice::Always + } else { + debug!("Auto"); + ColorChoice::Auto + } + } else { + ColorChoice::Never + } + } + + /// Iterate through the set of subcommands, getting a reference to each. + #[inline] + pub fn get_subcommands(&self) -> impl Iterator> { + self.subcommands.iter() + } + + /// Iterate through the set of subcommands, getting a mutable reference to each. + #[inline] + pub fn get_subcommands_mut(&mut self) -> impl Iterator> { + self.subcommands.iter_mut() + } + + /// Returns `true` if this `Command` has subcommands. + #[inline] + pub fn has_subcommands(&self) -> bool { + !self.subcommands.is_empty() + } + + /// Returns the help heading for listing subcommands. + #[inline] + pub fn get_subcommand_help_heading(&self) -> Option<&str> { + self.subcommand_heading + } + + /// Deprecated, replaced with [`App::get_subcommand_help_heading`] + #[inline] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `App::get_subcommand_help_heading`" + ) + )] + pub fn get_subommand_help_heading(&self) -> Option<&str> { + self.get_subcommand_help_heading() + } + + /// Returns the subcommand value name. + #[inline] + pub fn get_subcommand_value_name(&self) -> Option<&str> { + self.subcommand_value_name + } + + /// Returns the help heading for listing subcommands. + #[inline] + pub fn get_before_help(&self) -> Option<&str> { + self.before_help + } + + /// Returns the help heading for listing subcommands. + #[inline] + pub fn get_before_long_help(&self) -> Option<&str> { + self.before_long_help + } + + /// Returns the help heading for listing subcommands. + #[inline] + pub fn get_after_help(&self) -> Option<&str> { + self.after_help + } + + /// Returns the help heading for listing subcommands. + #[inline] + pub fn get_after_long_help(&self) -> Option<&str> { + self.after_long_help + } + + /// Find subcommand such that its name or one of aliases equals `name`. + /// + /// This does not recurse through subcommands of subcommands. + #[inline] + pub fn find_subcommand(&self, name: &T) -> Option<&App<'help>> + where + T: PartialEq + ?Sized, + { + self.get_subcommands().find(|s| s.aliases_to(name)) + } + + /// Find subcommand such that its name or one of aliases equals `name`, returning + /// a mutable reference to the subcommand. + /// + /// This does not recurse through subcommands of subcommands. + #[inline] + pub fn find_subcommand_mut(&mut self, name: &T) -> Option<&mut App<'help>> + where + T: PartialEq + ?Sized, + { + self.get_subcommands_mut().find(|s| s.aliases_to(name)) + } + + /// Iterate through the set of groups. + #[inline] + pub fn get_groups(&self) -> impl Iterator> { + self.groups.iter() + } + + /// Iterate through the set of arguments. + #[inline] + pub fn get_arguments(&self) -> impl Iterator> { + self.args.args() + } + + /// Iterate through the *positionals* arguments. + #[inline] + pub fn get_positionals(&self) -> impl Iterator> { + self.get_arguments().filter(|a| a.is_positional()) + } + + /// Iterate through the *options*. + pub fn get_opts(&self) -> impl Iterator> { + self.get_arguments() + .filter(|a| a.is_takes_value_set() && !a.is_positional()) + } + + /// Get a list of all arguments the given argument conflicts with. + /// + /// If the provided argument is declared as global, the conflicts will be determined + /// based on the propagation rules of global arguments. + /// + /// ### Panics + /// + /// If the given arg contains a conflict with an argument that is unknown to + /// this `Command`. + pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator + { + if arg.is_global_set() { + self.get_global_arg_conflicts_with(arg) + } else { + let mut result = Vec::new(); + for id in arg.blacklist.iter() { + if let Some(arg) = self.find(id) { + result.push(arg); + } else if let Some(group) = self.find_group(id) { + result.extend( + self.unroll_args_in_group(&group.id) + .iter() + .map(|id| self.find(id).expect(INTERNAL_ERROR_MSG)), + ); + } else { + panic!("Command::get_arg_conflicts_with: The passed arg conflicts with an arg unknown to the cmd"); + } + } + result + } + } + + // Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with. + // + // This behavior follows the propagation rules of global arguments. + // It is useful for finding conflicts for arguments declared as global. + // + // ### Panics + // + // If the given arg contains a conflict with an argument that is unknown to + // this `App`. + fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator + { + arg.blacklist + .iter() + .map(|id| { + self.args + .args() + .chain( + self.get_subcommands_containing(arg) + .iter() + .flat_map(|x| x.args.args()), + ) + .find(|arg| arg.id == *id) + .expect( + "Command::get_arg_conflicts_with: \ + The passed arg conflicts with an arg unknown to the cmd", + ) + }) + .collect() + } + + // Get a list of subcommands which contain the provided Argument + // + // This command will only include subcommands in its list for which the subcommands + // parent also contains the Argument. + // + // This search follows the propagation rules of global arguments. + // It is useful to finding subcommands, that have inherited a global argument. + // + // **NOTE:** In this case only Sucommand_1 will be included + // Subcommand_1 (contains Arg) + // Subcommand_1.1 (doesn't contain Arg) + // Subcommand_1.1.1 (contains Arg) + // + fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>> { + let mut vec = std::vec::Vec::new(); + for idx in 0..self.subcommands.len() { + if self.subcommands[idx].args.args().any(|ar| ar.id == arg.id) { + vec.push(&self.subcommands[idx]); + vec.append(&mut self.subcommands[idx].get_subcommands_containing(arg)); + } + } + vec + } + + /// Report whether [`Command::no_binary_name`] is set + pub fn is_no_binary_name_set(&self) -> bool { + self.is_set(AppSettings::NoBinaryName) + } + + /// Report whether [`Command::ignore_errors`] is set + pub(crate) fn is_ignore_errors_set(&self) -> bool { + self.is_set(AppSettings::IgnoreErrors) + } + + /// Report whether [`Command::dont_delimit_trailing_values`] is set + pub fn is_dont_delimit_trailing_values_set(&self) -> bool { + self.is_set(AppSettings::DontDelimitTrailingValues) + } + + /// Report whether [`Command::disable_version_flag`] is set + pub fn is_disable_version_flag_set(&self) -> bool { + self.is_set(AppSettings::DisableVersionFlag) + } + + /// Report whether [`Command::propagate_version`] is set + pub fn is_propagate_version_set(&self) -> bool { + self.is_set(AppSettings::PropagateVersion) + } + + /// Report whether [`Command::next_line_help`] is set + pub fn is_next_line_help_set(&self) -> bool { + self.is_set(AppSettings::NextLineHelp) + } + + /// Report whether [`Command::disable_help_flag`] is set + pub fn is_disable_help_flag_set(&self) -> bool { + self.is_set(AppSettings::DisableHelpFlag) + } + + /// Report whether [`Command::disable_help_subcommand`] is set + pub fn is_disable_help_subcommand_set(&self) -> bool { + self.is_set(AppSettings::DisableHelpSubcommand) + } + + /// Report whether [`Command::disable_colored_help`] is set + pub fn is_disable_colored_help_set(&self) -> bool { + self.is_set(AppSettings::DisableColoredHelp) + } + + /// Report whether [`Command::help_expected`] is set + #[cfg(debug_assertions)] + pub(crate) fn is_help_expected_set(&self) -> bool { + self.is_set(AppSettings::HelpExpected) + } + + /// Report whether [`Command::dont_collapse_args_in_usage`] is set + pub fn is_dont_collapse_args_in_usage_set(&self) -> bool { + self.is_set(AppSettings::DontCollapseArgsInUsage) + } + + /// Report whether [`Command::infer_long_args`] is set + pub(crate) fn is_infer_long_args_set(&self) -> bool { + self.is_set(AppSettings::InferLongArgs) + } + + /// Report whether [`Command::infer_subcommands`] is set + pub(crate) fn is_infer_subcommands_set(&self) -> bool { + self.is_set(AppSettings::InferSubcommands) + } + + /// Report whether [`Command::arg_required_else_help`] is set + pub fn is_arg_required_else_help_set(&self) -> bool { + self.is_set(AppSettings::ArgRequiredElseHelp) + } + + /// Report whether [`Command::allow_hyphen_values`] is set + pub(crate) fn is_allow_hyphen_values_set(&self) -> bool { + self.is_set(AppSettings::AllowHyphenValues) + } + + /// Report whether [`Command::allow_negative_numbers`] is set + pub fn is_allow_negative_numbers_set(&self) -> bool { + self.is_set(AppSettings::AllowNegativeNumbers) + } + + /// Report whether [`Command::trailing_var_arg`] is set + pub fn is_trailing_var_arg_set(&self) -> bool { + self.is_set(AppSettings::TrailingVarArg) + } + + /// Report whether [`Command::allow_missing_positional`] is set + pub fn is_allow_missing_positional_set(&self) -> bool { + self.is_set(AppSettings::AllowMissingPositional) + } + + /// Report whether [`Command::hide`] is set + pub fn is_hide_set(&self) -> bool { + self.is_set(AppSettings::Hidden) + } + + /// Report whether [`Command::subcommand_required`] is set + pub fn is_subcommand_required_set(&self) -> bool { + self.is_set(AppSettings::SubcommandRequired) + } + + /// Report whether [`Command::allow_external_subcommands`] is set + pub fn is_allow_external_subcommands_set(&self) -> bool { + self.is_set(AppSettings::AllowExternalSubcommands) + } + + /// Report whether [`Command::allow_invalid_utf8_for_external_subcommands`] is set + pub fn is_allow_invalid_utf8_for_external_subcommands_set(&self) -> bool { + self.is_set(AppSettings::AllowInvalidUtf8ForExternalSubcommands) + } + + /// Configured parser for values passed to an external subcommand + /// + /// # Example + /// + /// ```rust + /// let cmd = clap::Command::new("raw") + /// .allow_external_subcommands(true) + /// .allow_invalid_utf8_for_external_subcommands(true); + /// let value_parser = cmd.get_external_subcommand_value_parser(); + /// println!("{:?}", value_parser); + /// ``` + pub fn get_external_subcommand_value_parser(&self) -> Option<&super::ValueParser> { + if !self.is_allow_external_subcommands_set() { + None + } else if self.is_allow_invalid_utf8_for_external_subcommands_set() { + static DEFAULT: super::ValueParser = super::ValueParser::os_string(); + Some(&DEFAULT) + } else { + static DEFAULT: super::ValueParser = super::ValueParser::string(); + Some(&DEFAULT) + } + } + + /// Report whether [`Command::args_conflicts_with_subcommands`] is set + pub fn is_args_conflicts_with_subcommands_set(&self) -> bool { + self.is_set(AppSettings::ArgsNegateSubcommands) + } + + /// Report whether [`Command::subcommand_precedence_over_arg`] is set + pub fn is_subcommand_precedence_over_arg_set(&self) -> bool { + self.is_set(AppSettings::SubcommandPrecedenceOverArg) + } + + /// Report whether [`Command::subcommand_negates_reqs`] is set + pub fn is_subcommand_negates_reqs_set(&self) -> bool { + self.is_set(AppSettings::SubcommandsNegateReqs) + } + + /// Report whether [`Command::multicall`] is set + pub fn is_multicall_set(&self) -> bool { + self.is_set(AppSettings::Multicall) + } +} + +/// Deprecated +impl<'help> App<'help> { + /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? + #[cfg(feature = "yaml")] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" + ) + )] + #[doc(hidden)] + pub fn from_yaml(y: &'help Yaml) -> Self { + #![allow(deprecated)] + let yaml_file_hash = y.as_hash().expect("YAML file must be a hash"); + // We WANT this to panic on error...so expect() is good. + let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() { + (App::new(name), yaml_file_hash, "cmd".into()) + } else { + let (name_yaml, value_yaml) = yaml_file_hash + .iter() + .next() + .expect("There must be one subcommand in the YAML file"); + let name_str = name_yaml + .as_str() + .expect("Subcommand name must be a string"); + + ( + App::new(name_str), + value_yaml.as_hash().expect("Subcommand must be a hash"), + format!("subcommand '{}'", name_str), + ) + }; + + for (k, v) in yaml { + a = match k.as_str().expect("App fields must be strings") { + "version" => yaml_to_str!(a, v, version), + "long_version" => yaml_to_str!(a, v, long_version), + "author" => yaml_to_str!(a, v, author), + "bin_name" => yaml_to_str!(a, v, bin_name), + "about" => yaml_to_str!(a, v, about), + "long_about" => yaml_to_str!(a, v, long_about), + "before_help" => yaml_to_str!(a, v, before_help), + "after_help" => yaml_to_str!(a, v, after_help), + "template" => yaml_to_str!(a, v, help_template), + "usage" => yaml_to_str!(a, v, override_usage), + "help" => yaml_to_str!(a, v, override_help), + "help_message" => yaml_to_str!(a, v, help_message), + "version_message" => yaml_to_str!(a, v, version_message), + "alias" => yaml_to_str!(a, v, alias), + "aliases" => yaml_vec_or_str!(a, v, alias), + "visible_alias" => yaml_to_str!(a, v, visible_alias), + "visible_aliases" => yaml_vec_or_str!(a, v, visible_alias), + "display_order" => yaml_to_usize!(a, v, display_order), + "args" => { + if let Some(vec) = v.as_vec() { + for arg_yaml in vec { + a = a.arg(Arg::from_yaml(arg_yaml)); + } + } else { + panic!("Failed to convert YAML value {:?} to a vec", v); + } + a + } + "subcommands" => { + if let Some(vec) = v.as_vec() { + for sc_yaml in vec { + a = a.subcommand(App::from_yaml(sc_yaml)); + } + } else { + panic!("Failed to convert YAML value {:?} to a vec", v); + } + a + } + "groups" => { + if let Some(vec) = v.as_vec() { + for ag_yaml in vec { + a = a.group(ArgGroup::from(ag_yaml)); + } + } else { + panic!("Failed to convert YAML value {:?} to a vec", v); + } + a + } + "setting" | "settings" => { + yaml_to_setting!(a, v, setting, AppSettings, "AppSetting", err) + } + "global_setting" | "global_settings" => { + yaml_to_setting!(a, v, global_setting, AppSettings, "AppSetting", err) + } + _ => a, + } + } + + a + } + + /// Deprecated, replaced with [`Command::override_usage`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::override_usage`") + )] + #[doc(hidden)] + #[must_use] + pub fn usage>(self, usage: S) -> Self { + self.override_usage(usage) + } + + /// Deprecated, replaced with [`Command::override_help`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::override_help`") + )] + #[doc(hidden)] + #[must_use] + pub fn help>(self, help: S) -> Self { + self.override_help(help) + } + + /// Deprecated, replaced with [`Command::mut_arg`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") + )] + #[doc(hidden)] + #[must_use] + pub fn help_short(self, c: char) -> Self { + self.mut_arg("help", |a| a.short(c)) + } + + /// Deprecated, replaced with [`Command::mut_arg`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") + )] + #[doc(hidden)] + #[must_use] + pub fn version_short(self, c: char) -> Self { + self.mut_arg("version", |a| a.short(c)) + } + + /// Deprecated, replaced with [`Command::mut_arg`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") + )] + #[doc(hidden)] + #[must_use] + pub fn help_message(self, s: impl Into<&'help str>) -> Self { + self.mut_arg("help", |a| a.help(s.into())) + } + + /// Deprecated, replaced with [`Command::mut_arg`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") + )] + #[doc(hidden)] + #[must_use] + pub fn version_message(self, s: impl Into<&'help str>) -> Self { + self.mut_arg("version", |a| a.help(s.into())) + } + + /// Deprecated, replaced with [`Command::help_template`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::help_template`") + )] + #[doc(hidden)] + #[must_use] + pub fn template>(self, s: S) -> Self { + self.help_template(s) + } + + /// Deprecated, replaced with [`Command::setting(a| b)`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::setting(a | b)`") + )] + #[doc(hidden)] + #[must_use] + pub fn settings(mut self, settings: &[AppSettings]) -> Self { + for s in settings { + self.settings.insert((*s).into()); + } + self + } + + /// Deprecated, replaced with [`Command::unset_setting(a| b)`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::unset_setting(a | b)`") + )] + #[doc(hidden)] + #[must_use] + pub fn unset_settings(mut self, settings: &[AppSettings]) -> Self { + for s in settings { + self.settings.remove((*s).into()); + } + self + } + + /// Deprecated, replaced with [`Command::global_setting(a| b)`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::global_setting(a | b)`") + )] + #[doc(hidden)] + #[must_use] + pub fn global_settings(mut self, settings: &[AppSettings]) -> Self { + for s in settings { + self.settings.insert((*s).into()); + self.g_settings.insert((*s).into()); + } + self + } + + /// Deprecated, replaced with [`Command::term_width`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::term_width`") + )] + #[doc(hidden)] + #[must_use] + pub fn set_term_width(self, width: usize) -> Self { + self.term_width(width) + } + + /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!]. + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!") + )] + #[doc(hidden)] + #[must_use] + pub fn arg_from_usage(self, usage: &'help str) -> Self { + #![allow(deprecated)] + self.arg(Arg::from_usage(usage)) + } + + /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!]. + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!") + )] + #[doc(hidden)] + #[must_use] + pub fn args_from_usage(mut self, usage: &'help str) -> Self { + #![allow(deprecated)] + for line in usage.lines() { + let l = line.trim(); + if l.is_empty() { + continue; + } + self = self.arg(Arg::from_usage(l)); + } + self + } + + /// Deprecated, replaced with [`Command::render_version`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::render_version`") + )] + #[doc(hidden)] + pub fn write_version(&self, w: &mut W) -> ClapResult<()> { + write!(w, "{}", self.render_version()).map_err(From::from) + } + + /// Deprecated, replaced with [`Command::render_long_version`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::render_long_version`") + )] + #[doc(hidden)] + pub fn write_long_version(&self, w: &mut W) -> ClapResult<()> { + write!(w, "{}", self.render_long_version()).map_err(From::from) + } + + /// Deprecated, replaced with [`Command::try_get_matches`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches`") + )] + #[doc(hidden)] + pub fn get_matches_safe(self) -> ClapResult { + self.try_get_matches() + } + + /// Deprecated, replaced with [`Command::try_get_matches_from`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches_from`") + )] + #[doc(hidden)] + pub fn get_matches_from_safe(self, itr: I) -> ClapResult + where + I: IntoIterator, + T: Into + Clone, + { + self.try_get_matches_from(itr) + } + + /// Deprecated, replaced with [`Command::try_get_matches_from_mut`] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `App::try_get_matches_from_mut`" + ) + )] + #[doc(hidden)] + pub fn get_matches_from_safe_borrow(&mut self, itr: I) -> ClapResult + where + I: IntoIterator, + T: Into + Clone, + { + self.try_get_matches_from_mut(itr) + } +} + +// Internally used only +impl<'help> App<'help> { + pub(crate) fn get_id(&self) -> Id { + self.id.clone() + } + + pub(crate) fn get_override_usage(&self) -> Option<&str> { + self.usage_str + } + + pub(crate) fn get_override_help(&self) -> Option<&str> { + self.help_str + } + + pub(crate) fn get_help_template(&self) -> Option<&str> { + self.template + } + + pub(crate) fn get_term_width(&self) -> Option { + self.term_w + } + + pub(crate) fn get_max_term_width(&self) -> Option { + self.max_w + } + + pub(crate) fn get_replacement(&self, key: &str) -> Option<&[&str]> { + self.replacers.get(key).copied() + } + + pub(crate) fn get_keymap(&self) -> &MKeyMap<'help> { + &self.args + } + + fn get_used_global_args(&self, matches: &ArgMatches, global_arg_vec: &mut Vec) { + global_arg_vec.extend( + self.args + .args() + .filter(|a| a.is_global_set()) + .map(|ga| ga.id.clone()), + ); + if let Some((id, matches)) = matches.subcommand() { + if let Some(used_sub) = self.find_subcommand(id) { + used_sub.get_used_global_args(matches, global_arg_vec); + } + } + } + + fn _do_parse( + &mut self, + raw_args: &mut clap_lex::RawArgs, + args_cursor: clap_lex::ArgCursor, + ) -> ClapResult { + debug!("Command::_do_parse"); + + // If there are global arguments, or settings we need to propagate them down to subcommands + // before parsing in case we run into a subcommand + self._build_self(); + + let mut matcher = ArgMatcher::new(self); + + // do the real parsing + let mut parser = Parser::new(self); + if let Err(error) = parser.get_matches_with(&mut matcher, raw_args, args_cursor) { + if self.is_set(AppSettings::IgnoreErrors) { + debug!("Command::_do_parse: ignoring error: {}", error); + } else { + return Err(error); + } + } + + let mut global_arg_vec = Default::default(); + self.get_used_global_args(&matcher, &mut global_arg_vec); + + matcher.propagate_globals(&global_arg_vec); + + Ok(matcher.into_inner()) + } + + #[doc(hidden)] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.10", note = "Replaced with `Command::build`") + )] + pub fn _build_all(&mut self) { + self.build(); + } + + #[doc(hidden)] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.10", note = "Replaced with `Command::build`") + )] + pub fn _build(&mut self) { + self._build_self() + } + + #[doc(hidden)] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.13", note = "Replaced with `Command::build`") + )] + pub fn _build_bin_names(&mut self) { + self._build_bin_names_internal(); + } + + /// Prepare for introspecting on all included [`Command`]s + /// + /// Call this on the top-level [`Command`] when done building and before reading state for + /// cases like completions, custom help output, etc. + pub fn build(&mut self) { + self._build_recursive(); + self._build_bin_names_internal(); + } + + pub(crate) fn _build_recursive(&mut self) { + self._build_self(); + for subcmd in self.get_subcommands_mut() { + subcmd._build_recursive(); + } + } + + pub(crate) fn _build_self(&mut self) { + debug!("Command::_build: name={:?}", self.get_name()); + if !self.settings.is_set(AppSettings::Built) { + // Make sure all the globally set flags apply to us as well + self.settings = self.settings | self.g_settings; + + if self.is_multicall_set() { + self.settings.insert(AppSettings::SubcommandRequired.into()); + self.settings.insert(AppSettings::DisableHelpFlag.into()); + self.settings.insert(AppSettings::DisableVersionFlag.into()); + } + + self._propagate(); + self._check_help_and_version(); + self._propagate_global_args(); + self._derive_display_order(); + + let mut pos_counter = 1; + let self_override = self.is_set(AppSettings::AllArgsOverrideSelf); + let hide_pv = self.is_set(AppSettings::HidePossibleValues); + let auto_help = + !self.is_set(AppSettings::NoAutoHelp) && !self.is_disable_help_flag_set(); + let auto_version = + !self.is_set(AppSettings::NoAutoVersion) && !self.is_disable_version_flag_set(); + for a in self.args.args_mut() { + // Fill in the groups + for g in &a.groups { + if let Some(ag) = self.groups.iter_mut().find(|grp| grp.id == *g) { + ag.args.push(a.id.clone()); + } else { + let mut ag = ArgGroup::with_id(g.clone()); + ag.args.push(a.id.clone()); + self.groups.push(ag); + } + } + + // Figure out implied settings + if a.is_last_set() { + // if an arg has `Last` set, we need to imply DontCollapseArgsInUsage so that args + // in the usage string don't get confused or left out. + self.settings.set(AppSettings::DontCollapseArgsInUsage); + } + if hide_pv && a.is_takes_value_set() { + a.settings.set(ArgSettings::HidePossibleValues); + } + if self_override { + let self_id = a.id.clone(); + a.overrides.push(self_id); + } + a._build(); + // HACK: Setting up action at this level while auto-help / disable help flag is + // required. Otherwise, most of this won't be needed because when we can break + // compat, actions will reign supreme (default to `Store`) + if a.action.is_none() { + if a.get_id() == "help" && auto_help && !a.is_takes_value_set() { + let action = super::ArgAction::Help; + a.action = Some(action); + } else if a.get_id() == "version" && auto_version && !a.is_takes_value_set() { + let action = super::ArgAction::Version; + a.action = Some(action); + } else if a.is_takes_value_set() { + let action = super::ArgAction::StoreValue; + a.action = Some(action); + } else { + let action = super::ArgAction::IncOccurrence; + a.action = Some(action); + } + } + if a.is_positional() && a.index.is_none() { + a.index = Some(pos_counter); + pos_counter += 1; + } + } + + self.args._build(); + + #[cfg(debug_assertions)] + assert_app(self); + self.settings.set(AppSettings::Built); + } else { + debug!("Command::_build: already built"); + } + } + + pub(crate) fn _build_subcommand(&mut self, name: &str) -> Option<&mut Self> { + use std::fmt::Write; + + let mut mid_string = String::from(" "); + if !self.is_subcommand_negates_reqs_set() && !self.is_args_conflicts_with_subcommands_set() + { + let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m) + + for s in &reqs { + mid_string.push_str(s); + mid_string.push(' '); + } + } + let is_multicall_set = self.is_multicall_set(); + + let sc = self.subcommands.iter_mut().find(|s| s.name == name)?; + + // Display subcommand name, short and long in usage + let mut sc_names = sc.name.clone(); + let mut flag_subcmd = false; + if let Some(l) = sc.long_flag { + write!(sc_names, "|--{}", l).unwrap(); + flag_subcmd = true; + } + if let Some(s) = sc.short_flag { + write!(sc_names, "|-{}", s).unwrap(); + flag_subcmd = true; + } + + if flag_subcmd { + sc_names = format!("{{{}}}", sc_names); + } + + let usage_name = self + .bin_name + .as_ref() + .map(|bin_name| format!("{}{}{}", bin_name, mid_string, sc_names)) + .unwrap_or(sc_names); + sc.usage_name = Some(usage_name); + + // bin_name should be parent's bin_name + [] + the sc's name separated by + // a space + let bin_name = format!( + "{}{}{}", + self.bin_name.as_ref().unwrap_or(&String::new()), + if self.bin_name.is_some() { " " } else { "" }, + &*sc.name + ); + debug!( + "Command::_build_subcommand Setting bin_name of {} to {:?}", + sc.name, bin_name + ); + sc.bin_name = Some(bin_name); + + if sc.display_name.is_none() { + let self_display_name = if is_multicall_set { + self.display_name.as_deref().unwrap_or("") + } else { + self.display_name.as_deref().unwrap_or(&self.name) + }; + let display_name = format!( + "{}{}{}", + self_display_name, + if !self_display_name.is_empty() { + "-" + } else { + "" + }, + &*sc.name + ); + debug!( + "Command::_build_subcommand Setting display_name of {} to {:?}", + sc.name, display_name + ); + sc.display_name = Some(display_name); + } + + // Ensure all args are built and ready to parse + sc._build_self(); + + Some(sc) + } + + fn _build_bin_names_internal(&mut self) { + debug!("Command::_build_bin_names"); + + if !self.is_set(AppSettings::BinNameBuilt) { + let mut mid_string = String::from(" "); + if !self.is_subcommand_negates_reqs_set() + && !self.is_args_conflicts_with_subcommands_set() + { + let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m) + + for s in &reqs { + mid_string.push_str(s); + mid_string.push(' '); + } + } + let is_multicall_set = self.is_multicall_set(); + + let self_bin_name = if is_multicall_set { + self.bin_name.as_deref().unwrap_or("") + } else { + self.bin_name.as_deref().unwrap_or(&self.name) + } + .to_owned(); + + for mut sc in &mut self.subcommands { + debug!("Command::_build_bin_names:iter: bin_name set..."); + + if sc.usage_name.is_none() { + use std::fmt::Write; + // Display subcommand name, short and long in usage + let mut sc_names = sc.name.clone(); + let mut flag_subcmd = false; + if let Some(l) = sc.long_flag { + write!(sc_names, "|--{}", l).unwrap(); + flag_subcmd = true; + } + if let Some(s) = sc.short_flag { + write!(sc_names, "|-{}", s).unwrap(); + flag_subcmd = true; + } + + if flag_subcmd { + sc_names = format!("{{{}}}", sc_names); + } + + let usage_name = format!("{}{}{}", self_bin_name, mid_string, sc_names); + debug!( + "Command::_build_bin_names:iter: Setting usage_name of {} to {:?}", + sc.name, usage_name + ); + sc.usage_name = Some(usage_name); + } else { + debug!( + "Command::_build_bin_names::iter: Using existing usage_name of {} ({:?})", + sc.name, sc.usage_name + ); + } + + if sc.bin_name.is_none() { + let bin_name = format!( + "{}{}{}", + self_bin_name, + if !self_bin_name.is_empty() { " " } else { "" }, + &*sc.name + ); + debug!( + "Command::_build_bin_names:iter: Setting bin_name of {} to {:?}", + sc.name, bin_name + ); + sc.bin_name = Some(bin_name); + } else { + debug!( + "Command::_build_bin_names::iter: Using existing bin_name of {} ({:?})", + sc.name, sc.bin_name + ); + } + + if sc.display_name.is_none() { + let self_display_name = if is_multicall_set { + self.display_name.as_deref().unwrap_or("") + } else { + self.display_name.as_deref().unwrap_or(&self.name) + }; + let display_name = format!( + "{}{}{}", + self_display_name, + if !self_display_name.is_empty() { + "-" + } else { + "" + }, + &*sc.name + ); + debug!( + "Command::_build_bin_names:iter: Setting display_name of {} to {:?}", + sc.name, display_name + ); + sc.display_name = Some(display_name); + } else { + debug!( + "Command::_build_bin_names::iter: Using existing display_name of {} ({:?})", + sc.name, sc.display_name + ); + } + + sc._build_bin_names_internal(); + } + self.set(AppSettings::BinNameBuilt); + } else { + debug!("Command::_build_bin_names: already built"); + } + } + + pub(crate) fn _panic_on_missing_help(&self, help_required_globally: bool) { + if self.is_set(AppSettings::HelpExpected) || help_required_globally { + let args_missing_help: Vec = self + .args + .args() + .filter(|arg| arg.help.is_none() && arg.long_help.is_none()) + .map(|arg| String::from(arg.name)) + .collect(); + + assert!(args_missing_help.is_empty(), + "Command::help_expected is enabled for the Command {}, but at least one of its arguments does not have either `help` or `long_help` set. List of such arguments: {}", + self.name, + args_missing_help.join(", ") + ); + } + + for sub_app in &self.subcommands { + sub_app._panic_on_missing_help(help_required_globally); + } + } + + #[cfg(debug_assertions)] + pub(crate) fn two_args_of(&self, condition: F) -> Option<(&Arg<'help>, &Arg<'help>)> + where + F: Fn(&Arg) -> bool, + { + two_elements_of(self.args.args().filter(|a: &&Arg| condition(a))) + } + + // just in case + #[allow(unused)] + fn two_groups_of(&self, condition: F) -> Option<(&ArgGroup, &ArgGroup)> + where + F: Fn(&ArgGroup) -> bool, + { + two_elements_of(self.groups.iter().filter(|a| condition(a))) + } + + /// Propagate global args + pub(crate) fn _propagate_global_args(&mut self) { + debug!("Command::_propagate_global_args:{}", self.name); + + for sc in &mut self.subcommands { + for a in self.args.args().filter(|a| a.is_global_set()) { + let mut propagate = false; + let is_generated = matches!( + a.provider, + ArgProvider::Generated | ArgProvider::GeneratedMutated + ); + + // Remove generated help and version args in the subcommand + // + // Don't remove if those args are further mutated + if is_generated { + let generated_pos = sc + .args + .args() + .position(|x| x.id == a.id && x.provider == ArgProvider::Generated); + + if let Some(index) = generated_pos { + debug!( + "Command::_propagate removing {}'s {:?}", + sc.get_name(), + a.id + ); + sc.args.remove(index); + propagate = true; + } + } + + if propagate || sc.find(&a.id).is_none() { + debug!( + "Command::_propagate pushing {:?} to {}", + a.id, + sc.get_name(), + ); + sc.args.push(a.clone()); + } + } + } + } + + /// Propagate settings + pub(crate) fn _propagate(&mut self) { + debug!("Command::_propagate:{}", self.name); + let mut subcommands = std::mem::take(&mut self.subcommands); + for sc in &mut subcommands { + self._propagate_subcommand(sc); + } + self.subcommands = subcommands; + } + + fn _propagate_subcommand(&self, sc: &mut Self) { + // We have to create a new scope in order to tell rustc the borrow of `sc` is + // done and to recursively call this method + { + if self.settings.is_set(AppSettings::PropagateVersion) { + if sc.version.is_none() && self.version.is_some() { + sc.version = Some(self.version.unwrap()); + } + if sc.long_version.is_none() && self.long_version.is_some() { + sc.long_version = Some(self.long_version.unwrap()); + } + } + + sc.settings = sc.settings | self.g_settings; + sc.g_settings = sc.g_settings | self.g_settings; + sc.term_w = self.term_w; + sc.max_w = self.max_w; + } + } + + #[allow(clippy::blocks_in_if_conditions)] + pub(crate) fn _check_help_and_version(&mut self) { + debug!("Command::_check_help_and_version: {}", self.name); + + if self.is_set(AppSettings::DisableHelpFlag) + || self.args.args().any(|x| { + x.provider == ArgProvider::User + && (x.long == Some("help") || x.id == Id::help_hash()) + }) + || self + .subcommands + .iter() + .any(|sc| sc.long_flag == Some("help")) + { + debug!("Command::_check_help_and_version: Removing generated help"); + + let generated_help_pos = self + .args + .args() + .position(|x| x.id == Id::help_hash() && x.provider == ArgProvider::Generated); + + if let Some(index) = generated_help_pos { + self.args.remove(index); + } + } else { + let help = self + .args + .args() + .find(|x| x.id == Id::help_hash()) + .expect(INTERNAL_ERROR_MSG); + assert_ne!(help.provider, ArgProvider::User); + + if help.short.is_some() { + if help.short == Some('h') { + if let Some(other_arg) = self + .args + .args() + .find(|x| x.id != Id::help_hash() && x.short == Some('h')) + { + panic!( + "`help`s `-h` conflicts with `{}`. + +To change `help`s short, call `cmd.arg(Arg::new(\"help\")...)`.", + other_arg.name + ); + } + } + } else if !(self.args.args().any(|x| x.short == Some('h')) + || self.subcommands.iter().any(|sc| sc.short_flag == Some('h'))) + { + let help = self + .args + .args_mut() + .find(|x| x.id == Id::help_hash()) + .expect(INTERNAL_ERROR_MSG); + help.short = Some('h'); + } else { + debug!("Command::_check_help_and_version: Removing `-h` from help"); + } + } + + // Determine if we should remove the generated --version flag + // + // Note that if only mut_arg() was used, the first expression will evaluate to `true` + // however inside the condition block, we only check for Generated args, not + // GeneratedMutated args, so the `mut_arg("version", ..) will be skipped and fall through + // to the following condition below (Adding the short `-V`) + if self.settings.is_set(AppSettings::DisableVersionFlag) + || (self.version.is_none() && self.long_version.is_none()) + || self.args.args().any(|x| { + x.provider == ArgProvider::User + && (x.long == Some("version") || x.id == Id::version_hash()) + }) + || self + .subcommands + .iter() + .any(|sc| sc.long_flag == Some("version")) + { + debug!("Command::_check_help_and_version: Removing generated version"); + + // This is the check mentioned above that only checks for Generated, not + // GeneratedMutated args by design. + let generated_version_pos = self + .args + .args() + .position(|x| x.id == Id::version_hash() && x.provider == ArgProvider::Generated); + + if let Some(index) = generated_version_pos { + self.args.remove(index); + } + } + + // If we still have a generated --version flag, determine if we can apply the short `-V` + if self.args.args().any(|x| { + x.id == Id::version_hash() + && matches!( + x.provider, + ArgProvider::Generated | ArgProvider::GeneratedMutated + ) + }) { + let other_arg_has_short = self.args.args().any(|x| x.short == Some('V')); + let version = self + .args + .args_mut() + .find(|x| x.id == Id::version_hash()) + .expect(INTERNAL_ERROR_MSG); + + if !(version.short.is_some() + || other_arg_has_short + || self.subcommands.iter().any(|sc| sc.short_flag == Some('V'))) + { + version.short = Some('V'); + } + } + + if !self.is_set(AppSettings::DisableHelpSubcommand) + && self.has_subcommands() + && !self.subcommands.iter().any(|s| s.id == Id::help_hash()) + { + debug!("Command::_check_help_and_version: Building help subcommand"); + let mut help_subcmd = App::new("help") + .about("Print this message or the help of the given subcommand(s)") + .arg( + Arg::new("subcommand") + .index(1) + .takes_value(true) + .multiple_occurrences(true) + .value_name("SUBCOMMAND") + .help("The subcommand whose help message to display"), + ); + self._propagate_subcommand(&mut help_subcmd); + + // The parser acts like this is set, so let's set it so we don't falsely + // advertise it to the user + help_subcmd.version = None; + help_subcmd.long_version = None; + help_subcmd = help_subcmd + .setting(AppSettings::DisableHelpFlag) + .unset_global_setting(AppSettings::PropagateVersion); + + self.subcommands.push(help_subcmd); + } + } + + pub(crate) fn _derive_display_order(&mut self) { + debug!("Command::_derive_display_order:{}", self.name); + + if self.settings.is_set(AppSettings::DeriveDisplayOrder) { + for a in self + .args + .args_mut() + .filter(|a| !a.is_positional()) + .filter(|a| a.provider != ArgProvider::Generated) + { + a.disp_ord.make_explicit(); + } + for (i, sc) in &mut self.subcommands.iter_mut().enumerate() { + sc.disp_ord.get_or_insert(i); + } + } + for sc in &mut self.subcommands { + sc._derive_display_order(); + } + } + + pub(crate) fn _render_version(&self, use_long: bool) -> String { + debug!("Command::_render_version"); + + let ver = if use_long { + self.long_version.or(self.version).unwrap_or("") + } else { + self.version.or(self.long_version).unwrap_or("") + }; + if let Some(bn) = self.bin_name.as_ref() { + if bn.contains(' ') { + // In case we're dealing with subcommands i.e. git mv is translated to git-mv + format!("{} {}\n", bn.replace(' ', "-"), ver) + } else { + format!("{} {}\n", &self.name[..], ver) + } + } else { + format!("{} {}\n", &self.name[..], ver) + } + } + + pub(crate) fn format_group(&self, g: &Id) -> String { + let g_string = self + .unroll_args_in_group(g) + .iter() + .filter_map(|x| self.find(x)) + .map(|x| { + if x.is_positional() { + // Print val_name for positional arguments. e.g. + x.name_no_brackets().to_string() + } else { + // Print usage string for flags arguments, e.g. <--help> + x.to_string() + } + }) + .collect::>() + .join("|"); + format!("<{}>", &*g_string) + } +} + +/// A workaround: +/// +pub(crate) trait Captures<'a> {} +impl<'a, T> Captures<'a> for T {} + +// Internal Query Methods +impl<'help> App<'help> { + /// Iterate through the *flags* & *options* arguments. + pub(crate) fn get_non_positionals(&self) -> impl Iterator> { + self.get_arguments().filter(|a| !a.is_positional()) + } + + /// Iterate through the *positionals* that don't have custom heading. + pub(crate) fn get_positionals_with_no_heading(&self) -> impl Iterator> { + self.get_positionals() + .filter(|a| a.get_help_heading().is_none()) + } + + /// Iterate through the *flags* & *options* that don't have custom heading. + pub(crate) fn get_non_positionals_with_no_heading(&self) -> impl Iterator> { + self.get_non_positionals() + .filter(|a| a.get_help_heading().is_none()) + } + + pub(crate) fn find(&self, arg_id: &Id) -> Option<&Arg<'help>> { + self.args.args().find(|a| a.id == *arg_id) + } + + #[inline] + pub(crate) fn contains_short(&self, s: char) -> bool { + assert!( + self.is_set(AppSettings::Built), + "If App::_build hasn't been called, manually search through Arg shorts" + ); + + self.args.contains(s) + } + + #[inline] + pub(crate) fn set(&mut self, s: AppSettings) { + self.settings.set(s) + } + + #[inline] + pub(crate) fn has_args(&self) -> bool { + !self.args.is_empty() + } + + pub(crate) fn has_positionals(&self) -> bool { + self.args.keys().any(|x| x.is_position()) + } + + pub(crate) fn has_visible_subcommands(&self) -> bool { + self.subcommands + .iter() + .any(|sc| sc.name != "help" && !sc.is_set(AppSettings::Hidden)) + } + + /// Check if this subcommand can be referred to as `name`. In other words, + /// check if `name` is the name of this subcommand or is one of its aliases. + #[inline] + pub(crate) fn aliases_to(&self, name: &T) -> bool + where + T: PartialEq + ?Sized, + { + *name == *self.get_name() || self.get_all_aliases().any(|alias| *name == *alias) + } + + /// Check if this subcommand can be referred to as `name`. In other words, + /// check if `name` is the name of this short flag subcommand or is one of its short flag aliases. + #[inline] + pub(crate) fn short_flag_aliases_to(&self, flag: char) -> bool { + Some(flag) == self.short_flag + || self.get_all_short_flag_aliases().any(|alias| flag == alias) + } + + /// Check if this subcommand can be referred to as `name`. In other words, + /// check if `name` is the name of this long flag subcommand or is one of its long flag aliases. + #[inline] + pub(crate) fn long_flag_aliases_to(&self, flag: &T) -> bool + where + T: PartialEq + ?Sized, + { + match self.long_flag { + Some(long_flag) => { + flag == long_flag || self.get_all_long_flag_aliases().any(|alias| flag == alias) + } + None => self.get_all_long_flag_aliases().any(|alias| flag == alias), + } + } + + #[cfg(debug_assertions)] + pub(crate) fn id_exists(&self, id: &Id) -> bool { + self.args.args().any(|x| x.id == *id) || self.groups.iter().any(|x| x.id == *id) + } + + /// Iterate through the groups this arg is member of. + pub(crate) fn groups_for_arg<'a>(&'a self, arg: &Id) -> impl Iterator + 'a { + debug!("Command::groups_for_arg: id={:?}", arg); + let arg = arg.clone(); + self.groups + .iter() + .filter(move |grp| grp.args.iter().any(|a| a == &arg)) + .map(|grp| grp.id.clone()) + } + + pub(crate) fn find_group(&self, group_id: &Id) -> Option<&ArgGroup<'help>> { + self.groups.iter().find(|g| g.id == *group_id) + } + + /// Iterate through all the names of all subcommands (not recursively), including aliases. + /// Used for suggestions. + pub(crate) fn all_subcommand_names(&self) -> impl Iterator + Captures<'help> { + self.get_subcommands().flat_map(|sc| { + let name = sc.get_name(); + let aliases = sc.get_all_aliases(); + std::iter::once(name).chain(aliases) + }) + } + + pub(crate) fn required_graph(&self) -> ChildGraph { + let mut reqs = ChildGraph::with_capacity(5); + for a in self.args.args().filter(|a| a.is_required_set()) { + reqs.insert(a.id.clone()); + } + for group in &self.groups { + if group.required { + let idx = reqs.insert(group.id.clone()); + for a in &group.requires { + reqs.insert_child(idx, a.clone()); + } + } + } + + reqs + } + + pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec { + debug!("Command::unroll_args_in_group: group={:?}", group); + let mut g_vec = vec![group]; + let mut args = vec![]; + + while let Some(g) = g_vec.pop() { + for n in self + .groups + .iter() + .find(|grp| grp.id == *g) + .expect(INTERNAL_ERROR_MSG) + .args + .iter() + { + debug!("Command::unroll_args_in_group:iter: entity={:?}", n); + if !args.contains(n) { + if self.find(n).is_some() { + debug!("Command::unroll_args_in_group:iter: this is an arg"); + args.push(n.clone()) + } else { + debug!("Command::unroll_args_in_group:iter: this is a group"); + g_vec.push(n); + } + } + } + } + + args + } + + pub(crate) fn unroll_arg_requires(&self, func: F, arg: &Id) -> Vec + where + F: Fn(&(ArgPredicate<'_>, Id)) -> Option, + { + let mut processed = vec![]; + let mut r_vec = vec![arg]; + let mut args = vec![]; + + while let Some(a) = r_vec.pop() { + if processed.contains(&a) { + continue; + } + + processed.push(a); + + if let Some(arg) = self.find(a) { + for r in arg.requires.iter().filter_map(&func) { + if let Some(req) = self.find(&r) { + if !req.requires.is_empty() { + r_vec.push(&req.id) + } + } + args.push(r); + } + } + } + + args + } + + /// Find a flag subcommand name by short flag or an alias + pub(crate) fn find_short_subcmd(&self, c: char) -> Option<&str> { + self.get_subcommands() + .find(|sc| sc.short_flag_aliases_to(c)) + .map(|sc| sc.get_name()) + } + + /// Find a flag subcommand name by long flag or an alias + pub(crate) fn find_long_subcmd(&self, long: &str) -> Option<&str> { + self.get_subcommands() + .find(|sc| sc.long_flag_aliases_to(long)) + .map(|sc| sc.get_name()) + } + + pub(crate) fn get_display_order(&self) -> usize { + self.disp_ord.unwrap_or(999) + } + + pub(crate) fn write_help_err( + &self, + mut use_long: bool, + stream: Stream, + ) -> ClapResult { + debug!( + "Parser::write_help_err: use_long={:?}, stream={:?}", + use_long && self.use_long_help(), + stream + ); + + use_long = use_long && self.use_long_help(); + let usage = Usage::new(self); + + let mut c = Colorizer::new(stream, self.color_help()); + Help::new(HelpWriter::Buffer(&mut c), self, &usage, use_long).write_help()?; + Ok(c) + } + + pub(crate) fn use_long_help(&self) -> bool { + debug!("Command::use_long_help"); + // In this case, both must be checked. This allows the retention of + // original formatting, but also ensures that the actual -h or --help + // specified by the user is sent through. If hide_short_help is not included, + // then items specified with hidden_short_help will also be hidden. + let should_long = |v: &Arg| { + v.long_help.is_some() + || v.is_hide_long_help_set() + || v.is_hide_short_help_set() + || cfg!(feature = "unstable-v4") + && v.get_possible_values2() + .iter() + .any(PossibleValue::should_show_help) + }; + + // Subcommands aren't checked because we prefer short help for them, deferring to + // `cmd subcmd --help` for more. + self.get_long_about().is_some() + || self.get_before_long_help().is_some() + || self.get_after_long_help().is_some() + || self.get_arguments().any(should_long) + } + + // Should we color the help? + pub(crate) fn color_help(&self) -> ColorChoice { + #[cfg(feature = "color")] + if self.is_disable_colored_help_set() { + return ColorChoice::Never; + } + + self.get_color() + } +} + +impl<'help> Default for App<'help> { + fn default() -> Self { + Self { + id: Default::default(), + name: Default::default(), + long_flag: Default::default(), + short_flag: Default::default(), + display_name: Default::default(), + bin_name: Default::default(), + author: Default::default(), + version: Default::default(), + long_version: Default::default(), + about: Default::default(), + long_about: Default::default(), + before_help: Default::default(), + before_long_help: Default::default(), + after_help: Default::default(), + after_long_help: Default::default(), + aliases: Default::default(), + short_flag_aliases: Default::default(), + long_flag_aliases: Default::default(), + usage_str: Default::default(), + usage_name: Default::default(), + help_str: Default::default(), + disp_ord: Default::default(), + term_w: Default::default(), + max_w: Default::default(), + template: Default::default(), + settings: Default::default(), + g_settings: Default::default(), + args: Default::default(), + subcommands: Default::default(), + replacers: Default::default(), + groups: Default::default(), + current_help_heading: Default::default(), + current_disp_ord: Some(0), + subcommand_value_name: Default::default(), + subcommand_heading: Default::default(), + } + } +} + +impl<'help> Index<&'_ Id> for App<'help> { + type Output = Arg<'help>; + + fn index(&self, key: &Id) -> &Self::Output { + self.find(key).expect(INTERNAL_ERROR_MSG) + } +} + +impl fmt::Display for App<'_> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name) + } +} + +fn two_elements_of(mut iter: I) -> Option<(T, T)> +where + I: Iterator, +{ + let first = iter.next(); + let second = iter.next(); + + match (first, second) { + (Some(first), Some(second)) => Some((first, second)), + _ => None, + } +} + +#[test] +fn check_auto_traits() { + static_assertions::assert_impl_all!(Command: Send, Sync, Unpin); +} diff --git a/vendor/clap-3.2.20/src/builder/debug_asserts.rs b/vendor/clap-3.2.20/src/builder/debug_asserts.rs new file mode 100644 index 000000000..864b8b479 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/debug_asserts.rs @@ -0,0 +1,851 @@ +use std::cmp::Ordering; + +use clap_lex::RawOsStr; + +use crate::builder::arg::ArgProvider; +use crate::mkeymap::KeyType; +use crate::ArgAction; +use crate::{Arg, Command, ValueHint}; + +pub(crate) fn assert_app(cmd: &Command) { + debug!("Command::_debug_asserts"); + + let mut short_flags = vec![]; + let mut long_flags = vec![]; + + // Invalid version flag settings + if cmd.get_version().is_none() && cmd.get_long_version().is_none() { + // PropagateVersion is meaningless if there is no version + assert!( + !cmd.is_propagate_version_set(), + "Command {}: No version information via Command::version or Command::long_version to propagate", + cmd.get_name(), + ); + + // Used `Command::mut_arg("version", ..) but did not provide any version information to display + let version_needed = cmd + .get_arguments() + .filter(|x| { + let action_set = matches!(x.get_action(), ArgAction::Version); + #[cfg(not(feature = "unstable-v4"))] + let provider_set = matches!(x.provider, ArgProvider::GeneratedMutated); + #[cfg(feature = "unstable-v4")] + let provider_set = matches!( + x.provider, + ArgProvider::User | ArgProvider::GeneratedMutated + ); + action_set && provider_set + }) + .map(|x| x.get_id()) + .collect::>(); + + assert_eq!(version_needed, Vec::<&str>::new(), "Command {}: `ArgAction::Version` used without providing Command::version or Command::long_version" + ,cmd.get_name() + ); + } + + for sc in cmd.get_subcommands() { + if let Some(s) = sc.get_short_flag().as_ref() { + short_flags.push(Flag::Command(format!("-{}", s), sc.get_name())); + } + + for short_alias in sc.get_all_short_flag_aliases() { + short_flags.push(Flag::Command(format!("-{}", short_alias), sc.get_name())); + } + + if let Some(l) = sc.get_long_flag().as_ref() { + #[cfg(feature = "unstable-v4")] + { + assert!(!l.starts_with('-'), "Command {}: long_flag {:?} must not start with a `-`, that will be handled by the parser", sc.get_name(), l); + } + long_flags.push(Flag::Command(format!("--{}", l), sc.get_name())); + } + + for long_alias in sc.get_all_long_flag_aliases() { + long_flags.push(Flag::Command(format!("--{}", long_alias), sc.get_name())); + } + } + + for arg in cmd.get_arguments() { + assert_arg(arg); + + assert!( + !cmd.is_multicall_set(), + "Command {}: Arguments like {} cannot be set on a multicall command", + cmd.get_name(), + arg.name + ); + + if let Some(s) = arg.short.as_ref() { + short_flags.push(Flag::Arg(format!("-{}", s), &*arg.name)); + } + + for (short_alias, _) in &arg.short_aliases { + short_flags.push(Flag::Arg(format!("-{}", short_alias), arg.name)); + } + + if let Some(l) = arg.long.as_ref() { + #[cfg(feature = "unstable-v4")] + { + assert!(!l.starts_with('-'), "Argument {}: long {:?} must not start with a `-`, that will be handled by the parser", arg.name, l); + } + long_flags.push(Flag::Arg(format!("--{}", l), &*arg.name)); + } + + for (long_alias, _) in &arg.aliases { + long_flags.push(Flag::Arg(format!("--{}", long_alias), arg.name)); + } + + // Name conflicts + assert!( + cmd.two_args_of(|x| x.id == arg.id).is_none(), + "Command {}: Argument names must be unique, but '{}' is in use by more than one argument or group", + cmd.get_name(), + arg.name, + ); + + // Long conflicts + if let Some(l) = arg.long { + if let Some((first, second)) = cmd.two_args_of(|x| x.long == Some(l)) { + panic!( + "Command {}: Long option names must be unique for each argument, \ + but '--{}' is in use by both '{}' and '{}'", + cmd.get_name(), + l, + first.name, + second.name + ) + } + } + + // Short conflicts + if let Some(s) = arg.short { + if let Some((first, second)) = cmd.two_args_of(|x| x.short == Some(s)) { + panic!( + "Command {}: Short option names must be unique for each argument, \ + but '-{}' is in use by both '{}' and '{}'", + cmd.get_name(), + s, + first.name, + second.name + ) + } + } + + // Index conflicts + if let Some(idx) = arg.index { + if let Some((first, second)) = + cmd.two_args_of(|x| x.is_positional() && x.index == Some(idx)) + { + panic!( + "Command {}: Argument '{}' has the same index as '{}' \ + and they are both positional arguments\n\n\t \ + Use Arg::multiple_values(true) to allow one \ + positional argument to take multiple values", + cmd.get_name(), + first.name, + second.name + ) + } + } + + // requires, r_if, r_unless + for req in &arg.requires { + assert!( + cmd.id_exists(&req.1), + "Command {}: Argument or group '{:?}' specified in 'requires*' for '{}' does not exist", + cmd.get_name(), + req.1, + arg.name, + ); + } + + for req in &arg.r_ifs { + #[cfg(feature = "unstable-v4")] + { + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_if_eq*`", + arg.name + ); + } + assert!( + cmd.id_exists(&req.0), + "Command {}: Argument or group '{:?}' specified in 'required_if_eq*' for '{}' does not exist", + cmd.get_name(), + req.0, + arg.name + ); + } + + for req in &arg.r_ifs_all { + #[cfg(feature = "unstable-v4")] + { + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_if_eq_all`", + arg.name + ); + } + assert!( + cmd.id_exists(&req.0), + "Command {}: Argument or group '{:?}' specified in 'required_if_eq_all' for '{}' does not exist", + cmd.get_name(), + req.0, + arg.name + ); + } + + for req in &arg.r_unless { + #[cfg(feature = "unstable-v4")] + { + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_unless*`", + arg.name + ); + } + assert!( + cmd.id_exists(req), + "Command {}: Argument or group '{:?}' specified in 'required_unless*' for '{}' does not exist", + cmd.get_name(), + req, + arg.name, + ); + } + + for req in &arg.r_unless_all { + #[cfg(feature = "unstable-v4")] + { + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_unless*`", + arg.name + ); + } + assert!( + cmd.id_exists(req), + "Command {}: Argument or group '{:?}' specified in 'required_unless*' for '{}' does not exist", + cmd.get_name(), + req, + arg.name, + ); + } + + // blacklist + for req in &arg.blacklist { + assert!( + cmd.id_exists(req), + "Command {}: Argument or group '{:?}' specified in 'conflicts_with*' for '{}' does not exist", + cmd.get_name(), + req, + arg.name, + ); + } + + if arg.is_last_set() { + assert!( + arg.long.is_none(), + "Command {}: Flags or Options cannot have last(true) set. '{}' has both a long and last(true) set.", + cmd.get_name(), + arg.name + ); + assert!( + arg.short.is_none(), + "Command {}: Flags or Options cannot have last(true) set. '{}' has both a short and last(true) set.", + cmd.get_name(), + arg.name + ); + } + + assert!( + !(arg.is_required_set() && arg.is_global_set()), + "Command {}: Global arguments cannot be required.\n\n\t'{}' is marked as both global and required", + cmd.get_name(), + arg.name + ); + + // validators + assert!( + arg.validator.is_none() || arg.validator_os.is_none(), + "Command {}: Argument '{}' has both `validator` and `validator_os` set which is not allowed", + cmd.get_name(), + arg.name + ); + + if arg.get_value_hint() == ValueHint::CommandWithArguments { + assert!( + arg.is_positional(), + "Command {}: Argument '{}' has hint CommandWithArguments and must be positional.", + cmd.get_name(), + arg.name + ); + + assert!( + cmd.is_trailing_var_arg_set(), + "Command {}: Positional argument '{}' has hint CommandWithArguments, so Command must have TrailingVarArg set.", + cmd.get_name(), + arg.name + ); + } + } + + for group in cmd.get_groups() { + // Name conflicts + assert!( + cmd.get_groups().filter(|x| x.id == group.id).count() < 2, + "Command {}: Argument group name must be unique\n\n\t'{}' is already in use", + cmd.get_name(), + group.name, + ); + + // Groups should not have naming conflicts with Args + assert!( + !cmd.get_arguments().any(|x| x.id == group.id), + "Command {}: Argument group name '{}' must not conflict with argument name", + cmd.get_name(), + group.name, + ); + + for arg in &group.args { + // Args listed inside groups should exist + assert!( + cmd.get_arguments().any(|x| x.id == *arg), + "Command {}: Argument group '{}' contains non-existent argument '{:?}'", + cmd.get_name(), + group.name, + arg + ); + } + } + + // Conflicts between flags and subcommands + + long_flags.sort_unstable(); + short_flags.sort_unstable(); + + detect_duplicate_flags(&long_flags, "long"); + detect_duplicate_flags(&short_flags, "short"); + + _verify_positionals(cmd); + + if let Some(help_template) = cmd.get_help_template() { + assert!( + !help_template.contains("{flags}"), + "Command {}: {}", + cmd.get_name(), + "`{flags}` template variable was removed in clap3, they are now included in `{options}`", + ); + assert!( + !help_template.contains("{unified}"), + "Command {}: {}", + cmd.get_name(), + "`{unified}` template variable was removed in clap3, use `{options}` instead" + ); + } + + cmd._panic_on_missing_help(cmd.is_help_expected_set()); + assert_app_flags(cmd); +} + +#[derive(Eq)] +enum Flag<'a> { + Command(String, &'a str), + Arg(String, &'a str), +} + +impl PartialEq for Flag<'_> { + fn eq(&self, other: &Flag) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +impl PartialOrd for Flag<'_> { + fn partial_cmp(&self, other: &Flag) -> Option { + use Flag::*; + + match (self, other) { + (Command(s1, _), Command(s2, _)) + | (Arg(s1, _), Arg(s2, _)) + | (Command(s1, _), Arg(s2, _)) + | (Arg(s1, _), Command(s2, _)) => { + if s1 == s2 { + Some(Ordering::Equal) + } else { + s1.partial_cmp(s2) + } + } + } + } +} + +impl Ord for Flag<'_> { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() + } +} + +fn detect_duplicate_flags(flags: &[Flag], short_or_long: &str) { + use Flag::*; + + for (one, two) in find_duplicates(flags) { + match (one, two) { + (Command(flag, one), Command(_, another)) if one != another => panic!( + "the '{}' {} flag is specified for both '{}' and '{}' subcommands", + flag, short_or_long, one, another + ), + + (Arg(flag, one), Arg(_, another)) if one != another => panic!( + "{} option names must be unique, but '{}' is in use by both '{}' and '{}'", + short_or_long, flag, one, another + ), + + (Arg(flag, arg), Command(_, sub)) | (Command(flag, sub), Arg(_, arg)) => panic!( + "the '{}' {} flag for the '{}' argument conflicts with the short flag \ + for '{}' subcommand", + flag, short_or_long, arg, sub + ), + + _ => {} + } + } +} + +/// Find duplicates in a sorted array. +/// +/// The algorithm is simple: the array is sorted, duplicates +/// must be placed next to each other, we can check only adjacent elements. +fn find_duplicates(slice: &[T]) -> impl Iterator { + slice.windows(2).filter_map(|w| { + if w[0] == w[1] { + Some((&w[0], &w[1])) + } else { + None + } + }) +} + +fn assert_app_flags(cmd: &Command) { + macro_rules! checker { + ($a:ident requires $($b:ident)|+) => { + if cmd.$a() { + let mut s = String::new(); + + $( + if !cmd.$b() { + s.push_str(&format!(" AppSettings::{} is required when AppSettings::{} is set.\n", std::stringify!($b), std::stringify!($a))); + } + )+ + + if !s.is_empty() { + panic!("{}", s) + } + } + }; + ($a:ident conflicts $($b:ident)|+) => { + if cmd.$a() { + let mut s = String::new(); + + $( + if cmd.$b() { + s.push_str(&format!(" AppSettings::{} conflicts with AppSettings::{}.\n", std::stringify!($b), std::stringify!($a))); + } + )+ + + if !s.is_empty() { + panic!("{}\n{}", cmd.get_name(), s) + } + } + }; + } + + checker!(is_allow_invalid_utf8_for_external_subcommands_set requires is_allow_external_subcommands_set); + checker!(is_multicall_set conflicts is_no_binary_name_set); +} + +#[cfg(debug_assertions)] +fn _verify_positionals(cmd: &Command) -> bool { + debug!("Command::_verify_positionals"); + // Because you must wait until all arguments have been supplied, this is the first chance + // to make assertions on positional argument indexes + // + // First we verify that the index highest supplied index, is equal to the number of + // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3 + // but no 2) + + let highest_idx = cmd + .get_keymap() + .keys() + .filter_map(|x| { + if let KeyType::Position(n) = x { + Some(*n) + } else { + None + } + }) + .max() + .unwrap_or(0); + + let num_p = cmd.get_keymap().keys().filter(|x| x.is_position()).count(); + + assert!( + highest_idx == num_p, + "Found positional argument whose index is {} but there \ + are only {} positional arguments defined", + highest_idx, + num_p + ); + + // Next we verify that only the highest index has takes multiple arguments (if any) + let only_highest = |a: &Arg| a.is_multiple() && (a.index.unwrap_or(0) != highest_idx); + if cmd.get_positionals().any(only_highest) { + // First we make sure if there is a positional that allows multiple values + // the one before it (second to last) has one of these: + // * a value terminator + // * ArgSettings::Last + // * The last arg is Required + + // We can't pass the closure (it.next()) to the macro directly because each call to + // find() (iterator, not macro) gets called repeatedly. + let last = &cmd.get_keymap()[&KeyType::Position(highest_idx)]; + let second_to_last = &cmd.get_keymap()[&KeyType::Position(highest_idx - 1)]; + + // Either the final positional is required + // Or the second to last has a terminator or .last(true) set + let ok = last.is_required_set() + || (second_to_last.terminator.is_some() || second_to_last.is_last_set()) + || last.is_last_set(); + assert!( + ok, + "When using a positional argument with .multiple_values(true) that is *not the \ + last* positional argument, the last positional argument (i.e. the one \ + with the highest index) *must* have .required(true) or .last(true) set." + ); + + // We make sure if the second to last is Multiple the last is ArgSettings::Last + let ok = second_to_last.is_multiple() || last.is_last_set(); + assert!( + ok, + "Only the last positional argument, or second to last positional \ + argument may be set to .multiple_values(true)" + ); + + // Next we check how many have both Multiple and not a specific number of values set + let count = cmd + .get_positionals() + .filter(|p| { + #[allow(deprecated)] + { + p.is_multiple_occurrences_set() + || (p.is_multiple_values_set() && p.num_vals.is_none()) + } + }) + .count(); + let ok = count <= 1 + || (last.is_last_set() + && last.is_multiple() + && second_to_last.is_multiple() + && count == 2); + assert!( + ok, + "Only one positional argument with .multiple_values(true) set is allowed per \ + command, unless the second one also has .last(true) set" + ); + } + + let mut found = false; + + if cmd.is_allow_missing_positional_set() { + // Check that if a required positional argument is found, all positions with a lower + // index are also required. + let mut foundx2 = false; + + for p in cmd.get_positionals() { + if foundx2 && !p.is_required_set() { + assert!( + p.is_required_set(), + "Found non-required positional argument with a lower \ + index than a required positional argument by two or more: {:?} \ + index {:?}", + p.name, + p.index + ); + } else if p.is_required_set() && !p.is_last_set() { + // Args that .last(true) don't count since they can be required and have + // positionals with a lower index that aren't required + // Imagine: prog [opt1] -- + // Both of these are valid invocations: + // $ prog r1 -- r2 + // $ prog r1 o1 -- r2 + if found { + foundx2 = true; + continue; + } + found = true; + continue; + } else { + found = false; + } + } + } else { + // Check that if a required positional argument is found, all positions with a lower + // index are also required + for p in (1..=num_p).rev().filter_map(|n| cmd.get_keymap().get(&n)) { + if found { + assert!( + p.is_required_set(), + "Found non-required positional argument with a lower \ + index than a required positional argument: {:?} index {:?}", + p.name, + p.index + ); + } else if p.is_required_set() && !p.is_last_set() { + // Args that .last(true) don't count since they can be required and have + // positionals with a lower index that aren't required + // Imagine: prog [opt1] -- + // Both of these are valid invocations: + // $ prog r1 -- r2 + // $ prog r1 o1 -- r2 + found = true; + continue; + } + } + } + assert!( + cmd.get_positionals().filter(|p| p.is_last_set()).count() < 2, + "Only one positional argument may have last(true) set. Found two." + ); + if cmd + .get_positionals() + .any(|p| p.is_last_set() && p.is_required_set()) + && cmd.has_subcommands() + && !cmd.is_subcommand_negates_reqs_set() + { + panic!( + "Having a required positional argument with .last(true) set *and* child \ + subcommands without setting SubcommandsNegateReqs isn't compatible." + ); + } + + true +} + +fn assert_arg(arg: &Arg) { + debug!("Arg::_debug_asserts:{}", arg.name); + + // Self conflict + // TODO: this check should be recursive + assert!( + !arg.blacklist.iter().any(|x| *x == arg.id), + "Argument '{}' cannot conflict with itself", + arg.name, + ); + + assert_eq!( + arg.get_action().takes_values(), + arg.is_takes_value_set(), + "Argument `{}`'s selected action {:?} contradicts `takes_value`", + arg.name, + arg.get_action() + ); + if let Some(action_type_id) = arg.get_action().value_type_id() { + assert_eq!( + action_type_id, + arg.get_value_parser().type_id(), + "Argument `{}`'s selected action {:?} contradicts `value_parser` ({:?})", + arg.name, + arg.get_action(), + arg.get_value_parser() + ); + } + + if arg.get_value_hint() != ValueHint::Unknown { + assert!( + arg.is_takes_value_set(), + "Argument '{}' has value hint but takes no value", + arg.name + ); + + if arg.get_value_hint() == ValueHint::CommandWithArguments { + assert!( + arg.is_multiple_values_set(), + "Argument '{}' uses hint CommandWithArguments and must accept multiple values", + arg.name + ) + } + } + + if arg.index.is_some() { + assert!( + arg.is_positional(), + "Argument '{}' is a positional argument and can't have short or long name versions", + arg.name + ); + assert!( + arg.is_takes_value_set(), + "Argument '{}` is positional, it must take a value", + arg.name + ); + } + + #[cfg(feature = "unstable-v4")] + { + let num_vals = arg.get_num_vals().unwrap_or(usize::MAX); + let num_val_names = arg.get_value_names().unwrap_or(&[]).len(); + if num_vals < num_val_names { + panic!( + "Argument {}: Too many value names ({}) compared to number_of_values ({})", + arg.name, num_val_names, num_vals + ); + } + } + + assert_arg_flags(arg); + + assert_defaults(arg, "default_value", arg.default_vals.iter().copied()); + assert_defaults( + arg, + "default_missing_value", + arg.default_missing_vals.iter().copied(), + ); + assert_defaults( + arg, + "default_value_if", + arg.default_vals_ifs + .iter() + .filter_map(|(_, _, default)| *default), + ); +} + +fn assert_arg_flags(arg: &Arg) { + macro_rules! checker { + ($a:ident requires $($b:ident)|+) => { + if arg.$a() { + let mut s = String::new(); + + $( + if !arg.$b() { + s.push_str(&format!(" Arg::{} is required when Arg::{} is set.\n", std::stringify!($b), std::stringify!($a))); + } + )+ + + if !s.is_empty() { + panic!("Argument {:?}\n{}", arg.get_id(), s) + } + } + } + } + + checker!(is_require_value_delimiter_set requires is_takes_value_set); + checker!(is_require_value_delimiter_set requires is_use_value_delimiter_set); + checker!(is_hide_possible_values_set requires is_takes_value_set); + checker!(is_allow_hyphen_values_set requires is_takes_value_set); + checker!(is_require_equals_set requires is_takes_value_set); + checker!(is_last_set requires is_takes_value_set); + checker!(is_hide_default_value_set requires is_takes_value_set); + checker!(is_multiple_values_set requires is_takes_value_set); + checker!(is_ignore_case_set requires is_takes_value_set); + { + #![allow(deprecated)] + checker!(is_forbid_empty_values_set requires is_takes_value_set); + checker!(is_allow_invalid_utf8_set requires is_takes_value_set); + } +} + +fn assert_defaults<'d>( + arg: &Arg, + field: &'static str, + defaults: impl IntoIterator, +) { + for default_os in defaults { + if let Some(default_s) = default_os.to_str() { + if !arg.possible_vals.is_empty() { + if let Some(delim) = arg.get_value_delimiter() { + for part in default_s.split(delim) { + assert!( + arg.possible_vals.iter().any(|possible_val| { + possible_val.matches(part, arg.is_ignore_case_set()) + }), + "Argument `{}`'s {}={} doesn't match possible values", + arg.name, + field, + part + ) + } + } else { + assert!( + arg.possible_vals.iter().any(|possible_val| { + possible_val.matches(default_s, arg.is_ignore_case_set()) + }), + "Argument `{}`'s {}={} doesn't match possible values", + arg.name, + field, + default_s + ); + } + } + + if let Some(validator) = arg.validator.as_ref() { + let mut validator = validator.lock().unwrap(); + if let Some(delim) = arg.get_value_delimiter() { + for part in default_s.split(delim) { + if let Err(err) = validator(part) { + panic!( + "Argument `{}`'s {}={} failed validation: {}", + arg.name, field, part, err + ); + } + } + } else if let Err(err) = validator(default_s) { + panic!( + "Argument `{}`'s {}={} failed validation: {}", + arg.name, field, default_s, err + ); + } + } + } + + if let Some(validator) = arg.validator_os.as_ref() { + let mut validator = validator.lock().unwrap(); + if let Some(delim) = arg.get_value_delimiter() { + let default_os = RawOsStr::new(default_os); + for part in default_os.split(delim) { + if let Err(err) = validator(&part.to_os_str()) { + panic!( + "Argument `{}`'s {}={:?} failed validation: {}", + arg.name, field, part, err + ); + } + } + } else if let Err(err) = validator(default_os) { + panic!( + "Argument `{}`'s {}={:?} failed validation: {}", + arg.name, field, default_os, err + ); + } + } + + let value_parser = arg.get_value_parser(); + let assert_cmd = Command::new("assert"); + if let Some(delim) = arg.get_value_delimiter() { + let default_os = RawOsStr::new(default_os); + for part in default_os.split(delim) { + if let Err(err) = value_parser.parse_ref(&assert_cmd, Some(arg), &part.to_os_str()) + { + panic!( + "Argument `{}`'s {}={:?} failed validation: {}", + arg.name, + field, + part.to_str_lossy(), + err + ); + } + } + } else if let Err(err) = value_parser.parse_ref(&assert_cmd, Some(arg), default_os) { + panic!( + "Argument `{}`'s {}={:?} failed validation: {}", + arg.name, field, default_os, err + ); + } + } +} diff --git a/vendor/clap-3.2.20/src/builder/macros.rs b/vendor/clap-3.2.20/src/builder/macros.rs new file mode 100644 index 000000000..5be4d205e --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/macros.rs @@ -0,0 +1,180 @@ +#[cfg(feature = "yaml")] +macro_rules! yaml_tuple2 { + ($a:ident, $v:ident, $c:ident) => {{ + if let Some(vec) = $v.as_vec() { + for ys in vec { + if let Some(tup) = ys.as_vec() { + debug_assert_eq!(2, tup.len()); + $a = $a.$c(yaml_str!(tup[0]), yaml_str!(tup[1])); + } else { + panic!("Failed to convert YAML value to vec"); + } + } + } else { + panic!("Failed to convert YAML value to vec"); + } + $a + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_tuple3 { + ($a:ident, $v:ident, $c:ident) => {{ + if let Some(vec) = $v.as_vec() { + for ys in vec { + if let Some(tup) = ys.as_vec() { + debug_assert_eq!(3, tup.len()); + $a = $a.$c( + yaml_str!(tup[0]), + yaml_opt_str!(tup[1]), + yaml_opt_str!(tup[2]), + ); + } else { + panic!("Failed to convert YAML value to vec"); + } + } + } else { + panic!("Failed to convert YAML value to vec"); + } + $a + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_vec_or_str { + ($a:ident, $v:ident, $c:ident) => {{ + let maybe_vec = $v.as_vec(); + if let Some(vec) = maybe_vec { + for ys in vec { + if let Some(s) = ys.as_str() { + $a = $a.$c(s); + } else { + panic!("Failed to convert YAML value {:?} to a string", ys); + } + } + } else { + if let Some(s) = $v.as_str() { + $a = $a.$c(s); + } else { + panic!( + "Failed to convert YAML value {:?} to either a vec or string", + $v + ); + } + } + $a + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_vec { + ($a:ident, $v:ident, $c:ident) => {{ + let maybe_vec = $v.as_vec(); + if let Some(vec) = maybe_vec { + let content = vec.into_iter().map(|ys| { + if let Some(s) = ys.as_str() { + s + } else { + panic!("Failed to convert YAML value {:?} to a string", ys); + } + }); + $a = $a.$c(content) + } else { + panic!("Failed to convert YAML value {:?} to a vec", $v); + } + $a + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_opt_str { + ($v:expr) => {{ + if !$v.is_null() { + Some( + $v.as_str() + .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)), + ) + } else { + None + } + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_char { + ($v:expr) => {{ + $v.as_str() + .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)) + .chars() + .next() + .unwrap_or_else(|| panic!("Expected char")) + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_str { + ($v:expr) => {{ + $v.as_str() + .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)) + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_to_char { + ($a:ident, $v:ident, $c:ident) => {{ + $a.$c(yaml_char!($v)) + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_to_str { + ($a:ident, $v:ident, $c:ident) => {{ + $a.$c(yaml_str!($v)) + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_to_bool { + ($a:ident, $v:ident, $c:ident) => {{ + $a.$c($v + .as_bool() + .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))) + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_to_usize { + ($a:ident, $v:ident, $c:ident) => {{ + $a.$c($v + .as_i64() + .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)) + as usize) + }}; +} + +#[cfg(feature = "yaml")] +macro_rules! yaml_to_setting { + ($a:ident, $v:ident, $c:ident, $s:ident, $t:literal, $n:expr) => {{ + if let Some(v) = $v.as_vec() { + for ys in v { + if let Some(s) = ys.as_str() { + $a = $a.$c(s.parse::<$s>().unwrap_or_else(|_| { + panic!("Unknown {} '{}' found in YAML file for {}", $t, s, $n) + })); + } else { + panic!( + "Failed to convert YAML {:?} value to an array of strings", + $v + ); + } + } + } else if let Some(v) = $v.as_str() { + $a = $a.$c(v + .parse::<$s>() + .unwrap_or_else(|_| panic!("Unknown {} '{}' found in YAML file for {}", $t, v, $n))) + } else { + panic!("Failed to convert YAML {:?} value to a string", $v); + } + $a + }}; +} diff --git a/vendor/clap-3.2.20/src/builder/mod.rs b/vendor/clap-3.2.20/src/builder/mod.rs new file mode 100644 index 000000000..4f24c74d3 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/mod.rs @@ -0,0 +1,61 @@ +//! Define [`Command`] line [arguments][`Arg`] + +#[macro_use] +mod macros; + +mod action; +mod app_settings; +mod arg; +mod arg_group; +mod arg_predicate; +mod arg_settings; +mod command; +mod possible_value; +mod usage_parser; +mod value_hint; +mod value_parser; + +#[cfg(feature = "regex")] +mod regex; + +#[cfg(debug_assertions)] +mod debug_asserts; + +#[cfg(test)] +mod tests; + +pub use action::ArgAction; +pub use app_settings::{AppFlags, AppSettings}; +pub use arg::Arg; +pub use arg_group::ArgGroup; +pub use arg_settings::{ArgFlags, ArgSettings}; +pub use command::Command; +pub use possible_value::PossibleValue; +pub use value_hint::ValueHint; +pub use value_parser::PossibleValuesParser; +pub use value_parser::RangedI64ValueParser; +pub use value_parser::RangedU64ValueParser; +pub use value_parser::StringValueParser; +pub use value_parser::TypedValueParser; +pub use value_parser::ValueParser; +pub use value_parser::ValueParserFactory; +pub use value_parser::_AnonymousValueParser; +pub use value_parser::_AutoValueParser; +pub use value_parser::via_prelude; +pub use value_parser::BoolValueParser; +pub use value_parser::BoolishValueParser; +pub use value_parser::EnumValueParser; +pub use value_parser::FalseyValueParser; +pub use value_parser::NonEmptyStringValueParser; +pub use value_parser::OsStringValueParser; +pub use value_parser::PathBufValueParser; + +#[allow(deprecated)] +pub use command::App; + +#[cfg(feature = "regex")] +pub use self::regex::RegexRef; + +pub(crate) use action::CountType; +pub(crate) use arg::display_arg_val; +pub(crate) use arg_predicate::ArgPredicate; diff --git a/vendor/clap-3.2.20/src/builder/possible_value.rs b/vendor/clap-3.2.20/src/builder/possible_value.rs new file mode 100644 index 000000000..1c14217a6 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/possible_value.rs @@ -0,0 +1,259 @@ +use std::{borrow::Cow, iter}; + +use crate::util::eq_ignore_case; + +/// A possible value of an argument. +/// +/// This is used for specifying [possible values] of [Args]. +/// +/// **NOTE:** This struct is likely not needed for most usecases as it is only required to +/// [hide] single values from help messages and shell completions or to attach [help] to possible values. +/// +/// # Examples +/// +/// ```rust +/// # use clap::{Arg, PossibleValue}; +/// let cfg = Arg::new("config") +/// .takes_value(true) +/// .value_name("FILE") +/// .value_parser([ +/// PossibleValue::new("fast"), +/// PossibleValue::new("slow").help("slower than fast"), +/// PossibleValue::new("secret speed").hide(true) +/// ]); +/// ``` +/// [Args]: crate::Arg +/// [possible values]: crate::builder::ValueParser::possible_values +/// [hide]: PossibleValue::hide() +/// [help]: PossibleValue::help() +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct PossibleValue<'help> { + name: &'help str, + help: Option<&'help str>, + aliases: Vec<&'help str>, // (name, visible) + hide: bool, +} + +impl<'help> PossibleValue<'help> { + /// Create a [`PossibleValue`] with its name. + /// + /// The name will be used to decide whether this value was provided by the user to an argument. + /// + /// **NOTE:** In case it is not [hidden] it will also be shown in help messages for arguments + /// that use it as a [possible value] and have not hidden them through [`Arg::hide_possible_values(true)`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::PossibleValue; + /// PossibleValue::new("fast") + /// # ; + /// ``` + /// [hidden]: PossibleValue::hide + /// [possible value]: crate::Arg::possible_values + /// [`Arg::hide_possible_values(true)`]: crate::Arg::hide_possible_values() + pub fn new(name: &'help str) -> Self { + PossibleValue { + name, + ..Default::default() + } + } + + /// Sets the help description of the value. + /// + /// This is typically displayed in completions (where supported) and should be a short, one-line + /// description. + /// + /// # Examples + /// + /// ```rust + /// # use clap::PossibleValue; + /// PossibleValue::new("slow") + /// .help("not fast") + /// # ; + /// ``` + #[inline] + #[must_use] + pub fn help(mut self, help: &'help str) -> Self { + self.help = Some(help); + self + } + + /// Hides this value from help and shell completions. + /// + /// This is an alternative to hiding through [`Arg::hide_possible_values(true)`], if you only + /// want to hide some values. + /// + /// # Examples + /// + /// ```rust + /// # use clap::PossibleValue; + /// PossibleValue::new("secret") + /// .hide(true) + /// # ; + /// ``` + /// [`Arg::hide_possible_values(true)`]: crate::Arg::hide_possible_values() + #[inline] + #[must_use] + pub fn hide(mut self, yes: bool) -> Self { + self.hide = yes; + self + } + + /// Sets a *hidden* alias for this argument value. + /// + /// # Examples + /// + /// ```rust + /// # use clap::PossibleValue; + /// PossibleValue::new("slow") + /// .alias("not-fast") + /// # ; + /// ``` + #[must_use] + pub fn alias(mut self, name: &'help str) -> Self { + self.aliases.push(name); + self + } + + /// Sets multiple *hidden* aliases for this argument value. + /// + /// # Examples + /// + /// ```rust + /// # use clap::PossibleValue; + /// PossibleValue::new("slow") + /// .aliases(["not-fast", "snake-like"]) + /// # ; + /// ``` + #[must_use] + pub fn aliases(mut self, names: I) -> Self + where + I: IntoIterator, + { + self.aliases.extend(names.into_iter()); + self + } +} + +/// Reflection +impl<'help> PossibleValue<'help> { + /// Get the name of the argument value + #[inline] + pub fn get_name(&self) -> &'help str { + self.name + } + + /// Get the help specified for this argument, if any + #[inline] + pub fn get_help(&self) -> Option<&'help str> { + self.help + } + + /// Get the help specified for this argument, if any and the argument + /// value is not hidden + #[inline] + #[cfg(feature = "unstable-v4")] + pub(crate) fn get_visible_help(&self) -> Option<&'help str> { + if !self.hide { + self.help + } else { + None + } + } + + /// Deprecated, replaced with [`PossibleValue::is_hide_set`] + #[inline] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `PossibleValue::is_hide_set`") + )] + pub fn is_hidden(&self) -> bool { + self.is_hide_set() + } + + /// Report if [`PossibleValue::hide`] is set + #[inline] + pub fn is_hide_set(&self) -> bool { + self.hide + } + + /// Report if PossibleValue is not hidden and has a help message + pub(crate) fn should_show_help(&self) -> bool { + !self.hide && self.help.is_some() + } + + /// Get the name if argument value is not hidden, `None` otherwise + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.4", + note = "Use `PossibleValue::is_hide_set` and `PossibleValue::get_name`" + ) + )] + pub fn get_visible_name(&self) -> Option<&'help str> { + if self.hide { + None + } else { + Some(self.name) + } + } + + /// Get the name if argument value is not hidden, `None` otherwise, + /// but wrapped in quotes if it contains whitespace + pub(crate) fn get_visible_quoted_name(&self) -> Option> { + if !self.hide { + Some(if self.name.contains(char::is_whitespace) { + format!("{:?}", self.name).into() + } else { + self.name.into() + }) + } else { + None + } + } + + /// Returns all valid values of the argument value. + /// + /// Namely the name and all aliases. + pub fn get_name_and_aliases(&self) -> impl Iterator + '_ { + iter::once(&self.name).chain(&self.aliases).copied() + } + + /// Tests if the value is valid for this argument value + /// + /// The value is valid if it is either the name or one of the aliases. + /// + /// # Examples + /// + /// ```rust + /// # use clap::PossibleValue; + /// let arg_value = PossibleValue::new("fast").alias("not-slow"); + /// + /// assert!(arg_value.matches("fast", false)); + /// assert!(arg_value.matches("not-slow", false)); + /// + /// assert!(arg_value.matches("FAST", true)); + /// assert!(!arg_value.matches("FAST", false)); + /// ``` + pub fn matches(&self, value: &str, ignore_case: bool) -> bool { + if ignore_case { + self.get_name_and_aliases() + .any(|name| eq_ignore_case(name, value)) + } else { + self.get_name_and_aliases().any(|name| name == value) + } + } +} + +impl<'help> From<&'help str> for PossibleValue<'help> { + fn from(s: &'help str) -> Self { + Self::new(s) + } +} + +impl<'help> From<&'help &'help str> for PossibleValue<'help> { + fn from(s: &'help &'help str) -> Self { + Self::new(s) + } +} diff --git a/vendor/clap-3.2.20/src/builder/regex.rs b/vendor/clap-3.2.20/src/builder/regex.rs new file mode 100644 index 000000000..bf3a78e0c --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/regex.rs @@ -0,0 +1,88 @@ +use ::regex::{Error, Regex, RegexSet}; + +use core::{convert::TryFrom, ops::Deref, str::FromStr}; +use std::borrow::Cow; + +/// Contains either a regular expression or a set of them or a reference to one. +/// +/// See [Arg::validator_regex(][crate::Arg::validator_regex] to set this on an argument. +#[derive(Debug, Clone)] +pub enum RegexRef<'a> { + /// Used if the underlying is a regex set + RegexSet(Cow<'a, RegexSet>), + /// Used if the underlying is a regex + Regex(Cow<'a, Regex>), +} + +impl<'a> RegexRef<'a> { + pub(crate) fn is_match(&self, text: &str) -> bool { + match self { + Self::Regex(r) => r.deref().is_match(text), + Self::RegexSet(r) => r.deref().is_match(text), + } + } +} + +impl<'a> From<&'a Regex> for RegexRef<'a> { + fn from(r: &'a Regex) -> Self { + Self::Regex(Cow::Borrowed(r)) + } +} + +impl<'a> From for RegexRef<'a> { + fn from(r: Regex) -> Self { + Self::Regex(Cow::Owned(r)) + } +} + +impl<'a> From<&'a RegexSet> for RegexRef<'a> { + fn from(r: &'a RegexSet) -> Self { + Self::RegexSet(Cow::Borrowed(r)) + } +} + +impl<'a> From for RegexRef<'a> { + fn from(r: RegexSet) -> Self { + Self::RegexSet(Cow::Owned(r)) + } +} + +impl<'a> TryFrom<&'a str> for RegexRef<'a> { + type Error = ::Err; + + fn try_from(r: &'a str) -> Result { + Self::from_str(r) + } +} + +impl<'a> FromStr for RegexRef<'a> { + type Err = Error; + + fn from_str(s: &str) -> Result { + Regex::from_str(s).map(|v| Self::Regex(Cow::Owned(v))) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use core::convert::TryInto; + + #[test] + fn test_try_from_with_valid_string() { + let t: Result = "^Hello, World$".try_into(); + assert!(t.is_ok()) + } + + #[test] + fn test_try_from_with_invalid_string() { + let t: Result = "^Hello, World)$".try_into(); + assert!(t.is_err()); + } + + #[test] + fn from_str() { + let t: Result = RegexRef::from_str("^Hello, World"); + assert!(t.is_ok()); + } +} diff --git a/vendor/clap-3.2.20/src/builder/tests.rs b/vendor/clap-3.2.20/src/builder/tests.rs new file mode 100644 index 000000000..76c8b8785 --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/tests.rs @@ -0,0 +1,56 @@ +use crate::Arg; +use crate::Command; + +#[test] +fn propagate_version() { + let mut cmd = Command::new("test") + .propagate_version(true) + .version("1.1") + .subcommand(Command::new("sub1")); + cmd._propagate(); + assert_eq!( + cmd.get_subcommands().next().unwrap().get_version(), + Some("1.1") + ); +} + +#[test] +fn global_setting() { + let mut cmd = Command::new("test") + .disable_version_flag(true) + .subcommand(Command::new("subcmd")); + cmd._propagate(); + assert!(cmd + .get_subcommands() + .find(|s| s.get_name() == "subcmd") + .unwrap() + .is_disable_version_flag_set()); +} + +// This test will *fail to compile* if Command is not Send + Sync +#[test] +fn app_send_sync() { + fn foo(_: T) {} + foo(Command::new("test")) +} + +#[test] +fn issue_2090() { + let mut cmd = Command::new("cmd") + .disable_version_flag(true) + .subcommand(Command::new("sub")); + cmd._build_self(); + + assert!(cmd + .get_subcommands() + .next() + .unwrap() + .is_disable_version_flag_set()); +} + +// This test will *fail to compile* if Arg is not Send + Sync +#[test] +fn arg_send_sync() { + fn foo(_: T) {} + foo(Arg::new("test")) +} diff --git a/vendor/clap-3.2.20/src/builder/usage_parser.rs b/vendor/clap-3.2.20/src/builder/usage_parser.rs new file mode 100644 index 000000000..85d0d304e --- /dev/null +++ b/vendor/clap-3.2.20/src/builder/usage_parser.rs @@ -0,0 +1,1277 @@ +#![allow(deprecated)] + +// Internal +use crate::builder::Arg; +use crate::builder::ArgSettings; +use crate::INTERNAL_ERROR_MSG; + +#[derive(PartialEq, Debug)] +enum UsageToken { + Name, + ValName, + Short, + Long, + Help, + Multiple, + Unknown, + Default, +} + +#[derive(Debug)] +pub(crate) struct UsageParser<'help> { + usage: &'help str, + pos: usize, + start: usize, + prev: UsageToken, + explicit_name_set: bool, +} + +impl<'help> UsageParser<'help> { + fn new(usage: &'help str) -> Self { + debug!("new: usage={:?}", usage); + UsageParser { + usage, + pos: 0, + start: 0, + prev: UsageToken::Unknown, + explicit_name_set: false, + } + } + + pub(crate) fn from_usage(usage: &'help str) -> Self { + debug!("UsageParser::from_usage"); + UsageParser::new(usage) + } + + pub(crate) fn parse(mut self) -> Arg<'help> { + debug!("UsageParser::parse"); + let mut arg = Arg::default(); + loop { + debug!("UsageParser::parse:iter: pos={}", self.pos); + self.stop_at(token); + if let Some(&c) = self.usage.as_bytes().get(self.pos) { + match c { + b'-' => self.short_or_long(&mut arg), + b'.' => self.multiple(&mut arg), + b'@' => self.default(&mut arg), + b'\'' => self.help(&mut arg), + _ => self.name(&mut arg), + } + } else { + break; + } + } + + debug!("UsageParser::parse: vals...{:?}", arg.val_names); + arg + } + + fn name(&mut self, arg: &mut Arg<'help>) { + debug!("UsageParser::name"); + if *self + .usage + .as_bytes() + .get(self.pos) + .expect(INTERNAL_ERROR_MSG) + == b'<' + && !self.explicit_name_set + { + arg.settings.set(ArgSettings::Required); + } + self.pos += 1; + self.stop_at(name_end); + let name = &self.usage[self.start..self.pos]; + if self.prev == UsageToken::Unknown { + debug!("UsageParser::name: setting name...{}", name); + arg.id = name.into(); + arg.name = name; + if arg.long.is_none() && arg.short.is_none() { + debug!("name: explicit name set..."); + self.explicit_name_set = true; + self.prev = UsageToken::Name; + } + } else { + debug!("UsageParser::name: setting val name...{}", name); + if arg.val_names.is_empty() { + arg.settings.set(ArgSettings::TakesValue); + } + let len = arg.val_names.len(); + arg.val_names.insert(len, name); + self.prev = UsageToken::ValName; + } + } + + fn stop_at(&mut self, f: F) + where + F: Fn(u8) -> bool, + { + debug!("UsageParser::stop_at"); + self.start = self.pos; + self.pos += self.usage[self.start..] + .bytes() + .take_while(|&b| f(b)) + .count(); + } + + fn short_or_long(&mut self, arg: &mut Arg<'help>) { + debug!("UsageParser::short_or_long"); + self.pos += 1; + if *self + .usage + .as_bytes() + .get(self.pos) + .expect(INTERNAL_ERROR_MSG) + == b'-' + { + self.pos += 1; + self.long(arg); + return; + } + self.short(arg) + } + + fn long(&mut self, arg: &mut Arg<'help>) { + debug!("UsageParser::long"); + self.stop_at(long_end); + let name = &self.usage[self.start..self.pos]; + if !self.explicit_name_set { + debug!("UsageParser::long: setting name...{}", name); + arg.id = name.into(); + arg.name = name; + } + debug!("UsageParser::long: setting long...{}", name); + arg.long = Some(name); + self.prev = UsageToken::Long; + } + + fn short(&mut self, arg: &mut Arg<'help>) { + debug!("UsageParser::short"); + let start = &self.usage[self.pos..]; + let short = start.chars().next().expect(INTERNAL_ERROR_MSG); + debug!("UsageParser::short: setting short...{}", short); + arg.short = Some(short); + if arg.name.is_empty() { + // --long takes precedence but doesn't set self.explicit_name_set + let name = &start[..short.len_utf8()]; + debug!("UsageParser::short: setting name...{}", name); + arg.id = name.into(); + arg.name = name; + } + self.prev = UsageToken::Short; + } + + // "something..." + fn multiple(&mut self, arg: &mut Arg) { + debug!("UsageParser::multiple"); + let mut dot_counter = 1; + let start = self.pos; + let mut bytes = self.usage[start..].bytes(); + while bytes.next() == Some(b'.') { + dot_counter += 1; + self.pos += 1; + if dot_counter == 3 { + debug!("UsageParser::multiple: setting multiple"); + arg.settings.set(ArgSettings::MultipleOccurrences); + if arg.is_takes_value_set() { + arg.settings.set(ArgSettings::MultipleValues); + arg.settings.set(ArgSettings::UseValueDelimiter); + arg.val_delim.get_or_insert(','); + } + self.prev = UsageToken::Multiple; + self.pos += 1; + break; + } + } + } + + fn help(&mut self, arg: &mut Arg<'help>) { + debug!("UsageParser::help"); + self.stop_at(help_start); + self.start = self.pos + 1; + self.pos = self.usage.len() - 1; + debug!( + "UsageParser::help: setting help...{}", + &self.usage[self.start..self.pos] + ); + arg.help = Some(&self.usage[self.start..self.pos]); + self.pos += 1; // Move to next byte to keep from thinking ending ' is a start + self.prev = UsageToken::Help; + } + + fn default(&mut self, arg: &mut Arg<'help>) { + debug!( + "UsageParser::default: from=\"{}\"", + &self.usage[self.pos..self.usage.len()] + ); + self.pos += 1; // Skip @ + self.stop_at(default_value_end); // Find first space after value + debug!( + "UsageParser::default: setting default...\"{}\"", + &self.usage[self.start..self.pos] + ); + arg.settings.set(ArgSettings::TakesValue); + arg.default_vals = vec![std::ffi::OsStr::new(&self.usage[self.start..self.pos])]; + self.prev = UsageToken::Default; + } +} + +#[inline] +fn name_end(b: u8) -> bool { + b != b']' && b != b'>' +} + +#[inline] +fn token(b: u8) -> bool { + b != b'\'' && b != b'.' && b != b'<' && b != b'[' && b != b'-' && b != b'@' +} + +#[inline] +fn long_end(b: u8) -> bool { + b != b'\'' && b != b'.' && b != b'<' && b != b'[' && b != b'=' && b != b' ' +} + +#[inline] +fn help_start(b: u8) -> bool { + b != b'\'' +} + +#[inline] +fn default_value_end(b: u8) -> bool { + b != b' ' +} + +#[cfg(test)] +mod test { + #![allow(deprecated)] + + use crate::builder::{Arg, ArgSettings}; + + #[allow(clippy::cognitive_complexity)] + #[test] + fn create_flag_usage() { + let a = Arg::from_usage("[flag] -f 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.long.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("[flag] --flag 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.long.unwrap(), "flag"); + assert!(a.short.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("--flag 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.long.unwrap(), "flag"); + assert!(a.short.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("[flag] -f --flag 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.short.unwrap(), 'f'); + assert_eq!(a.long.unwrap(), "flag"); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("[flag] -f... 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.long.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("[flag] -f --flag... 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.long.unwrap(), "flag"); + assert_eq!(a.short.unwrap(), 'f'); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("-f --flag... 'some help info'"); + assert_eq!(a.name, "flag"); + assert_eq!(a.long.unwrap(), "flag"); + assert_eq!(a.short.unwrap(), 'f'); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("--flags"); + assert_eq!(a.name, "flags"); + assert_eq!(a.long.unwrap(), "flags"); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("--flags..."); + assert_eq!(a.name, "flags"); + assert_eq!(a.long.unwrap(), "flags"); + assert!(a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("[flags] -f"); + assert_eq!(a.name, "flags"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("[flags] -f..."); + assert_eq!(a.name, "flags"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("-f 'some help info'"); + assert_eq!(a.name, "f"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.long.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("-f"); + assert_eq!(a.name, "f"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.val_names.is_empty()); + + let a = Arg::from_usage("-f..."); + assert_eq!(a.name, "f"); + assert_eq!(a.short.unwrap(), 'f'); + assert!(a.is_multiple_occurrences_set()); + assert!(a.val_names.is_empty()); + } + + #[test] + fn create_option_usage0() { + // Short only + let a = Arg::from_usage("[option] -o [opt] 'some help info'"); + assert_eq!(a.name, "option"); + assert_eq!(a.short.unwrap(), 'o'); + assert!(a.long.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(!a.is_multiple_values_set()); + assert!(a.is_takes_value_set()); + assert!(!a.is_required_set()); + assert_eq!(a.val_names.iter().collect::>(), [&"opt"]); + } + + #[test] + fn create_option_usage1() { + let a = Arg::from_usage("-o [opt] 'some help info'"); + assert_eq!(a.name, "o"); + assert_eq!(a.short.unwrap(), 'o'); + assert!(a.long.is_none()); + assert_eq!(a.help.unwrap(), "some help info"); + assert!(!a.is_multiple_occurrences_set()); + assert!(!a.is_multiple_values_set()); + assert!(a.is_takes_value_set()); + assert!(!a.is_required_set()); + assert_eq!(a.val_names.iter().collect::>(), [&"opt"]); + } + + #[test] + fn create_option_usage2() { + let a = Arg::from_usage(" Allow invalid UTF-8 paths - -O Implicitly using `std::str::FromStr` - --sleep Allow human-readable durations - -``` - -Optimization-level (number) -```console -$ typed-derive -O 1 -Args { optimization: Some(1), include: None, bind: None, sleep: None, defines: [] } - -$ typed-derive -O plaid -? failed -error: Invalid value "plaid" for '-O ': invalid digit found in string - -For more information try --help - -``` - -Include (path) -```console -$ typed-derive -I../hello -Args { optimization: None, include: Some("../hello"), bind: None, sleep: None, defines: [] } - -``` - -IP Address -```console -$ typed-derive --bind 192.0.0.1 -Args { optimization: None, include: None, bind: Some(192.0.0.1), sleep: None, defines: [] } - -$ typed-derive --bind localhost -? failed -error: Invalid value "localhost" for '--bind ': invalid IP address syntax - -For more information try --help - -``` - -Time -```console -$ typed-derive --sleep 10s -Args { optimization: None, include: None, bind: None, sleep: Some(Duration(10s)), defines: [] } - -$ typed-derive --sleep forever -? failed -error: Invalid value "forever" for '--sleep ': expected number at 0 - -For more information try --help - -``` - -Defines (key-value pairs) -```console -$ typed-derive -D Foo=10 -D Alice=30 -Args { optimization: None, include: None, bind: None, sleep: None, defines: [("Foo", 10), ("Alice", 30)] } - -$ typed-derive -D Foo -? failed -error: Invalid value "Foo" for '-D ': invalid KEY=value: no `=` found in `Foo` - -For more information try --help - -$ typed-derive -D Foo=Bar -? failed -error: Invalid value "Foo=Bar" for '-D ': invalid digit found in string - -For more information try --help - -``` diff --git a/vendor/clap/examples/typed-derive.rs b/vendor/clap/examples/typed-derive.rs deleted file mode 100644 index 31084029d..000000000 --- a/vendor/clap/examples/typed-derive.rs +++ /dev/null @@ -1,44 +0,0 @@ -use clap::Parser; -use std::error::Error; - -#[derive(Parser, Debug)] // requires `derive` feature -struct Args { - /// Implicitly using `std::str::FromStr` - #[clap(short = 'O', value_parser)] - optimization: Option, - - /// Allow invalid UTF-8 paths - #[clap(short = 'I', value_parser, value_name = "DIR", value_hint = clap::ValueHint::DirPath)] - include: Option, - - /// Handle IP addresses - #[clap(long, value_parser)] - bind: Option, - - /// Allow human-readable durations - #[clap(long, value_parser)] - sleep: Option, - - /// Hand-written parser for tuples - #[clap(short = 'D', value_parser = parse_key_val::)] - defines: Vec<(String, i32)>, -} - -/// Parse a single key-value pair -fn parse_key_val(s: &str) -> Result<(T, U), Box> -where - T: std::str::FromStr, - T::Err: Error + Send + Sync + 'static, - U: std::str::FromStr, - U::Err: Error + Send + Sync + 'static, -{ - let pos = s - .find('=') - .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?; - Ok((s[..pos].parse()?, s[pos + 1..].parse()?)) -} - -fn main() { - let args = Args::parse(); - println!("{:?}", args); -} diff --git a/vendor/clap/src/_cookbook/cargo_example.rs b/vendor/clap/src/_cookbook/cargo_example.rs deleted file mode 100644 index ec5d582db..000000000 --- a/vendor/clap/src/_cookbook/cargo_example.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: cargo subcommand (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/cargo-example.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/cargo-example.md")] diff --git a/vendor/clap/src/_cookbook/cargo_example_derive b/vendor/clap/src/_cookbook/cargo_example_derive deleted file mode 100644 index e69de29bb..000000000 diff --git a/vendor/clap/src/_cookbook/cargo_example_derive.rs b/vendor/clap/src/_cookbook/cargo_example_derive.rs deleted file mode 100644 index d49f956f9..000000000 --- a/vendor/clap/src/_cookbook/cargo_example_derive.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: cargo subcommand (Derive API) -//! -//! ```rust -#![doc = include_str!("../../examples/cargo-example-derive.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/cargo-example-derive.md")] diff --git a/vendor/clap/src/_cookbook/escaped_positional.rs b/vendor/clap/src/_cookbook/escaped_positional.rs deleted file mode 100644 index 99a3f83f3..000000000 --- a/vendor/clap/src/_cookbook/escaped_positional.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/escaped-positional.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/escaped-positional.md")] diff --git a/vendor/clap/src/_cookbook/escaped_positional_derive.rs b/vendor/clap/src/_cookbook/escaped_positional_derive.rs deleted file mode 100644 index e6f99ad17..000000000 --- a/vendor/clap/src/_cookbook/escaped_positional_derive.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example (Derive API) -//! -//! ```rust -#![doc = include_str!("../../examples/escaped-positional-derive.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/escaped-positional-derive.md")] diff --git a/vendor/clap/src/_cookbook/git.rs b/vendor/clap/src/_cookbook/git.rs deleted file mode 100644 index 03a926ca8..000000000 --- a/vendor/clap/src/_cookbook/git.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: git-like CLI (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/git.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/git.md")] diff --git a/vendor/clap/src/_cookbook/git_derive.rs b/vendor/clap/src/_cookbook/git_derive.rs deleted file mode 100644 index d3119736d..000000000 --- a/vendor/clap/src/_cookbook/git_derive.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: git-like CLI (Derive API) -//! -//! ```rust -#![doc = include_str!("../../examples/git-derive.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/git-derive.md")] diff --git a/vendor/clap/src/_cookbook/mod.rs b/vendor/clap/src/_cookbook/mod.rs deleted file mode 100644 index 1a78ed11b..000000000 --- a/vendor/clap/src/_cookbook/mod.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Contributing -// -// New examples: -// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. -// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax -// - Link the `.md` file from here - -//! # Documentation: Cookbook -//! -//! Typed arguments: [derive][typed_derive] -//! - Topics: -//! - Custom `parse()` -//! -//! Custom cargo command: [builder][cargo_example], [derive][cargo_example_derive] -//! - Topics: -//! - Subcommands -//! - Cargo plugins -//! -//! git-like interface: [builder][git], [derive][git_derive] -//! - Topics: -//! - Subcommands -//! - External subcommands -//! - Optional subcommands -//! - Default subcommands -//! -//! pacman-like interface: [builder][pacman] -//! - Topics: -//! - Flag subcommands -//! - Conflicting arguments -//! -//! Escaped positionals with `--`: [builder][escaped_positional], [derive][escaped_positional_derive] -//! -//! Multi-call -//! - busybox: [builder][multicall_busybox] -//! - Topics: -//! - Subcommands -//! - hostname: [builder][multicall_hostname] -//! - Topics: -//! - Subcommands -//! -//! repl: [builder][repl] -//! - Topics: -//! - Read-Eval-Print Loops / Custom command lines - -pub mod cargo_example; -pub mod cargo_example_derive; -pub mod escaped_positional; -pub mod escaped_positional_derive; -pub mod git; -pub mod git_derive; -pub mod multicall_busybox; -pub mod multicall_hostname; -pub mod pacman; -pub mod repl; -pub mod typed_derive; diff --git a/vendor/clap/src/_cookbook/multicall_busybox.rs b/vendor/clap/src/_cookbook/multicall_busybox.rs deleted file mode 100644 index e3384d682..000000000 --- a/vendor/clap/src/_cookbook/multicall_busybox.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: busybox-like CLI (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/multicall-busybox.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/multicall-busybox.md")] diff --git a/vendor/clap/src/_cookbook/multicall_hostname.rs b/vendor/clap/src/_cookbook/multicall_hostname.rs deleted file mode 100644 index 9777654dc..000000000 --- a/vendor/clap/src/_cookbook/multicall_hostname.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: hostname-like CLI (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/multicall-hostname.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/multicall-hostname.md")] diff --git a/vendor/clap/src/_cookbook/pacman.rs b/vendor/clap/src/_cookbook/pacman.rs deleted file mode 100644 index 880c58158..000000000 --- a/vendor/clap/src/_cookbook/pacman.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: pacman-like CLI (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/pacman.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/pacman.md")] diff --git a/vendor/clap/src/_cookbook/repl.rs b/vendor/clap/src/_cookbook/repl.rs deleted file mode 100644 index 549ec8259..000000000 --- a/vendor/clap/src/_cookbook/repl.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! # Example: Command REPL (Builder API) -//! -//! ```rust -#![doc = include_str!("../../examples/repl.rs")] -//! ``` diff --git a/vendor/clap/src/_cookbook/typed_derive.rs b/vendor/clap/src/_cookbook/typed_derive.rs deleted file mode 100644 index a5fd15ff8..000000000 --- a/vendor/clap/src/_cookbook/typed_derive.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! # Example: Custom Types (Derive API) -//! -//! ```rust -#![doc = include_str!("../../examples/typed-derive.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/typed-derive.md")] diff --git a/vendor/clap/src/_derive/_tutorial.rs b/vendor/clap/src/_derive/_tutorial.rs deleted file mode 100644 index abd57cef8..000000000 --- a/vendor/clap/src/_derive/_tutorial.rs +++ /dev/null @@ -1,205 +0,0 @@ -// Contributing -// -// New example code: -// - Please update the corresponding section in the derive tutorial -// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. -// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax -// -// See also the general CONTRIBUTING - -//! # Documentation: Derive Tutorial -//! -//! 1. [Quick Start](#quick-start) -//! 2. [Configuring the Parser](#configuring-the-parser) -//! 3. [Adding Arguments](#adding-arguments) -//! 1. [Positionals](#positionals) -//! 2. [Options](#options) -//! 3. [Flags](#flags) -//! 4. [Subcommands](#subcommands) -//! 5. [Defaults](#defaults) -//! 4. Validation -//! 1. [Enumerated values](#enumerated-values) -//! 2. [Validated values](#validated-values) -//! 3. [Argument Relations](#argument-relations) -//! 4. [Custom Validation](#custom-validation) -//! 5. [Testing](#testing) -//! -//! See also -//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis] -//! - The [cookbook][crate::_cookbook] for more application-focused examples -//! -//! ## Quick Start -//! -//! You can create an application declaratively with a `struct` and some -//! attributes. **This requires enabling the [`derive` feature flag][crate::_features].** -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/01_quick.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/tutorial_derive/01_quick.md")] -//! -//! ## Configuring the Parser -//! -//! You use derive [`Parser`][crate::Parser] to start building a parser. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/02_apps.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/tutorial_derive/02_apps.md")] -//! -//! You can use `#[clap(author, version, about)]` attribute defaults to fill these fields in from your `Cargo.toml` file. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/02_crate.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/02_crate.md")] -//! -//! You can use attributes to change the application level behavior of clap. Any [`Command`][crate::Command]] builder function can be used as an attribute. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/02_app_settings.md")] -//! -//! ## Adding Arguments -//! -//! ### Positionals -//! -//! You can have users specify values by their position on the command-line: -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/03_03_positional.md")] -//! -//! ### Options -//! -//! You can name your arguments with a flag: -//! - Order doesn't matter -//! - They can be optional -//! - Intent is clearer -//! -//! The `#[clap(short = 'n')]` and `#[clap(long = "name")]` attributes that define -//! the flags are [`Arg`][crate::Args] methods that are derived from the field name when no value -//! is specified (`#[clap(short)]` and `#[clap(long)]`). -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_02_option.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/03_02_option.md")] -//! -//! ### Flags -//! -//! Flags can also be switches that can be on/off. This is enabled via the -//! `#[clap(action = ArgAction::SetTrue)]` attribute though this is implied when the field is a -//! `bool`. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_bool.md")] -//! -//! Or counted with `#[clap(action = clap::ArgAction::Count)]`: -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/03_01_flag_count.md")] -//! -//! ### Subcommands -//! -//! Subcommands are derived with `#[derive(Subcommand)]` and be added via `#[clap(subcommand)]` attribute. Each -//! instance of a [Subcommand][crate::Subcommand] can have its own version, author(s), Args, and even its own -//! subcommands. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.rs")] -//! ``` -//! We used a struct-variant to define the `add` subcommand. -//! Alternatively, you can use a struct for your subcommand's arguments: -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands_alt.rs")] -//! ``` -//! -#![doc = include_str!("../../examples/tutorial_derive/03_04_subcommands.md")] -//! -//! ### Defaults -//! -//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional. -//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can -//! set `#[clap(default_value_t)]`. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/03_05_default_values.md")] -//! -//! ## Validation -//! -//! ### Enumerated values -//! -//! If you have arguments of specific values you want to test for, you can derive -//! [`ValueEnum`][crate::ValueEnum]. -//! -//! This allows you specify the valid values for that argument. If the user does not use one of -//! those specific values, they will receive a graceful exit with error message informing them -//! of the mistake, and what the possible valid values are -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/04_01_enum.md")] -//! -//! ### Validated values -//! -//! More generally, you can validate and parse into any data type. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/04_02_parse.md")] -//! -//! A custom parser can be used to improve the error messages or provide additional validation: -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/04_02_validate.md")] -//! -//! ### Argument Relations -//! -//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even -//! [`ArgGroup`][crate::ArgGroup]s. -//! -//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list -//! each individually, or when you want a rule to apply "any but not all" arguments. -//! -//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one -//! argument to be present out of a given set. Imagine that you had multiple arguments, and you -//! want one of them to be required, but making all of them required isn't feasible because perhaps -//! they conflict with each other. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/04_03_relations.md")] -//! -//! ### Custom Validation -//! -//! As a last resort, you can create custom errors with the basics of clap's formatting. -//! -//! ```rust -#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.rs")] -//! ``` -#![doc = include_str!("../../examples/tutorial_derive/04_04_custom.md")] -//! -//! ## Testing -//! -//! clap reports most development errors as `debug_assert!`s. Rather than checking every -//! subcommand, you should have a test that calls -//! [`Command::debug_assert`][crate::App::debug_assert]: -//! ```rust,no_run -#![doc = include_str!("../../examples/tutorial_derive/05_01_assert.rs")] -//! ``` diff --git a/vendor/clap/src/_derive/mod.rs b/vendor/clap/src/_derive/mod.rs deleted file mode 100644 index fc9f35db5..000000000 --- a/vendor/clap/src/_derive/mod.rs +++ /dev/null @@ -1,510 +0,0 @@ -//! # Documentation: Derive Reference -//! -//! 1. [Overview](#overview) -//! 2. [Attributes](#attributes) -//! 1. [Terminology](#terminology) -//! 2. [Command Attributes](#command-attributes) -//! 3. [Arg Attributes](#arg-attributes) -//! 4. [ValueEnum Attributes](#valueenum-attributes) -//! 5. [Possible Value Attributes](#possible-value-attributes) -//! 3. [Arg Types](#arg-types) -//! 4. [Doc Comments](#doc-comments) -//! 5. [Mixing Builder and Derive APIs](#mixing-builder-and-derive-apis) -//! 6. [Tips](#tips) -//! -//! ## Overview -//! -//! To derive `clap` types, you need to enable the [`derive` feature flag][crate::_features]. -//! -//! Example: -//! ```rust -#![doc = include_str!("../../examples/demo.rs")] -//! ``` -//! -//! Let's start by breaking down the anatomy of the derive attributes: -//! ```rust -//! use clap::{Parser, Args, Subcommand, ValueEnum}; -//! -//! /// Doc comment -//! #[derive(Parser)] -//! #[clap(APP ATTRIBUTE)] -//! struct Cli { -//! /// Doc comment -//! #[clap(ARG ATTRIBUTE)] -//! field: UserType, -//! -//! #[clap(value_enum, ARG ATTRIBUTE...)] -//! field: EnumValues, -//! -//! #[clap(flatten)] -//! delegate: Struct, -//! -//! #[clap(subcommand)] -//! command: Command, -//! } -//! -//! /// Doc comment -//! #[derive(Args)] -//! #[clap(PARENT APP ATTRIBUTE)] -//! struct Struct { -//! /// Doc comment -//! #[clap(ARG ATTRIBUTE)] -//! field: UserType, -//! } -//! -//! /// Doc comment -//! #[derive(Subcommand)] -//! #[clap(PARENT APP ATTRIBUTE)] -//! enum Command { -//! /// Doc comment -//! #[clap(APP ATTRIBUTE)] -//! Variant1(Struct), -//! -//! /// Doc comment -//! #[clap(APP ATTRIBUTE)] -//! Variant2 { -//! /// Doc comment -//! #[clap(ARG ATTRIBUTE)] -//! field: UserType, -//! } -//! } -//! -//! /// Doc comment -//! #[derive(ValueEnum)] -//! #[clap(VALUE ENUM ATTRIBUTE)] -//! enum EnumValues { -//! /// Doc comment -//! #[clap(POSSIBLE VALUE ATTRIBUTE)] -//! Variant1, -//! } -//! -//! fn main() { -//! let cli = Cli::parse(); -//! } -//! ``` -//! -//! Traits: -//! - [`Parser`][crate::Parser] parses arguments into a `struct` (arguments) or `enum` (subcommands). -//! - [`Args`][crate::Args] allows defining a set of re-usable arguments that get merged into their parent container. -//! - [`Subcommand`][crate::Subcommand] defines available subcommands. -//! - Subcommand arguments can be defined in a struct-variant or automatically flattened with a tuple-variant. -//! - [`ValueEnum`][crate::ValueEnum] allows parsing a value directly into an `enum`, erroring on unsupported values. -//! - The derive doesn't work on enums that contain non-unit variants, unless they are skipped -//! -//! *See also the [derive tutorial][crate::_derive::_tutorial] and [cookbook][crate::_cookbook]* -//! -//! ## Attributes -//! -//! ### Terminology -//! -//! **Raw attributes** are forwarded directly to the underlying [`clap` builder][crate::builder]. Any -//! [`Command`][crate::Command], [`Arg`][crate::Arg], or [`PossibleValue`][crate::PossibleValue] method can be used as an attribute. -//! -//! Raw attributes come in two different syntaxes: -//! ```rust,ignore -//! #[clap( -//! global = true, // name = arg form, neat for one-arg methods -//! required_if_eq("out", "file") // name(arg1, arg2, ...) form. -//! )] -//! ``` -//! -//! - `method = arg` can only be used for methods which take only one argument. -//! - `method(arg1, arg2)` can be used with any method. -//! -//! As long as `method_name` is not one of the magical methods it will be -//! translated into a mere method call. -//! -//! **Magic attributes** have post-processing done to them, whether that is -//! - Providing of defaults -//! - Special behavior is triggered off of it -//! -//! Magic attributes are more constrained in the syntax they support, usually just -//! ` = ` though some use `()` instead. See the specific -//! magic attributes documentation for details. This allows users to access the -//! raw behavior of an attribute via `()` syntax. -//! -//! **NOTE:** Some attributes are inferred from [Arg Types](#arg-types) and [Doc -//! Comments](#doc-comments). Explicit attributes take precedence over inferred -//! attributes. -//! -//! ### Command Attributes -//! -//! These correspond to a [`Command`][crate::Command] which is used for both top-level parsers and -//! when defining subcommands. -//! -//! **Raw attributes:** Any [`Command` method][crate::Command] can also be used as an attribute, -//! see [Terminology](#terminology) for syntax. -//! - e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)` -//! -//! **Magic attributes:** -//! - `name = `: [`Command::name`][crate::App::name] -//! - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (if on [`Parser`][crate::Parser] container), variant name (if on [`Subcommand`][crate::Subcommand] variant) -//! - `version [= ]`: [`Command::version`][crate::App::version] -//! - When not present: no version set -//! - Without ``: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field) -//! - `author [= ]`: [`Command::author`][crate::App::author] -//! - When not present: no author set -//! - Without ``: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field) -//! - `about [= ]`: [`Command::about`][crate::App::about] -//! - When not present: [Doc comment summary](#doc-comments) -//! - Without ``: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) ([`Parser`][crate::Parser] container) -//! - **TIP:** When a doc comment is also present, you most likely want to add -//! `#[clap(long_about = None)]` to clear the doc comment so only [`about`][crate::App::about] -//! gets shown with both `-h` and `--help`. -//! - `long_about = `: [`Command::long_about`][crate::App::long_about] -//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing -//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`about`][crate::App::about] / [`long_about`][crate::App::long_about] -//! - `next_display_order`: [`Command::next_display_order`][crate::App::next_display_order] -//! - `next_help_heading`: [`Command::next_help_heading`][crate::App::next_help_heading] -//! - When `flatten`ing [`Args`][crate::Args], this is scoped to just the args in this struct and any struct `flatten`ed into it -//! - `rename_all = `: Override default field / variant name case conversion for [`Command::name`][crate::Command::name] / [`Arg::id`][crate::Arg::id] -//! - When not present: `"kebab-case"` -//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"` -//! - `rename_all_env = `: Override default field name case conversion for env variables for [`Arg::env`][crate::Arg::env] -//! - When not present: `"SCREAMING_SNAKE_CASE"` -//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"` -//! -//! And for [`Subcommand`][crate::Subcommand] variants: -//! - `skip`: Ignore this variant -//! - `flatten`: Delegates to the variant for more subcommands (must implement -//! [`Subcommand`][crate::Subcommand]) -//! - `subcommand`: Nest subcommands under the current set of subcommands (must implement -//! [`Subcommand`][crate::Subcommand]) -//! - `external_subcommand`: [`Command::allow_external_subcommand(true)`][crate::App::allow_external_subcommands] -//! - Variant must be either `Variant(Vec)` or `Variant(Vec)` -//! -//! ### Arg Attributes -//! -//! These correspond to a [`Arg`][crate::Arg]. -//! -//! **Raw attributes:** Any [`Arg` method][crate::Arg] can also be used as an attribute, see [Terminology](#terminology) for syntax. -//! - e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)` -//! -//! **Magic attributes**: -//! - `id = `: [`Arg::id`][crate::Arg::id] -//! - When not present: case-converted field name is used -//! - `name = `: [`Arg::id`][crate::Arg::id] -//! - **Deprecated:** use `id` -//! - `value_parser [= ]`: [`Arg::value_parser`][crate::Arg::value_parser] -//! - When not present: will auto-select an implementation based on the field type using -//! [`value_parser!][crate::value_parser!] -//! - When present but defaulted: opt-in to clap v4 semantics -//! - Env parsing is now dependent on inferred parser -//! - `PathBuf` will implicitly skip UTF-8 validation (before it required specifying -//! `try_from_os_str`) -//! - When present, implies `#[clap(action)]` -//! - To register a custom type's [`ValueParser`][crate::builder::ValueParser], implement [`ValueParserFactory`][crate::builder::ValueParserFactory] -//! - `action [= ]`: [`Arg::action`][crate::Arg::action] -//! - When not present: will auto-select an action based on the field type -//! - When present but defaulted: opt-in to clap v4 semantics -//! - When present, implies `#[clap(value_parser)]` -//! - `args_override_self` is forced on for single flags -//! - `help = `: [`Arg::help`][crate::Arg::help] -//! - When not present: [Doc comment summary](#doc-comments) -//! - `long_help = `: [`Arg::long_help`][crate::Arg::long_help] -//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing -//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`help`][crate::Arg::help] / [`long_help`][crate::Arg::long_help] -//! - `short [= ]`: [`Arg::short`][crate::Arg::short] -//! - When not present: no short set -//! - Without ``: defaults to first character in the case-converted field name -//! - `long [= ]`: [`Arg::long`][crate::Arg::long] -//! - When not present: no long set -//! - Without ``: defaults to the case-converted field name -//! - `env [= ]`: [`Arg::env`][crate::Arg::env] (needs [`env` feature][crate::_features] enabled) -//! - When not present: no env set -//! - Without ``: defaults to the case-converted field name -//! - `flatten`: Delegates to the field for more arguments (must implement [`Args`][crate::Args]) -//! - Only [`next_help_heading`][crate::Command::next_help_heading] can be used with `flatten`. See -//! [clap-rs/clap#3269](https://github.com/clap-rs/clap/issues/3269) for why -//! arg attributes are not generally supported. -//! - **Tip:** Though we do apply a flattened [`Args`][crate::Args]'s Parent Command Attributes, this -//! makes reuse harder. Generally prefer putting the cmd attributes on the -//! [`Parser`][crate::Parser] or on the flattened field. -//! - `subcommand`: Delegates definition of subcommands to the field (must implement -//! [`Subcommand`][crate::Subcommand]) -//! - When `Option`, the subcommand becomes optional -//! - `from_global`: Read a [`Arg::global`][crate::Arg::global] argument (raw attribute), regardless of what subcommand you are in -//! - `parse( [= ])`: [`Arg::validator`][crate::Arg::validator] and [`ArgMatches::values_of_t`][crate::ArgMatches::values_of_t] -//! - **Deprecated:** -//! - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str` -//! - Use `action(ArgAction::Count` for `from_occurrences` -//! - Use `action(ArgAction::SetTrue` for `from_flag` -//! - Default: `try_from_str` -//! - Warning: for `Path` / `OsString`, be sure to use `try_from_os_str` -//! - See [Arg Types](#arg-types) for more details -//! - `value_enum`: Parse the value using the [`ValueEnum`][crate::ValueEnum] -//! - `skip [= ]`: Ignore this field, filling in with `` -//! - Without ``: fills the field with `Default::default()` -//! - `default_value = `: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required] -//! - `default_value_t [= ]`: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required] -//! - Requires `std::fmt::Display` or `#[clap(value_enum)]` -//! - Without ``, relies on `Default::default()` -//! - `default_values_t = `: [`Arg::default_values`][crate::Arg::default_values] and [`Arg::required(false)`][crate::Arg::required] -//! - Requires field arg to be of type `Vec` and `T` to implement `std::fmt::Display` or `#[clap(value_enum)]` -//! - `` must implement `IntoIterator` -//! - `default_value_os_t [= ]`: [`Arg::default_value_os`][crate::Arg::default_value_os] and [`Arg::required(false)`][crate::Arg::required] -//! - Requires `std::convert::Into` or `#[clap(value_enum)]` -//! - Without ``, relies on `Default::default()` -//! - `default_values_os_t = `: [`Arg::default_values_os`][crate::Arg::default_values_os] and [`Arg::required(false)`][crate::Arg::required] -//! - Requires field arg to be of type `Vec` and `T` to implement `std::convert::Into` or `#[clap(value_enum)]` -//! - `` must implement `IntoIterator` -//! -//! ### ValueEnum Attributes -//! -//! - `rename_all = `: Override default field / variant name case conversion for [`PossibleValue::new`][crate::PossibleValue] -//! - When not present: `"kebab-case"` -//! - Available values: `"camelCase"`, `"kebab-case"`, `"PascalCase"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"lower"`, `"UPPER"`, `"verbatim"` -//! -//! ### Possible Value Attributes -//! -//! These correspond to a [`PossibleValue`][crate::PossibleValue]. -//! -//! **Raw attributes:** Any [`PossibleValue` method][crate::PossibleValue] can also be used as an attribute, see [Terminology](#terminology) for syntax. -//! - e.g. `#[clap(alias("foo"))]` would translate to `pv.alias("foo")` -//! -//! **Magic attributes**: -//! - `name = `: [`PossibleValue::new`][crate::PossibleValue::new] -//! - When not present: case-converted field name is used -//! - `help = `: [`PossibleValue::help`][crate::PossibleValue::help] -//! - When not present: [Doc comment summary](#doc-comments) -//! -//! ## Arg Types -//! -//! `clap` assumes some intent based on the type used: -//! -//! | Type | Effect | Implies | -//! |---------------------|--------------------------------------|------------------------------------------------------------------| -//! | `bool` | flag | `#[clap(parse(from_flag))]` | -//! | `Option` | optional argument | `.takes_value(true).required(false)` | -//! | `Option>` | optional value for optional argument | `.takes_value(true).required(false).min_values(0).max_values(1)` | -//! | `T` | required argument | `.takes_value(true).required(!has_default)` | -//! | `Vec` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` | -//! | `Option>` | `0..` occurrences of argument | `.takes_value(true).required(false).multiple_occurrences(true)` | -//! -//! Notes: -//! - For custom type behavior, you can override the implied attributes/settings and/or set additional ones -//! - For example, see [custom-bool](./custom-bool.md) -//! - `Option>` will be `None` instead of `vec![]` if no arguments are provided. -//! - This gives the user some flexibility in designing their argument, like with `min_values(0)` -//! -//! You can then support your custom type with `#[clap(parse( [= ]))]`: -//! -//! | `` | Signature | Default `` | -//! |--------------------------|---------------------------------------|---------------------------------| -//! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | -//! | `try_from_str` (default) | `fn(&str) -> Result` | `::std::str::FromStr::from_str` | -//! | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` | -//! | `try_from_os_str` | `fn(&OsStr) -> Result` | (no default function) | -//! | `from_occurrences` | `fn(u64) -> T` | `value as T` | -//! | `from_flag` | `fn(bool) -> T` | `::std::convert::From::from` | -//! -//! Notes: -//! - `from_os_str`: -//! - Implies `arg.takes_value(true).allow_invalid_utf8(true)` -//! - `try_from_os_str`: -//! - Implies `arg.takes_value(true).allow_invalid_utf8(true)` -//! - `from_occurrences`: -//! - Implies `arg.takes_value(false).multiple_occurrences(true)` -//! - Reads from `clap::ArgMatches::occurrences_of` rather than a `get_one` function -//! - Note: operations on values, like `default_value`, are unlikely to do what you want -//! - `from_flag` -//! - Implies `arg.takes_value(false)` -//! - Reads from `clap::ArgMatches::is_present` rather than a `get_one` function -//! - Note: operations on values, like `default_value`, are unlikely to do what you want -//! -//! **Warning:** -//! - To support non-UTF8 paths, you should use `#[clap(value_parser)]` otherwise -//! `clap` will parse it as a `String` which will fail on some paths. -//! -//! ## Doc Comments -//! -//! In clap, help messages for the whole binary can be specified -//! via [`Command::about`][crate::App::about] and [`Command::long_about`][crate::App::long_about] while help messages -//! for individual arguments can be specified via [`Arg::help`][crate::Arg::help] and [`Arg::long_help`][crate::Arg::long_help]. -//! -//! `long_*` variants are used when user calls the program with -//! `--help` and "short" variants are used with `-h` flag. -//! -//! ```rust -//! # use clap::Parser; -//! -//! #[derive(Parser)] -//! #[clap(about = "I am a program and I work, just pass `-h`", long_about = None)] -//! struct Foo { -//! #[clap(short, help = "Pass `-h` and you'll see me!")] -//! bar: String, -//! } -//! ``` -//! -//! For convenience, doc comments can be used instead of raw methods -//! (this example works exactly like the one above): -//! -//! ```rust -//! # use clap::Parser; -//! -//! #[derive(Parser)] -//! /// I am a program and I work, just pass `-h` -//! struct Foo { -//! /// Pass `-h` and you'll see me! -//! bar: String, -//! } -//! ``` -//! -//! **NOTE:** Attributes have priority over doc comments! -//! -//! **Top level doc comments always generate `Command::about/long_about` calls!** -//! If you really want to use the `Command::about/long_about` methods (you likely don't), -//! use the `about` / `long_about` attributes to override the calls generated from -//! the doc comment. To clear `long_about`, you can use -//! `#[clap(long_about = None)]`. -//! -//! **TIP:** Set `#![deny(missing_docs)]` to catch missing `--help` documentation at compile time. -//! -//! ### Pre-processing -//! -//! ```rust -//! # use clap::Parser; -//! #[derive(Parser)] -//! /// Hi there, I'm Robo! -//! /// -//! /// I like beeping, stumbling, eating your electricity, -//! /// and making records of you singing in a shower. -//! /// Pay up, or I'll upload it to youtube! -//! struct Robo { -//! /// Call my brother SkyNet. -//! /// -//! /// I am artificial superintelligence. I won't rest -//! /// until I'll have destroyed humanity. Enjoy your -//! /// pathetic existence, you mere mortals. -//! #[clap(long, action)] -//! kill_all_humans: bool, -//! } -//! ``` -//! -//! A doc comment consists of three parts: -//! - Short summary -//! - A blank line (whitespace only) -//! - Detailed description, all the rest -//! -//! The summary corresponds with `Command::about` / `Arg::help`. When a blank line is -//! present, the whole doc comment will be passed to `Command::long_about` / -//! `Arg::long_help`. Or in other words, a doc may result in just a `Command::about` / -//! `Arg::help` or `Command::about` / `Arg::help` and `Command::long_about` / -//! `Arg::long_help` -//! -//! In addition, when `verbatim_doc_comment` is not present, `clap` applies some preprocessing, including: -//! -//! - Strip leading and trailing whitespace from every line, if present. -//! -//! - Strip leading and trailing blank lines, if present. -//! -//! - Interpret each group of non-empty lines as a word-wrapped paragraph. -//! -//! We replace newlines within paragraphs with spaces to allow the output -//! to be re-wrapped to the terminal width. -//! -//! - Strip any excess blank lines so that there is exactly one per paragraph break. -//! -//! - If the first paragraph ends in exactly one period, -//! remove the trailing period (i.e. strip trailing periods but not trailing ellipses). -//! -//! Sometimes you don't want this preprocessing to apply, for example the comment contains -//! some ASCII art or markdown tables, you would need to preserve LFs along with -//! blank lines and the leading/trailing whitespace. When you pass use the -//! `verbatim_doc_comment` magic attribute, you preserve -//! them. -//! -//! **Note:** Keep in mind that `verbatim_doc_comment` will *still* -//! - Remove one leading space from each line, even if this attribute is present, -//! to allow for a space between `///` and the content. -//! - Remove leading and trailing blank lines -//! -//! ## Mixing Builder and Derive APIs -//! -//! The builder and derive APIs do not live in isolation. They can work together, which is -//! especially helpful if some arguments can be specified at compile-time while others must be -//! specified at runtime. -//! -//! ### Using derived arguments in a builder application -//! -//! When using the derive API, you can `#[clap(flatten)]` a struct deriving `Args` into a struct -//! deriving `Args` or `Parser`. This example shows how you can augment a `Command` instance -//! created using the builder API with `Args` created using the derive API. -//! -//! It uses the [`Args::augment_args`][crate::Args::augment_args] method to add the arguments to -//! the `Command` instance. -//! -//! Crates such as [clap-verbosity-flag](https://github.com/rust-cli/clap-verbosity-flag) provide -//! structs that implement `Args`. Without the technique shown in this example, it would not be -//! possible to use such crates with the builder API. -//! -//! For example: -//! ```rust -#![doc = include_str!("../../examples/derive_ref/augment_args.rs")] -//! ``` -//! -//! ### Using derived subcommands in a builder application -//! -//! When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add -//! subcommands. The type of the field is usually an enum that derived `Parser`. However, you can -//! also add the subcommands in that enum to a `Command` instance created with the builder API. -//! -//! It uses the [`Subcommand::augment_subcommands`][crate::Subcommand::augment_subcommands] method -//! to add the subcommands to the `Command` instance. -//! -//! For example: -//! ```rust -#![doc = include_str!("../../examples/derive_ref/augment_subcommands.rs")] -//! ``` -//! -//! ### Adding hand-implemented subcommands to a derived application -//! -//! When using the derive API, you can use `#[clap(subcommand)]` inside the struct to add -//! subcommands. The type of the field is usually an enum that derived `Parser`. However, you can -//! also implement the `Subcommand` trait manually on this enum (or any other type) and it can -//! still be used inside the struct created with the derive API. The implementation of the -//! `Subcommand` trait will use the builder API to add the subcommands to the `Command` instance -//! created behind the scenes for you by the derive API. -//! -//! Notice how in the previous example we used -//! [`augment_subcommands`][crate::Subcommand::augment_subcommands] on an enum that derived -//! `Parser`, whereas now we implement -//! [`augment_subcommands`][crate::Subcommand::augment_subcommands] ourselves, but the derive API -//! calls it automatically since we used the `#[clap(subcommand)]` attribute. -//! -//! For example: -//! ```rust -#![doc = include_str!("../../examples/derive_ref/hand_subcommand.rs")] -//! ``` -//! -//! ### Flattening hand-implemented args into a derived application -//! -//! When using the derive API, you can use `#[clap(flatten)]` inside the struct to add arguments as -//! if they were added directly to the containing struct. The type of the field is usually an -//! struct that derived `Args`. However, you can also implement the `Args` trait manually on this -//! struct (or any other type) and it can still be used inside the struct created with the derive -//! API. The implementation of the `Args` trait will use the builder API to add the arguments to -//! the `Command` instance created behind the scenes for you by the derive API. -//! -//! Notice how in the previous example we used [`augment_args`][crate::Args::augment_args] on the -//! struct that derived `Parser`, whereas now we implement -//! [`augment_args`][crate::Args::augment_args] ourselves, but the derive API calls it -//! automatically since we used the `#[clap(flatten)]` attribute. -//! -//! For example: -//! ```rust -#![doc = include_str!("../../examples/derive_ref/flatten_hand_args.rs")] -//! ``` -//! -//! ## Tips -//! -//! - To get access to a [`Command`][crate::Command] call -//! [`CommandFactory::command`][crate::CommandFactory::command] (implemented when deriving -//! [`Parser`][crate::Parser]) -//! - Proactively check for bad [`Command`][crate::Command] configurations by calling -//! [`Command::debug_assert`][crate::App::debug_assert] in a test -//! ([example](../tutorial_derive/05_01_assert.rs)) - -pub mod _tutorial; -#[doc(inline)] -pub use crate::_cookbook; diff --git a/vendor/clap/src/_faq.rs b/vendor/clap/src/_faq.rs deleted file mode 100644 index 661a7e73d..000000000 --- a/vendor/clap/src/_faq.rs +++ /dev/null @@ -1,95 +0,0 @@ -//! # Documentation: FAQ -//! -//! 1. [Comparisons](#comparisons) -//! 1. [How does `clap` compare to structopt?](#how-does-clap-compare-to-structopt) -//! 2. [What are some reasons to use `clap`? (The Pitch)](#what-are-some-reasons-to-use-clap-the-pitch) -//! 3. [What are some reasons *not* to use `clap`? (The Anti Pitch)](#what-are-some-reasons-not-to-use-clap-the-anti-pitch) -//! 4. [Reasons to use `clap`](#reasons-to-use-clap) -//! 2. [How many approaches are there to create a parser?](#how-many-approaches-are-there-to-create-a-parser) -//! 3. [When should I use the builder vs derive APIs?](#when-should-i-use-the-builder-vs-derive-apis) -//! 4. [Why is there a default subcommand of help?](#why-is-there-a-default-subcommand-of-help) -//! -//! ### Comparisons -//! -//! First, let me say that these comparisons are highly subjective, and not meant -//! in a critical or harsh manner. All the argument parsing libraries out there (to -//! include `clap`) have their own strengths and weaknesses. Sometimes it just -//! comes down to personal taste when all other factors are equal. When in doubt, -//! try them all and pick one that you enjoy :) There's plenty of room in the Rust -//! community for multiple implementations! -//! -//! For less detailed but more broad comparisons, see -//! [argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs). -//! -//! #### How does `clap` compare to [structopt](https://github.com/TeXitoi/structopt)? -//! -//! Simple! `clap` *is* `structopt`. `structopt` started as a derive API built on -//! top of clap v2. With clap v3, we've forked structopt and integrated it -//! directly into clap. structopt is in -//! [maintenance mode](https://github.com/TeXitoi/structopt/issues/516#issuecomment-989566094) -//! with the release of `clap_derive`. -//! -//! The benefits of integrating `structopt` and `clap` are: -//! - Easier cross-linking in documentation -//! - [Documentation parity](../examples) -//! - Tighter design feedback loop, ensuring all new features are designed with -//! derives in mind and easier to change `clap` in response to `structopt` bugs. -//! - Clearer endorsement of `structopt` -//! -//! See also -//! - [`clap` v3 CHANGELOG](../CHANGELOG.md#300---2021-12-31) -//! - [`structopt` migration guide](../CHANGELOG.md#migrate-structopt) -//! -//! #### What are some reasons to use `clap`? (The Pitch) -//! -//! `clap` is as fast, and as lightweight as possible while still giving all the features you'd expect from a modern argument parser. In fact, for the amount and type of features `clap` offers it remains about as fast as `getopts`. If you use `clap` when just need some simple arguments parsed, you'll find it's a walk in the park. `clap` also makes it possible to represent extremely complex, and advanced requirements, without too much thought. `clap` aims to be intuitive, easy to use, and fully capable for wide variety use cases and needs. -//! -//! #### What are some reasons *not* to use `clap`? (The Anti Pitch) -//! -//! Depending on the style in which you choose to define the valid arguments, `clap` can be very verbose. `clap` also offers so many finetuning knobs and dials, that learning everything can seem overwhelming. I strive to keep the simple cases simple, but when turning all those custom dials it can get complex. `clap` is also opinionated about parsing. Even though so much can be tweaked and tuned with `clap` (and I'm adding more all the time), there are still certain features which `clap` implements in specific ways which may be contrary to some users use-cases. -//! -//! #### Reasons to use `clap` -//! -//! * You want all the nice CLI features your users may expect, yet you don't want to implement them all yourself. You'd like to focus your application, not argument parsing. -//! * In addition to the point above; you don't want to sacrifice performance to get all those nice features -//! * You have complex requirements/conflicts between your various valid args. -//! * You want to use subcommands (although other libraries also support subcommands, they are not nearly as feature rich as those provided by `clap`) -//! * You want some sort of custom validation built into the argument parsing process, instead of as part of your application (which allows for earlier failures, better error messages, more cohesive experience, etc.) -//! -//! ### How many approaches are there to create a parser? -//! -//! The following APIs are supported: -//! - [Derive][crate::_derive::_tutorial] -//! - [Builder][crate::_tutorial] -//! -//! Previously, we supported: -//! - [YAML](https://github.com/clap-rs/clap/issues/3087) -//! - [docopt](http://docopt.org/)-inspired [usage parser](https://github.com/clap-rs/clap/issues/3086) -//! - [`clap_app!`](https://github.com/clap-rs/clap/issues/2835) -//! -//! There are also experiments with other APIs: -//! - [fncmd](https://github.com/yuhr/fncmd): function attribute -//! - [clap-serde](https://github.com/aobatact/clap-serde): create an `Command` from a deserializer -//! -//! ### When should I use the builder vs derive APIs? -//! -//! Our default answer is to use the [Derive API][crate::_derive::_tutorial]: -//! - Easier to read, write, and modify -//! - Easier to keep the argument declaration and reading of argument in sync -//! - Easier to reuse, e.g. [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag) -//! -//! The [Builder API][crate::_tutorial] is a lower-level API that someone might want to use for -//! - Faster compile times if you aren't already using other procedural macros -//! - More flexibility, e.g. you can look up an [arguments values][crate::ArgMatches::get_many], -//! their [ordering with other arguments][crate::ArgMatches::indices_of], and [what set -//! them][crate::ArgMatches::value_source]. The Derive API can only report values and not -//! indices of or other data. -//! -//! You can [interop between Derive and Builder APIs][crate::_derive#mixing-builder-and-derive-apis]. -//! -//! ### Why is there a default subcommand of help? -//! -//! There is only a default subcommand of `help` when other subcommands have been defined manually. So it's opt-in(ish), being that you only get a `help` subcommand if you're actually using subcommands. -//! -//! Also, if the user defined a `help` subcommand themselves, the auto-generated one wouldn't be added (meaning it's only generated if the user hasn't defined one themselves). -//! diff --git a/vendor/clap/src/_features.rs b/vendor/clap/src/_features.rs deleted file mode 100644 index 923134c45..000000000 --- a/vendor/clap/src/_features.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! ## Documentation: Feature Flags -//! -//! Available [compile-time feature flags](https://doc.rust-lang.org/cargo/reference/features.html#dependency-features) -//! -//! #### Default Features -//! -//! * **std**: _Not Currently Used._ Placeholder for supporting `no_std` environments in a backwards compatible manner. -//! * **color**: Turns on colored error messages. -//! * **suggestions**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. -//! -//! #### Optional features -//! -//! * **deprecated**: Guided experience to prepare for next breaking release (at different stages of development, this may become default) -//! * **derive**: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above. -//! * **cargo**: Turns on macros that read values from [`CARGO_*` environment variables](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates). -//! * **env**: Turns on the usage of environment variables during parsing. -//! * **regex**: Enables regex validators. -//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages. -//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size. -//! -//! #### Experimental features -//! -//! **Warning:** These may contain breaking changes between minor releases. -//! -//! * **unstable-replace**: Enable [`Command::replace`](https://github.com/clap-rs/clap/issues/2836) -//! * **unstable-grouped**: Enable [`ArgMatches::grouped_values_of`](https://github.com/clap-rs/clap/issues/2924) -//! * **unstable-v4**: Preview features which will be stable on the v4.0 release diff --git a/vendor/clap/src/_tutorial.rs b/vendor/clap/src/_tutorial.rs deleted file mode 100644 index 9dbfc6864..000000000 --- a/vendor/clap/src/_tutorial.rs +++ /dev/null @@ -1,204 +0,0 @@ -// Contributing -// -// New example code: -// - Please update the corresponding section in the derive tutorial -// - Building: They must be added to `Cargo.toml` with the appropriate `required-features`. -// - Testing: Ensure there is a markdown file with [trycmd](https://docs.rs/trycmd) syntax -// -// See also the general CONTRIBUTING - -//! # Documentation: Builder Tutorial -//! -//! 1. [Quick Start](#quick-start) -//! 2. [Configuring the Parser](#configuring-the-parser) -//! 3. [Adding Arguments](#adding-arguments) -//! 1. [Positionals](#positionals) -//! 2. [Options](#options) -//! 3. [Flags](#flags) -//! 4. [Subcommands](#subcommands) -//! 5. [Defaults](#defaults) -//! 4. Validation -//! 1. [Enumerated values](#enumerated-values) -//! 2. [Validated values](#validated-values) -//! 3. [Argument Relations](#argument-relations) -//! 4. [Custom Validation](#custom-validation) -//! 5. [Testing](#testing) -//! -//! See also -//! - [FAQ: When should I use the builder vs derive APIs?][crate::_faq#when-should-i-use-the-builder-vs-derive-apis] -//! - The [cookbook][crate::_cookbook] for more application-focused examples -//! -//! ## Quick Start -//! -//! You can create an application with several arguments using usage strings. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/01_quick.rs")] -//! ``` -//! -#![doc = include_str!("../examples/tutorial_builder/01_quick.md")] -//! -//! ## Configuring the Parser -//! -//! You use [`Command`][crate::Command] to start building a parser. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/02_apps.rs")] -//! ``` -//! -#![doc = include_str!("../examples/tutorial_builder/02_apps.md")] -//! -//! You can use [`command!()`][crate::command!] to fill these fields in from your `Cargo.toml` -//! file. **This requires the [`cargo` feature flag][crate::_features].** -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/02_crate.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/02_crate.md")] -//! -//! You can use [`Command`][crate::Command] methods to change the application level behavior of -//! clap. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/02_app_settings.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/02_app_settings.md")] -//! -//! ## Adding Arguments -//! -//! ### Positionals -//! -//! You can have users specify values by their position on the command-line: -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/03_03_positional.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/03_03_positional.md")] -//! -//! ### Options -//! -//! You can name your arguments with a flag: -//! - Order doesn't matter -//! - They can be optional -//! - Intent is clearer -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/03_02_option.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/03_02_option.md")] -//! -//! ### Flags -//! -//! Flags can also be switches that can be on/off: -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/03_01_flag_bool.md")] -//! -//! Or counted. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/03_01_flag_count.md")] -//! -//! ### Subcommands -//! -//! Subcommands are defined as [`Command`][crate::Command]s that get added via -//! [`Command::subcommand`][crate::Command::subcommand]. Each instance of a Subcommand can have its -//! own version, author(s), Args, and even its own subcommands. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/03_04_subcommands.md")] -//! -//! ### Defaults -//! -//! We've previously showed that arguments can be [`required`][crate::Arg::required] or optional. -//! When optional, you work with a `Option` and can `unwrap_or`. Alternatively, you can set -//! [`Arg::default_value`][crate::Arg::default_value]. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/03_05_default_values.md")] -//! -//! ## Validation -//! -//! ### Enumerated values -//! -//! If you have arguments of specific values you want to test for, you can use the -//! [`PossibleValuesParser`][crate::builder::PossibleValuesParser] or [`Arg::value_parser(["val1", -//! ...])`][crate::Arg::value_parser] for short. -//! -//! This allows you specify the valid values for that argument. If the user does not use one of -//! those specific values, they will receive a graceful exit with error message informing them -//! of the mistake, and what the possible valid values are -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/04_01_possible.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/04_01_possible.md")] -//! -//! When enabling the [`derive` feature][crate::_features], you can use -//! [`ValueEnum`][crate::ValueEnum] to take care of the boiler plate for you, giving the same -//! results. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/04_01_enum.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/04_01_enum.md")] -//! -//! ### Validated values -//! -//! More generally, you can validate and parse into any data type. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/04_02_parse.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/04_02_parse.md")] -//! -//! A custom parser can be used to improve the error messages or provide additional validation: -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/04_02_validate.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/04_02_validate.md")] -//! -//! ### Argument Relations -//! -//! You can declare dependencies or conflicts between [`Arg`][crate::Arg]s or even -//! [`ArgGroup`][crate::ArgGroup]s. -//! -//! [`ArgGroup`][crate::ArgGroup]s make it easier to declare relations instead of having to list -//! each individually, or when you want a rule to apply "any but not all" arguments. -//! -//! Perhaps the most common use of [`ArgGroup`][crate::ArgGroup]s is to require one and *only* one -//! argument to be present out of a given set. Imagine that you had multiple arguments, and you -//! want one of them to be required, but making all of them required isn't feasible because perhaps -//! they conflict with each other. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/04_03_relations.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/04_03_relations.md")] -//! -//! ### Custom Validation -//! -//! As a last resort, you can create custom errors with the basics of clap's formatting. -//! -//! ```rust -#![doc = include_str!("../examples/tutorial_builder/04_04_custom.rs")] -//! ``` -#![doc = include_str!("../examples/tutorial_builder/04_04_custom.md")] -//! -//! ## Testing -//! -//! clap reports most development errors as `debug_assert!`s. Rather than checking every -//! subcommand, you should have a test that calls -//! [`Command::debug_assert`][crate::App::debug_assert]: -//! ```rust,no_run -#![doc = include_str!("../examples/tutorial_builder/05_01_assert.rs")] -//! ``` diff --git a/vendor/clap/src/bin/stdio-fixture.rs b/vendor/clap/src/bin/stdio-fixture.rs deleted file mode 100644 index e3f34b41a..000000000 --- a/vendor/clap/src/bin/stdio-fixture.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - let cmd = clap::Command::new("stdio-fixture") - .version("1.0") - .long_version("1.0 - a2132c") - .arg_required_else_help(true) - .subcommand(clap::Command::new("more")) - .arg( - clap::Arg::new("verbose") - .long("verbose") - .help("log") - .long_help("more log"), - ); - cmd.get_matches(); -} diff --git a/vendor/clap/src/builder/action.rs b/vendor/clap/src/builder/action.rs deleted file mode 100644 index 71a91a8b1..000000000 --- a/vendor/clap/src/builder/action.rs +++ /dev/null @@ -1,325 +0,0 @@ -/// Behavior of arguments when they are encountered while parsing -/// -/// # Examples -/// -/// ```rust -/// # use clap::Command; -/// # use clap::Arg; -/// let cmd = Command::new("mycmd") -/// .arg( -/// Arg::new("special-help") -/// .short('?') -/// .action(clap::ArgAction::Help) -/// ); -/// -/// // Existing help still exists -/// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); -/// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); -/// -/// // New help available -/// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); -/// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); -/// ``` -#[derive(Clone, Debug)] -#[non_exhaustive] -#[allow(missing_copy_implementations)] // In the future, we may accept `Box` -pub enum ArgAction { - /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::Set) - /// ); - /// - /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_many::("flag").unwrap_or_default().map(|v| v.as_str()).collect::>(), - /// vec!["value"] - /// ); - /// ``` - Set, - /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::Append) - /// ); - /// - /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value1", "--flag", "value2"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_many::("flag").unwrap_or_default().map(|v| v.as_str()).collect::>(), - /// vec!["value1", "value2"] - /// ); - /// ``` - Append, - /// Deprecated, replaced with [`ArgAction::Set`] or [`ArgAction::Append`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `ArgAction::Set` or `ArgAction::Append`" - ) - )] - StoreValue, - /// Deprecated, replaced with [`ArgAction::SetTrue`] or [`ArgAction::Count`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `ArgAction::SetTrue` or `ArgAction::Count`" - ) - )] - IncOccurrence, - /// When encountered, act as if `"true"` was encountered on the command-line - /// - /// If no [`default_value`][super::Arg::default_value] is set, it will be `false`. - /// - /// No value is allowed. To optionally accept a value, see - /// [`Arg::default_missing_value`][super::Arg::default_missing_value] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::SetTrue) - /// ); - /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_one::("flag").copied(), - /// Some(true) - /// ); - /// - /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_one::("flag").copied(), - /// Some(false) - /// ); - /// ``` - SetTrue, - /// When encountered, act as if `"false"` was encountered on the command-line - /// - /// If no [`default_value`][super::Arg::default_value] is set, it will be `true`. - /// - /// No value is allowed. To optionally accept a value, see - /// [`Arg::default_missing_value`][super::Arg::default_missing_value] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::SetFalse) - /// ); - /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_one::("flag").copied(), - /// Some(false) - /// ); - /// - /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_one::("flag").copied(), - /// Some(true) - /// ); - /// ``` - SetFalse, - /// When encountered, increment a `u8` counter - /// - /// If no [`default_value`][super::Arg::default_value] is set, it will be `0`. - /// - /// No value is allowed. To optionally accept a value, see - /// [`Arg::default_missing_value`][super::Arg::default_missing_value] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::Count) - /// ); - /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_count("flag"), - /// 2 - /// ); - /// - /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_count("flag"), - /// 0 - /// ); - /// ``` - Count, - /// When encountered, display [`Command::print_help`][super::App::print_help] - /// - /// Depending on the flag, [`Command::print_long_help`][super::App::print_long_help] may be shown - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("special-help") - /// .short('?') - /// .action(clap::ArgAction::Help) - /// ); - /// - /// // Existing help still exists - /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); - /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); - /// - /// // New help available - /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); - /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); - /// ``` - Help, - /// When encountered, display [`Command::version`][super::App::version] - /// - /// Depending on the flag, [`Command::long_version`][super::App::long_version] may be shown - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .version("1.0.0") - /// .arg( - /// Arg::new("special-version") - /// .long("special-version") - /// .action(clap::ArgAction::Version) - /// ); - /// - /// // Existing help still exists - /// let err = cmd.clone().try_get_matches_from(["mycmd", "--version"]).unwrap_err(); - /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion); - /// - /// // New help available - /// let err = cmd.try_get_matches_from(["mycmd", "--special-version"]).unwrap_err(); - /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion); - /// ``` - Version, -} - -impl ArgAction { - /// Returns whether this action accepts values on the command-line - /// - /// [`default_values`][super::Arg::default_values] and [`env`][super::Arg::env] may still be - /// processed. - pub fn takes_values(&self) -> bool { - match self { - Self::Set => true, - Self::Append => true, - #[allow(deprecated)] - Self::StoreValue => true, - #[allow(deprecated)] - Self::IncOccurrence => false, - Self::SetTrue => false, - Self::SetFalse => false, - Self::Count => false, - Self::Help => false, - Self::Version => false, - } - } - - pub(crate) fn default_value(&self) -> Option<&'static std::ffi::OsStr> { - match self { - Self::Set => None, - Self::Append => None, - #[allow(deprecated)] - Self::StoreValue => None, - #[allow(deprecated)] - Self::IncOccurrence => None, - Self::SetTrue => Some(std::ffi::OsStr::new("false")), - Self::SetFalse => Some(std::ffi::OsStr::new("true")), - Self::Count => Some(std::ffi::OsStr::new("0")), - Self::Help => None, - Self::Version => None, - } - } - - pub(crate) fn default_value_parser(&self) -> Option { - match self { - Self::Set => None, - Self::Append => None, - #[allow(deprecated)] - Self::StoreValue => None, - #[allow(deprecated)] - Self::IncOccurrence => None, - Self::SetTrue => Some(super::ValueParser::bool()), - Self::SetFalse => Some(super::ValueParser::bool()), - Self::Count => Some(crate::value_parser!(u8).into()), - Self::Help => None, - Self::Version => None, - } - } - - #[cfg(debug_assertions)] - pub(crate) fn value_type_id(&self) -> Option { - use crate::parser::AnyValueId; - - match self { - Self::Set => None, - Self::Append => None, - #[allow(deprecated)] - Self::StoreValue => None, - #[allow(deprecated)] - Self::IncOccurrence => None, - Self::SetTrue => Some(AnyValueId::of::()), - Self::SetFalse => Some(AnyValueId::of::()), - Self::Count => Some(AnyValueId::of::()), - Self::Help => None, - Self::Version => None, - } - } -} - -pub(crate) type CountType = u8; diff --git a/vendor/clap/src/builder/app_settings.rs b/vendor/clap/src/builder/app_settings.rs deleted file mode 100644 index 88bc243c4..000000000 --- a/vendor/clap/src/builder/app_settings.rs +++ /dev/null @@ -1,864 +0,0 @@ -#![allow(deprecated)] - -// Std -use std::ops::BitOr; -#[cfg(feature = "yaml")] -use std::str::FromStr; - -#[allow(unused)] -use crate::Arg; -#[allow(unused)] -use crate::Command; - -// Third party -use bitflags::bitflags; - -#[doc(hidden)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct AppFlags(Flags); - -impl Default for AppFlags { - fn default() -> Self { - AppFlags(Flags::COLOR_AUTO) - } -} - -/// Application level settings, which affect how [`Command`] operates -/// -/// **NOTE:** When these settings are used, they apply only to current command, and are *not* -/// propagated down or up through child or parent subcommands -/// -/// [`Command`]: crate::Command -#[derive(Debug, PartialEq, Copy, Clone)] -#[non_exhaustive] -pub enum AppSettings { - /// Deprecated, replaced with [`Command::ignore_errors`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command::ignore_errors`") - )] - IgnoreErrors, - - /// Deprecated, replace - /// ```rust,no_run - /// let cmd = clap::Command::new("cmd") - /// .global_setting(clap::AppSettings::WaitOnError) - /// .arg(clap::arg!(--flag)); - /// let m = cmd.get_matches(); - /// ``` - /// with - /// ```rust - /// let cmd = clap::Command::new("cmd") - /// .arg(clap::arg!(--flag)); - /// let m = match cmd.try_get_matches() { - /// Ok(m) => m, - /// Err(err) => { - /// if err.use_stderr() { - /// let _ = err.print(); - /// - /// eprintln!("\nPress [ENTER] / [RETURN] to continue..."); - /// use std::io::BufRead; - /// let mut s = String::new(); - /// let i = std::io::stdin(); - /// i.lock().read_line(&mut s).unwrap(); - /// - /// std::process::exit(2); - /// } else { - /// let _ = err.print(); - /// std::process::exit(0); - /// } - /// } - /// }; - /// ``` - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "See documentation for how to hand-implement this" - ) - )] - WaitOnError, - - /// Deprecated, replaced with [`Command::allow_hyphen_values`] and - /// [`Arg::is_allow_hyphen_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`" - ) - )] - AllowHyphenValues, - - /// Deprecated, replaced with [`Command::allow_negative_numbers`] and - /// [`Command::is_allow_negative_numbers_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::allow_negative_numbers` and `Command::is_allow_negative_numbers_set`" - ) - )] - AllowNegativeNumbers, - - /// Deprecated, replaced with [`Command::args_override_self`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command::args_override_self`") - )] - AllArgsOverrideSelf, - - /// Deprecated, replaced with [`Command::allow_missing_positional`] and - /// [`Command::is_allow_missing_positional_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::allow_missing_positional` and `Command::is_allow_missing_positional_set`" - ) - )] - AllowMissingPositional, - - /// Deprecated, replaced with [`Command::trailing_var_arg`] and [`Command::is_trailing_var_arg_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::trailing_var_arg` and `Command::is_trailing_var_arg_set`" - ) - )] - TrailingVarArg, - - /// Deprecated, replaced with [`Command::dont_delimit_trailing_values`] and - /// [`Command::is_dont_delimit_trailing_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::dont_delimit_trailing_values` and `Command::is_dont_delimit_trailing_values_set`" - ) - )] - DontDelimitTrailingValues, - - /// Deprecated, replaced with [`Command::infer_long_args`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command::infer_long_args`") - )] - InferLongArgs, - - /// Deprecated, replaced with [`Command::infer_subcommands`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command::infer_subcommands`") - )] - InferSubcommands, - - /// Deprecated, replaced with [`Command::subcommand_required`] and - /// [`Command::is_subcommand_required_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::subcommand_required` and `Command::is_subcommand_required_set`" - ) - )] - SubcommandRequired, - - /// Deprecated, replaced with [`Command::subcommand_required`] combined with - /// [`Command::arg_required_else_help`]. - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::subcommand_required` combined with `Command::arg_required_else_help`" - ) - )] - SubcommandRequiredElseHelp, - - /// Deprecated, replaced with [`Command::allow_external_subcommands`] and - /// [`Command::is_allow_external_subcommands_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::allow_external_subcommands` and `Command::is_allow_external_subcommands_set`" - ) - )] - AllowExternalSubcommands, - - /// Deprecated, replaced with [`Command::multicall`] and [`Command::is_multicall_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::multicall` and `Command::is_multicall_set`" - ) - )] - Multicall, - - /// Deprecated, replaced with [`Command::allow_invalid_utf8_for_external_subcommands`] and [`Command::is_allow_invalid_utf8_for_external_subcommands_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::allow_invalid_utf8_for_external_subcommands` and `Command::is_allow_invalid_utf8_for_external_subcommands_set`" - ) - )] - AllowInvalidUtf8ForExternalSubcommands, - - /// Deprecated, this is now the default - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "This is now the default") - )] - UseLongFormatForHelpSubcommand, - - /// Deprecated, replaced with [`Command::subcommand_negates_reqs`] and - /// [`Command::is_subcommand_negates_reqs_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::subcommand_negates_reqs` and `Command::is_subcommand_negates_reqs_set`" - ) - )] - SubcommandsNegateReqs, - - /// Deprecated, replaced with [`Command::args_conflicts_with_subcommands`] and - /// [`Command::is_args_conflicts_with_subcommands_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::args_conflicts_with_subcommands` and `Command::is_args_conflicts_with_subcommands_set`" - ) - )] - ArgsNegateSubcommands, - - /// Deprecated, replaced with [`Command::subcommand_precedence_over_arg`] and - /// [`Command::is_subcommand_precedence_over_arg_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::subcommand_precedence_over_arg` and `Command::is_subcommand_precedence_over_arg_set`" - ) - )] - SubcommandPrecedenceOverArg, - - /// Deprecated, replaced with [`Command::arg_required_else_help`] and - /// [`Command::is_arg_required_else_help_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::arg_required_else_help` and `Command::is_arg_required_else_help_set`" - ) - )] - ArgRequiredElseHelp, - - /// Displays the arguments and [`subcommands`] in the help message in the order that they were - /// declared in, and not alphabetically which is the default. - /// - /// To override the declaration order, see [`Arg::display_order`] and [`Command::display_order`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, AppSettings}; - /// Command::new("myprog") - /// .global_setting(AppSettings::DeriveDisplayOrder) - /// .get_matches(); - /// ``` - /// - /// [`subcommands`]: crate::Command::subcommand() - /// [`Arg::display_order`]: crate::Arg::display_order - /// [`Command::display_order`]: crate::Command::display_order - DeriveDisplayOrder, - - /// Deprecated, replaced with [`Command::dont_collapse_args_in_usage`] and - /// [`Command::is_dont_collapse_args_in_usage_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::dont_collapse_args_in_usage` and `Command::is_dont_collapse_args_in_usage_set`" - ) - )] - DontCollapseArgsInUsage, - - /// Deprecated, replaced with [`Command::next_line_help`] and [`Command::is_next_line_help_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::next_line_help` and `Command::is_next_line_help_set`" - ) - )] - NextLineHelp, - - /// Deprecated, replaced with [`Command::disable_colored_help`] and - /// [`Command::is_disable_colored_help_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::disable_colored_help` and `Command::is_disable_colored_help_set`" - ) - )] - DisableColoredHelp, - - /// Deprecated, replaced with [`Command::disable_help_flag`] and [`Command::is_disable_help_flag_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::disable_help_flag` and `Command::is_disable_help_flag_set`" - ) - )] - DisableHelpFlag, - - /// Deprecated, replaced with [`Command::disable_help_subcommand`] and - /// [`Command::is_disable_help_subcommand_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::disable_help_subcommand` and `Command::is_disable_help_subcommand_set`" - ) - )] - DisableHelpSubcommand, - - /// Deprecated, replaced with [`Command::disable_version_flag`] and - /// [`Command::is_disable_version_flag_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::disable_version_flag` and `Command::is_disable_version_flag_set`" - ) - )] - DisableVersionFlag, - - /// Deprecated, replaced with [`Command::propagate_version`] and [`Command::is_propagate_version_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::propagate_version` and `Command::is_propagate_version_set`" - ) - )] - PropagateVersion, - - /// Deprecated, replaced with [`Command::hide`] and [`Command::is_hide_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::hide` and `Command::is_hide_set`" - ) - )] - Hidden, - - /// Deprecated, replaced with [`Command::hide_possible_values`] and - /// [`Arg::is_hide_possible_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Command::hide_possible_values` and `Arg::is_hide_possible_values_set`" - ) - )] - HidePossibleValues, - - /// Deprecated, replaced with [`Command::help_expected`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command::help_expected`") - )] - HelpExpected, - - /// Deprecated, replaced with [`Command::no_binary_name`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command::no_binary_name`") - )] - NoBinaryName, - - /// Deprecated, replaced with [`Arg::action`][super::Arg::action] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::action`") - )] - NoAutoHelp, - - /// Deprecated, replaced with [`Arg::action`][super::Arg::action] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::action`") - )] - NoAutoVersion, - - /// Deprecated, replaced with [`Command::allow_hyphen_values`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Command::allow_hyphen_values`") - )] - #[doc(hidden)] - AllowLeadingHyphen, - - /// Deprecated, replaced with [`Command::allow_invalid_utf8_for_external_subcommands`] and [`Command::is_allow_invalid_utf8_for_external_subcommands_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Command::allow_invalid_utf8_for_external_subcommands` and `Command::is_allow_invalid_utf8_for_external_subcommands_set`" - ) - )] - #[doc(hidden)] - StrictUtf8, - - /// Deprecated, this is now the default - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "This is now the default") - )] - #[doc(hidden)] - UnifiedHelpMessage, - - /// Deprecated, this is now the default - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "This is now the default") - )] - #[doc(hidden)] - ColoredHelp, - - /// Deprecated, see [`Command::color`][crate::Command::color] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Command::color`") - )] - #[doc(hidden)] - ColorAuto, - - /// Deprecated, replaced with [`Command::color`][crate::Command::color] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Command::color`") - )] - #[doc(hidden)] - ColorAlways, - - /// Deprecated, replaced with [`Command::color`][crate::Command::color] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Command::color`") - )] - #[doc(hidden)] - ColorNever, - - /// Deprecated, replaced with [`Command::disable_help_flag`] and [`Command::is_disable_help_flag_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Command::disable_help_flag` and `Command::is_disable_help_flag_set`" - ) - )] - #[doc(hidden)] - DisableHelpFlags, - - /// Deprecated, replaced with [`Command::disable_version_flag`] and - /// [`Command::is_disable_version_flag_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Command::disable_version_flag` and `Command::is_disable_version_flag_set`" - ) - )] - #[doc(hidden)] - DisableVersion, - - /// Deprecated, replaced with [`Command::propagate_version`] and [`Command::is_propagate_version_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Command::propagate_version` and `Command::is_propagate_version_set`" - ) - )] - #[doc(hidden)] - GlobalVersion, - - /// Deprecated, replaced with [`Command::hide_possible_values`] and - /// [`Arg::is_hide_possible_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Command::hide_possible_values` and `Arg::is_hide_possible_values_set`" - ) - )] - #[doc(hidden)] - HidePossibleValuesInHelp, - - /// Deprecated, this is now the default - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "This is now the default") - )] - #[doc(hidden)] - UnifiedHelp, - - /// If the cmd is already built, used for caching. - #[doc(hidden)] - Built, - - /// If the cmd's bin name is already built, used for caching. - #[doc(hidden)] - BinNameBuilt, -} - -bitflags! { - struct Flags: u64 { - const SC_NEGATE_REQS = 1; - const SC_REQUIRED = 1 << 1; - const ARG_REQUIRED_ELSE_HELP = 1 << 2; - const PROPAGATE_VERSION = 1 << 3; - const DISABLE_VERSION_FOR_SC = 1 << 4; - const WAIT_ON_ERROR = 1 << 6; - const SC_REQUIRED_ELSE_HELP = 1 << 7; - const NO_AUTO_HELP = 1 << 8; - const NO_AUTO_VERSION = 1 << 9; - const DISABLE_VERSION_FLAG = 1 << 10; - const HIDDEN = 1 << 11; - const TRAILING_VARARG = 1 << 12; - const NO_BIN_NAME = 1 << 13; - const ALLOW_UNK_SC = 1 << 14; - const SC_UTF8_NONE = 1 << 15; - const LEADING_HYPHEN = 1 << 16; - const NO_POS_VALUES = 1 << 17; - const NEXT_LINE_HELP = 1 << 18; - const DERIVE_DISP_ORDER = 1 << 19; - const DISABLE_COLORED_HELP = 1 << 20; - const COLOR_ALWAYS = 1 << 21; - const COLOR_AUTO = 1 << 22; - const COLOR_NEVER = 1 << 23; - const DONT_DELIM_TRAIL = 1 << 24; - const ALLOW_NEG_NUMS = 1 << 25; - const DISABLE_HELP_SC = 1 << 27; - const DONT_COLLAPSE_ARGS = 1 << 28; - const ARGS_NEGATE_SCS = 1 << 29; - const PROPAGATE_VALS_DOWN = 1 << 30; - const ALLOW_MISSING_POS = 1 << 31; - const TRAILING_VALUES = 1 << 32; - const BUILT = 1 << 33; - const BIN_NAME_BUILT = 1 << 34; - const VALID_ARG_FOUND = 1 << 35; - const INFER_SUBCOMMANDS = 1 << 36; - const CONTAINS_LAST = 1 << 37; - const ARGS_OVERRIDE_SELF = 1 << 38; - const HELP_REQUIRED = 1 << 39; - const SUBCOMMAND_PRECEDENCE_OVER_ARG = 1 << 40; - const DISABLE_HELP_FLAG = 1 << 41; - const USE_LONG_FORMAT_FOR_HELP_SC = 1 << 42; - const INFER_LONG_ARGS = 1 << 43; - const IGNORE_ERRORS = 1 << 44; - const MULTICALL = 1 << 45; - const NO_OP = 0; - } -} - -impl_settings! { AppSettings, AppFlags, - ArgRequiredElseHelp - => Flags::ARG_REQUIRED_ELSE_HELP, - SubcommandPrecedenceOverArg - => Flags::SUBCOMMAND_PRECEDENCE_OVER_ARG, - ArgsNegateSubcommands - => Flags::ARGS_NEGATE_SCS, - AllowExternalSubcommands - => Flags::ALLOW_UNK_SC, - StrictUtf8 - => Flags::NO_OP, - AllowInvalidUtf8ForExternalSubcommands - => Flags::SC_UTF8_NONE, - AllowHyphenValues - => Flags::LEADING_HYPHEN, - AllowLeadingHyphen - => Flags::LEADING_HYPHEN, - AllowNegativeNumbers - => Flags::ALLOW_NEG_NUMS, - AllowMissingPositional - => Flags::ALLOW_MISSING_POS, - UnifiedHelpMessage - => Flags::NO_OP, - ColoredHelp - => Flags::NO_OP, - ColorAlways - => Flags::COLOR_ALWAYS, - ColorAuto - => Flags::COLOR_AUTO, - ColorNever - => Flags::COLOR_NEVER, - DontDelimitTrailingValues - => Flags::DONT_DELIM_TRAIL, - DontCollapseArgsInUsage - => Flags::DONT_COLLAPSE_ARGS, - DeriveDisplayOrder - => Flags::DERIVE_DISP_ORDER, - DisableColoredHelp - => Flags::DISABLE_COLORED_HELP, - DisableHelpSubcommand - => Flags::DISABLE_HELP_SC, - DisableHelpFlag - => Flags::DISABLE_HELP_FLAG, - DisableHelpFlags - => Flags::DISABLE_HELP_FLAG, - DisableVersionFlag - => Flags::DISABLE_VERSION_FLAG, - DisableVersion - => Flags::DISABLE_VERSION_FLAG, - PropagateVersion - => Flags::PROPAGATE_VERSION, - GlobalVersion - => Flags::PROPAGATE_VERSION, - HidePossibleValues - => Flags::NO_POS_VALUES, - HidePossibleValuesInHelp - => Flags::NO_POS_VALUES, - HelpExpected - => Flags::HELP_REQUIRED, - Hidden - => Flags::HIDDEN, - Multicall - => Flags::MULTICALL, - NoAutoHelp - => Flags::NO_AUTO_HELP, - NoAutoVersion - => Flags::NO_AUTO_VERSION, - NoBinaryName - => Flags::NO_BIN_NAME, - SubcommandsNegateReqs - => Flags::SC_NEGATE_REQS, - SubcommandRequired - => Flags::SC_REQUIRED, - SubcommandRequiredElseHelp - => Flags::SC_REQUIRED_ELSE_HELP, - UseLongFormatForHelpSubcommand - => Flags::USE_LONG_FORMAT_FOR_HELP_SC, - TrailingVarArg - => Flags::TRAILING_VARARG, - UnifiedHelp => Flags::NO_OP, - NextLineHelp - => Flags::NEXT_LINE_HELP, - IgnoreErrors - => Flags::IGNORE_ERRORS, - WaitOnError - => Flags::WAIT_ON_ERROR, - Built - => Flags::BUILT, - BinNameBuilt - => Flags::BIN_NAME_BUILT, - InferSubcommands - => Flags::INFER_SUBCOMMANDS, - AllArgsOverrideSelf - => Flags::ARGS_OVERRIDE_SELF, - InferLongArgs - => Flags::INFER_LONG_ARGS -} - -/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? -#[cfg(feature = "yaml")] -impl FromStr for AppSettings { - type Err = String; - fn from_str(s: &str) -> Result::Err> { - #[allow(deprecated)] - #[allow(unreachable_patterns)] - match &*s.to_ascii_lowercase() { - "argrequiredelsehelp" => Ok(AppSettings::ArgRequiredElseHelp), - "subcommandprecedenceoverarg" => Ok(AppSettings::SubcommandPrecedenceOverArg), - "argsnegatesubcommands" => Ok(AppSettings::ArgsNegateSubcommands), - "allowexternalsubcommands" => Ok(AppSettings::AllowExternalSubcommands), - "strictutf8" => Ok(AppSettings::StrictUtf8), - "allowinvalidutf8forexternalsubcommands" => { - Ok(AppSettings::AllowInvalidUtf8ForExternalSubcommands) - } - "allowhyphenvalues" => Ok(AppSettings::AllowHyphenValues), - "allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen), - "allownegativenumbers" => Ok(AppSettings::AllowNegativeNumbers), - "allowmissingpositional" => Ok(AppSettings::AllowMissingPositional), - "unifiedhelpmessage" => Ok(AppSettings::UnifiedHelpMessage), - "coloredhelp" => Ok(AppSettings::ColoredHelp), - "coloralways" => Ok(AppSettings::ColorAlways), - "colorauto" => Ok(AppSettings::ColorAuto), - "colornever" => Ok(AppSettings::ColorNever), - "dontdelimittrailingvalues" => Ok(AppSettings::DontDelimitTrailingValues), - "dontcollapseargsinusage" => Ok(AppSettings::DontCollapseArgsInUsage), - "derivedisplayorder" => Ok(AppSettings::DeriveDisplayOrder), - "disablecoloredhelp" => Ok(AppSettings::DisableColoredHelp), - "disablehelpsubcommand" => Ok(AppSettings::DisableHelpSubcommand), - "disablehelpflag" => Ok(AppSettings::DisableHelpFlag), - "disablehelpflags" => Ok(AppSettings::DisableHelpFlags), - "disableversionflag" => Ok(AppSettings::DisableVersionFlag), - "disableversion" => Ok(AppSettings::DisableVersion), - "propagateversion" => Ok(AppSettings::PropagateVersion), - "propagateversion" => Ok(AppSettings::GlobalVersion), - "hidepossiblevalues" => Ok(AppSettings::HidePossibleValues), - "hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp), - "helpexpected" => Ok(AppSettings::HelpExpected), - "hidden" => Ok(AppSettings::Hidden), - "noautohelp" => Ok(AppSettings::NoAutoHelp), - "noautoversion" => Ok(AppSettings::NoAutoVersion), - "nobinaryname" => Ok(AppSettings::NoBinaryName), - "subcommandsnegatereqs" => Ok(AppSettings::SubcommandsNegateReqs), - "subcommandrequired" => Ok(AppSettings::SubcommandRequired), - "subcommandrequiredelsehelp" => Ok(AppSettings::SubcommandRequiredElseHelp), - "uselongformatforhelpsubcommand" => Ok(AppSettings::UseLongFormatForHelpSubcommand), - "trailingvararg" => Ok(AppSettings::TrailingVarArg), - "unifiedhelp" => Ok(AppSettings::UnifiedHelp), - "nextlinehelp" => Ok(AppSettings::NextLineHelp), - "ignoreerrors" => Ok(AppSettings::IgnoreErrors), - "waitonerror" => Ok(AppSettings::WaitOnError), - "built" => Ok(AppSettings::Built), - "binnamebuilt" => Ok(AppSettings::BinNameBuilt), - "infersubcommands" => Ok(AppSettings::InferSubcommands), - "allargsoverrideself" => Ok(AppSettings::AllArgsOverrideSelf), - "inferlongargs" => Ok(AppSettings::InferLongArgs), - _ => Err(format!("unknown AppSetting: `{}`", s)), - } - } -} - -#[cfg(test)] -mod test { - #[allow(clippy::cognitive_complexity)] - #[test] - #[cfg(feature = "yaml")] - fn app_settings_fromstr() { - use super::AppSettings; - - assert_eq!( - "disablehelpflag".parse::().unwrap(), - AppSettings::DisableHelpFlag - ); - assert_eq!( - "argsnegatesubcommands".parse::().unwrap(), - AppSettings::ArgsNegateSubcommands - ); - assert_eq!( - "argrequiredelsehelp".parse::().unwrap(), - AppSettings::ArgRequiredElseHelp - ); - assert_eq!( - "subcommandprecedenceoverarg" - .parse::() - .unwrap(), - AppSettings::SubcommandPrecedenceOverArg - ); - assert_eq!( - "allowexternalsubcommands".parse::().unwrap(), - AppSettings::AllowExternalSubcommands - ); - assert_eq!( - "allowinvalidutf8forexternalsubcommands" - .parse::() - .unwrap(), - AppSettings::AllowInvalidUtf8ForExternalSubcommands - ); - assert_eq!( - "allowhyphenvalues".parse::().unwrap(), - AppSettings::AllowHyphenValues - ); - assert_eq!( - "allownegativenumbers".parse::().unwrap(), - AppSettings::AllowNegativeNumbers - ); - assert_eq!( - "disablehelpsubcommand".parse::().unwrap(), - AppSettings::DisableHelpSubcommand - ); - assert_eq!( - "disableversionflag".parse::().unwrap(), - AppSettings::DisableVersionFlag - ); - assert_eq!( - "dontcollapseargsinusage".parse::().unwrap(), - AppSettings::DontCollapseArgsInUsage - ); - assert_eq!( - "dontdelimittrailingvalues".parse::().unwrap(), - AppSettings::DontDelimitTrailingValues - ); - assert_eq!( - "derivedisplayorder".parse::().unwrap(), - AppSettings::DeriveDisplayOrder - ); - assert_eq!( - "disablecoloredhelp".parse::().unwrap(), - AppSettings::DisableColoredHelp - ); - assert_eq!( - "propagateversion".parse::().unwrap(), - AppSettings::PropagateVersion - ); - assert_eq!( - "hidden".parse::().unwrap(), - AppSettings::Hidden - ); - assert_eq!( - "hidepossiblevalues".parse::().unwrap(), - AppSettings::HidePossibleValues - ); - assert_eq!( - "helpexpected".parse::().unwrap(), - AppSettings::HelpExpected - ); - assert_eq!( - "nobinaryname".parse::().unwrap(), - AppSettings::NoBinaryName - ); - assert_eq!( - "nextlinehelp".parse::().unwrap(), - AppSettings::NextLineHelp - ); - assert_eq!( - "subcommandsnegatereqs".parse::().unwrap(), - AppSettings::SubcommandsNegateReqs - ); - assert_eq!( - "subcommandrequired".parse::().unwrap(), - AppSettings::SubcommandRequired - ); - assert_eq!( - "subcommandrequiredelsehelp".parse::().unwrap(), - AppSettings::SubcommandRequiredElseHelp - ); - assert_eq!( - "uselongformatforhelpsubcommand" - .parse::() - .unwrap(), - AppSettings::UseLongFormatForHelpSubcommand - ); - assert_eq!( - "trailingvararg".parse::().unwrap(), - AppSettings::TrailingVarArg - ); - assert_eq!( - "waitonerror".parse::().unwrap(), - AppSettings::WaitOnError - ); - assert_eq!("built".parse::().unwrap(), AppSettings::Built); - assert_eq!( - "binnamebuilt".parse::().unwrap(), - AppSettings::BinNameBuilt - ); - assert_eq!( - "infersubcommands".parse::().unwrap(), - AppSettings::InferSubcommands - ); - assert!("hahahaha".parse::().is_err()); - } -} diff --git a/vendor/clap/src/builder/arg.rs b/vendor/clap/src/builder/arg.rs deleted file mode 100644 index e9403d0b7..000000000 --- a/vendor/clap/src/builder/arg.rs +++ /dev/null @@ -1,5494 +0,0 @@ -#![allow(deprecated)] - -// Std -use std::{ - borrow::Cow, - cmp::{Ord, Ordering}, - error::Error, - ffi::OsStr, - fmt::{self, Display, Formatter}, - str, - sync::{Arc, Mutex}, -}; -#[cfg(feature = "env")] -use std::{env, ffi::OsString}; - -#[cfg(feature = "yaml")] -use yaml_rust::Yaml; - -// Internal -use crate::builder::usage_parser::UsageParser; -use crate::builder::ArgPredicate; -use crate::util::{Id, Key}; -use crate::ArgAction; -use crate::PossibleValue; -use crate::ValueHint; -use crate::INTERNAL_ERROR_MSG; -use crate::{ArgFlags, ArgSettings}; - -#[cfg(feature = "regex")] -use crate::builder::RegexRef; - -/// The abstract representation of a command line argument. Used to set all the options and -/// relationships that define a valid argument for the program. -/// -/// There are two methods for constructing [`Arg`]s, using the builder pattern and setting options -/// manually, or using a usage string which is far less verbose but has fewer options. You can also -/// use a combination of the two methods to achieve the best of both worlds. -/// -/// - [Basic API][crate::Arg#basic-api] -/// - [Value Handling][crate::Arg#value-handling] -/// - [Help][crate::Arg#help-1] -/// - [Advanced Argument Relations][crate::Arg#advanced-argument-relations] -/// - [Reflection][crate::Arg#reflection] -/// -/// # Examples -/// -/// ```rust -/// # use clap::{Arg, arg}; -/// // Using the traditional builder pattern and setting each option manually -/// let cfg = Arg::new("config") -/// .short('c') -/// .long("config") -/// .takes_value(true) -/// .value_name("FILE") -/// .help("Provides a config file to myprog"); -/// // Using a usage string (setting a similar argument to the one above) -/// let input = arg!(-i --input "Provides an input file to the program"); -/// ``` -#[allow(missing_debug_implementations)] -#[derive(Default, Clone)] -pub struct Arg<'help> { - pub(crate) id: Id, - pub(crate) provider: ArgProvider, - pub(crate) name: &'help str, - pub(crate) help: Option<&'help str>, - pub(crate) long_help: Option<&'help str>, - pub(crate) action: Option, - pub(crate) value_parser: Option, - pub(crate) blacklist: Vec, - pub(crate) settings: ArgFlags, - pub(crate) overrides: Vec, - pub(crate) groups: Vec, - pub(crate) requires: Vec<(ArgPredicate<'help>, Id)>, - pub(crate) r_ifs: Vec<(Id, &'help str)>, - pub(crate) r_ifs_all: Vec<(Id, &'help str)>, - pub(crate) r_unless: Vec, - pub(crate) r_unless_all: Vec, - pub(crate) short: Option, - pub(crate) long: Option<&'help str>, - pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible) - pub(crate) short_aliases: Vec<(char, bool)>, // (name, visible) - pub(crate) disp_ord: DisplayOrder, - pub(crate) possible_vals: Vec>, - pub(crate) val_names: Vec<&'help str>, - pub(crate) num_vals: Option, - pub(crate) max_occurs: Option, - pub(crate) max_vals: Option, - pub(crate) min_vals: Option, - pub(crate) validator: Option>>>, - pub(crate) validator_os: Option>>>, - pub(crate) val_delim: Option, - pub(crate) default_vals: Vec<&'help OsStr>, - pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate<'help>, Option<&'help OsStr>)>, - pub(crate) default_missing_vals: Vec<&'help OsStr>, - #[cfg(feature = "env")] - pub(crate) env: Option<(&'help OsStr, Option)>, - pub(crate) terminator: Option<&'help str>, - pub(crate) index: Option, - pub(crate) help_heading: Option>, - pub(crate) value_hint: Option, -} - -/// # Basic API -impl<'help> Arg<'help> { - /// Create a new [`Arg`] with a unique name. - /// - /// The name is used to check whether or not the argument was used at - /// runtime, get values, set relationships with other args, etc.. - /// - /// **NOTE:** In the case of arguments that take values (i.e. [`Arg::takes_value(true)`]) - /// and positional arguments (i.e. those without a preceding `-` or `--`) the name will also - /// be displayed when the user prints the usage/help information of the program. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("config") - /// # ; - /// ``` - /// [`Arg::takes_value(true)`]: Arg::takes_value() - pub fn new>(n: S) -> Self { - Arg::default().name(n) - } - - /// Set the identifier used for referencing this argument in the clap API. - /// - /// See [`Arg::new`] for more details. - #[must_use] - pub fn id>(mut self, n: S) -> Self { - let name = n.into(); - self.id = Id::from(&*name); - self.name = name; - self - } - - /// Deprecated, replaced with [`Arg::id`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Arg::id`") - )] - pub fn name>(self, n: S) -> Self { - self.id(n) - } - - /// Sets the short version of the argument without the preceding `-`. - /// - /// By default `V` and `h` are used by the auto-generated `version` and `help` arguments, - /// respectively. You may use the uppercase `V` or lowercase `h` for your own arguments, in - /// which case `clap` simply will not assign those to the auto-generated - /// `version` or `help` arguments. - /// - /// # Examples - /// - /// When calling `short`, use a single valid UTF-8 character which will allow using the - /// argument via a single hyphen (`-`) such as `-c`: - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("config") - /// .short('c') - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "-c", "file.toml" - /// ]); - /// - /// assert_eq!(m.get_one::("config").map(String::as_str), Some("file.toml")); - /// ``` - #[inline] - #[must_use] - pub fn short(mut self, s: char) -> Self { - assert!(s != '-', "short option name cannot be `-`"); - - self.short = Some(s); - self - } - - /// Sets the long version of the argument without the preceding `--`. - /// - /// By default `version` and `help` are used by the auto-generated `version` and `help` - /// arguments, respectively. You may use the word `version` or `help` for the long form of your - /// own arguments, in which case `clap` simply will not assign those to the auto-generated - /// `version` or `help` arguments. - /// - /// **NOTE:** Any leading `-` characters will be stripped - /// - /// # Examples - /// - /// To set `long` use a word containing valid UTF-8. If you supply a double leading - /// `--` such as `--config` they will be stripped. Hyphens in the middle of the word, however, - /// will *not* be stripped (i.e. `config-file` is allowed). - /// - /// Setting `long` allows using the argument via a double hyphen (`--`) such as `--config` - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--config", "file.toml" - /// ]); - /// - /// assert_eq!(m.get_one::("cfg").map(String::as_str), Some("file.toml")); - /// ``` - #[inline] - #[must_use] - pub fn long(mut self, l: &'help str) -> Self { - #[cfg(feature = "unstable-v4")] - { - self.long = Some(l); - } - #[cfg(not(feature = "unstable-v4"))] - { - self.long = Some(l.trim_start_matches(|c| c == '-')); - } - self - } - - /// Add an alias, which functions as a hidden long flag. - /// - /// This is more efficient, and easier than creating multiple hidden arguments as one only - /// needs to check for the existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .long("test") - /// .alias("alias") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--alias", "cool" - /// ]); - /// assert!(m.contains_id("test")); - /// assert_eq!(m.value_of("test"), Some("cool")); - /// ``` - #[must_use] - pub fn alias>(mut self, name: S) -> Self { - self.aliases.push((name.into(), false)); - self - } - - /// Add an alias, which functions as a hidden short flag. - /// - /// This is more efficient, and easier than creating multiple hidden arguments as one only - /// needs to check for the existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .short('t') - /// .short_alias('e') - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "-e", "cool" - /// ]); - /// assert!(m.contains_id("test")); - /// assert_eq!(m.value_of("test"), Some("cool")); - /// ``` - #[must_use] - pub fn short_alias(mut self, name: char) -> Self { - assert!(name != '-', "short alias name cannot be `-`"); - - self.short_aliases.push((name, false)); - self - } - - /// Add aliases, which function as hidden long flags. - /// - /// This is more efficient, and easier than creating multiple hidden subcommands as one only - /// needs to check for the existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .long("test") - /// .aliases(&["do-stuff", "do-tests", "tests"]) - /// .action(ArgAction::SetTrue) - /// .help("the file to add") - /// .required(false)) - /// .get_matches_from(vec![ - /// "prog", "--do-tests" - /// ]); - /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); - /// ``` - #[must_use] - pub fn aliases(mut self, names: &[&'help str]) -> Self { - self.aliases.extend(names.iter().map(|&x| (x, false))); - self - } - - /// Add aliases, which functions as a hidden short flag. - /// - /// This is more efficient, and easier than creating multiple hidden subcommands as one only - /// needs to check for the existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .short('t') - /// .short_aliases(&['e', 's']) - /// .action(ArgAction::SetTrue) - /// .help("the file to add") - /// .required(false)) - /// .get_matches_from(vec![ - /// "prog", "-s" - /// ]); - /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); - /// ``` - #[must_use] - pub fn short_aliases(mut self, names: &[char]) -> Self { - for s in names { - assert!(s != &'-', "short alias name cannot be `-`"); - self.short_aliases.push((*s, false)); - } - self - } - - /// Add an alias, which functions as a visible long flag. - /// - /// Like [`Arg::alias`], except that they are visible inside the help message. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .visible_alias("something-awesome") - /// .long("test") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--something-awesome", "coffee" - /// ]); - /// assert!(m.contains_id("test")); - /// assert_eq!(m.value_of("test"), Some("coffee")); - /// ``` - /// [`Command::alias`]: Arg::alias() - #[must_use] - pub fn visible_alias>(mut self, name: S) -> Self { - self.aliases.push((name.into(), true)); - self - } - - /// Add an alias, which functions as a visible short flag. - /// - /// Like [`Arg::short_alias`], except that they are visible inside the help message. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .long("test") - /// .visible_short_alias('t') - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "-t", "coffee" - /// ]); - /// assert!(m.contains_id("test")); - /// assert_eq!(m.value_of("test"), Some("coffee")); - /// ``` - #[must_use] - pub fn visible_short_alias(mut self, name: char) -> Self { - assert!(name != '-', "short alias name cannot be `-`"); - - self.short_aliases.push((name, true)); - self - } - - /// Add aliases, which function as visible long flags. - /// - /// Like [`Arg::aliases`], except that they are visible inside the help message. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .long("test") - /// .action(ArgAction::SetTrue) - /// .visible_aliases(&["something", "awesome", "cool"])) - /// .get_matches_from(vec![ - /// "prog", "--awesome" - /// ]); - /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); - /// ``` - /// [`Command::aliases`]: Arg::aliases() - #[must_use] - pub fn visible_aliases(mut self, names: &[&'help str]) -> Self { - self.aliases.extend(names.iter().map(|n| (*n, true))); - self - } - - /// Add aliases, which function as visible short flags. - /// - /// Like [`Arg::short_aliases`], except that they are visible inside the help message. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("prog") - /// .arg(Arg::new("test") - /// .long("test") - /// .action(ArgAction::SetTrue) - /// .visible_short_aliases(&['t', 'e'])) - /// .get_matches_from(vec![ - /// "prog", "-t" - /// ]); - /// assert_eq!(*m.get_one::("test").expect("defaulted by clap"), true); - /// ``` - #[must_use] - pub fn visible_short_aliases(mut self, names: &[char]) -> Self { - for n in names { - assert!(n != &'-', "short alias name cannot be `-`"); - self.short_aliases.push((*n, true)); - } - self - } - - /// Specifies the index of a positional argument **starting at** 1. - /// - /// **NOTE:** The index refers to position according to **other positional argument**. It does - /// not define position in the argument list as a whole. - /// - /// **NOTE:** You can optionally leave off the `index` method, and the index will be - /// assigned in order of evaluation. Utilizing the `index` method allows for setting - /// indexes out of order - /// - /// **NOTE:** This is only meant to be used for positional arguments and shouldn't to be used - /// with [`Arg::short`] or [`Arg::long`]. - /// - /// **NOTE:** When utilized with [`Arg::multiple_values(true)`], only the **last** positional argument - /// may be defined as multiple (i.e. with the highest index) - /// - /// # Panics - /// - /// [`Command`] will [`panic!`] if indexes are skipped (such as defining `index(1)` and `index(3)` - /// but not `index(2)`, or a positional argument is defined as multiple and is not the highest - /// index - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("config") - /// .index(1) - /// # ; - /// ``` - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("mode") - /// .index(1)) - /// .arg(Arg::new("debug") - /// .long("debug")) - /// .get_matches_from(vec![ - /// "prog", "--debug", "fast" - /// ]); - /// - /// assert!(m.contains_id("mode")); - /// assert_eq!(m.value_of("mode"), Some("fast")); // notice index(1) means "first positional" - /// // *not* first argument - /// ``` - /// [`Arg::short`]: Arg::short() - /// [`Arg::long`]: Arg::long() - /// [`Arg::multiple_values(true)`]: Arg::multiple_values() - /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html - /// [`Command`]: crate::Command - #[inline] - #[must_use] - pub fn index(mut self, idx: usize) -> Self { - self.index = Some(idx); - self - } - - /// This arg is the last, or final, positional argument (i.e. has the highest - /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args -- - /// last_arg`). - /// - /// Even, if no other arguments are left to parse, if the user omits the `--` syntax - /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also - /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with - /// the `--` syntax is otherwise not possible. - /// - /// **NOTE:** This will change the usage string to look like `$ prog [OPTIONS] [-- ]` if - /// `ARG` is marked as `.last(true)`. - /// - /// **NOTE:** This setting will imply [`crate::Command::dont_collapse_args_in_usage`] because failing - /// to set this can make the usage string very confusing. - /// - /// **NOTE**: This setting only applies to positional arguments, and has no effect on OPTIONS - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`] - /// - /// **CAUTION:** Using this setting *and* having child subcommands is not - /// recommended with the exception of *also* using - /// [`crate::Command::args_conflicts_with_subcommands`] - /// (or [`crate::Command::subcommand_negates_reqs`] if the argument marked `Last` is also - /// marked [`Arg::required`]) - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("args") - /// .takes_value(true) - /// .last(true) - /// # ; - /// ``` - /// - /// Setting `last` ensures the arg has the highest [index] of all positional args - /// and requires that the `--` syntax be used to access it early. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("first")) - /// .arg(Arg::new("second")) - /// .arg(Arg::new("third") - /// .takes_value(true) - /// .last(true)) - /// .try_get_matches_from(vec![ - /// "prog", "one", "--", "three" - /// ]); - /// - /// assert!(res.is_ok()); - /// let m = res.unwrap(); - /// assert_eq!(m.value_of("third"), Some("three")); - /// assert!(m.value_of("second").is_none()); - /// ``` - /// - /// Even if the positional argument marked `Last` is the only argument left to parse, - /// failing to use the `--` syntax results in an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("first")) - /// .arg(Arg::new("second")) - /// .arg(Arg::new("third") - /// .takes_value(true) - /// .last(true)) - /// .try_get_matches_from(vec![ - /// "prog", "one", "two", "three" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - /// [index]: Arg::index() - /// [`UnknownArgument`]: crate::ErrorKind::UnknownArgument - #[inline] - #[must_use] - pub fn last(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::Last) - } else { - self.unset_setting(ArgSettings::Last) - } - } - - /// Specifies that the argument must be present. - /// - /// Required by default means it is required, when no other conflicting rules or overrides have - /// been evaluated. Conflicting rules take precedence over being required. - /// - /// **Pro tip:** Flags (i.e. not positional, or arguments that take values) shouldn't be - /// required by default. This is because if a flag were to be required, it should simply be - /// implied. No additional information is required from user. Flags by their very nature are - /// simply boolean on/off switches. The only time a user *should* be required to use a flag - /// is if the operation is destructive in nature, and the user is essentially proving to you, - /// "Yes, I know what I'm doing." - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required(true) - /// # ; - /// ``` - /// - /// Setting required requires that the argument be used at runtime. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required(true) - /// .takes_value(true) - /// .long("config")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "file.conf", - /// ]); - /// - /// assert!(res.is_ok()); - /// ``` - /// - /// Setting required and then *not* supplying that argument at runtime is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required(true) - /// .takes_value(true) - /// .long("config")) - /// .try_get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - #[inline] - #[must_use] - pub fn required(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::Required) - } else { - self.unset_setting(ArgSettings::Required) - } - } - - /// Sets an argument that is required when this one is present - /// - /// i.e. when using this argument, the following argument *must* be present. - /// - /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .requires("input") - /// # ; - /// ``` - /// - /// Setting [`Arg::requires(name)`] requires that the argument be used at runtime if the - /// defining argument is used. If the defining argument isn't used, the other argument isn't - /// required - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires("input") - /// .long("config")) - /// .arg(Arg::new("input")) - /// .try_get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(res.is_ok()); // We didn't use cfg, so input wasn't required - /// ``` - /// - /// Setting [`Arg::requires(name)`] and *not* supplying that argument is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires("input") - /// .long("config")) - /// .arg(Arg::new("input")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "file.conf" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [`Arg::requires(name)`]: Arg::requires() - /// [Conflicting]: Arg::conflicts_with() - /// [override]: Arg::overrides_with() - #[must_use] - pub fn requires(mut self, arg_id: T) -> Self { - self.requires.push((ArgPredicate::IsPresent, arg_id.into())); - self - } - - /// This argument must be passed alone; it conflicts with all other arguments. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .exclusive(true) - /// # ; - /// ``` - /// - /// Setting an exclusive argument and having any other arguments present at runtime - /// is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("exclusive") - /// .takes_value(true) - /// .exclusive(true) - /// .long("exclusive")) - /// .arg(Arg::new("debug") - /// .long("debug")) - /// .arg(Arg::new("input")) - /// .try_get_matches_from(vec![ - /// "prog", "--exclusive", "file.conf", "file.txt" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict); - /// ``` - #[inline] - #[must_use] - pub fn exclusive(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::Exclusive) - } else { - self.unset_setting(ArgSettings::Exclusive) - } - } - - /// Specifies that an argument can be matched to all child [`Subcommand`]s. - /// - /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however - /// their values once a user uses them will be propagated back up to parents. In effect, this - /// means one should *define* all global arguments at the top level, however it doesn't matter - /// where the user *uses* the global argument. - /// - /// # Examples - /// - /// Assume an application with two subcommands, and you'd like to define a - /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't - /// want to clutter the source with three duplicate [`Arg`] definitions. - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("prog") - /// .arg(Arg::new("verb") - /// .long("verbose") - /// .short('v') - /// .action(ArgAction::SetTrue) - /// .global(true)) - /// .subcommand(Command::new("test")) - /// .subcommand(Command::new("do-stuff")) - /// .get_matches_from(vec![ - /// "prog", "do-stuff", "--verbose" - /// ]); - /// - /// assert_eq!(m.subcommand_name(), Some("do-stuff")); - /// let sub_m = m.subcommand_matches("do-stuff").unwrap(); - /// assert_eq!(*sub_m.get_one::("verb").expect("defaulted by clap"), true); - /// ``` - /// - /// [`Subcommand`]: crate::Subcommand - #[inline] - #[must_use] - pub fn global(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::Global) - } else { - self.unset_setting(ArgSettings::Global) - } - } - - /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::action` (Issue #3772)") - )] - pub fn multiple_occurrences(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::MultipleOccurrences) - } else { - self.unset_setting(ArgSettings::MultipleOccurrences) - } - } - - /// Deprecated, for flags this is replaced with `action(ArgAction::Count).value_parser(value_parser!(u8).range(..max))` - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "For flags, replaced with `action(ArgAction::Count).value_parser(value_parser!(u8).range(..max))`" - ) - )] - pub fn max_occurrences(mut self, qty: usize) -> Self { - self.max_occurs = Some(qty); - if qty > 1 { - self.multiple_occurrences(true) - } else { - self - } - } - - /// Check if the [`ArgSettings`] variant is currently set on the argument. - /// - /// [`ArgSettings`]: crate::ArgSettings - #[inline] - pub fn is_set(&self, s: ArgSettings) -> bool { - self.settings.is_set(s) - } - - /// Apply a setting to the argument. - /// - /// See [`ArgSettings`] for a full list of possibilities and examples. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Arg, ArgSettings}; - /// Arg::new("config") - /// .setting(ArgSettings::Required) - /// .setting(ArgSettings::TakesValue) - /// # ; - /// ``` - /// - /// ```no_run - /// # use clap::{Arg, ArgSettings}; - /// Arg::new("config") - /// .setting(ArgSettings::Required | ArgSettings::TakesValue) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.insert(setting.into()); - self - } - - /// Remove a setting from the argument. - /// - /// See [`ArgSettings`] for a full list of possibilities and examples. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Arg, ArgSettings}; - /// Arg::new("config") - /// .unset_setting(ArgSettings::Required) - /// .unset_setting(ArgSettings::TakesValue) - /// # ; - /// ``` - /// - /// ```no_run - /// # use clap::{Arg, ArgSettings}; - /// Arg::new("config") - /// .unset_setting(ArgSettings::Required | ArgSettings::TakesValue) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn unset_setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.remove(setting.into()); - self - } -} - -/// # Value Handling -impl<'help> Arg<'help> { - /// Specifies that the argument takes a value at run time. - /// - /// **NOTE:** values for arguments may be specified in any of the following methods - /// - /// - Using a space such as `-o value` or `--option value` - /// - Using an equals and no space such as `-o=value` or `--option=value` - /// - Use a short and no space such as `-ovalue` - /// - /// **NOTE:** By default, args which allow [multiple values] are delimited by commas, meaning - /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to - /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`], - /// alternatively you can turn delimiting values **OFF** by using - /// [`Arg::use_value_delimiter(false)`][Arg::use_value_delimiter] - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("mode") - /// .long("mode") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--mode", "fast" - /// ]); - /// - /// assert!(m.contains_id("mode")); - /// assert_eq!(m.value_of("mode"), Some("fast")); - /// ``` - /// [`Arg::value_delimiter(char)`]: Arg::value_delimiter() - /// [multiple values]: Arg::multiple_values - #[inline] - #[must_use] - pub fn takes_value(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::TakesValue) - } else { - self.unset_setting(ArgSettings::TakesValue) - } - } - - /// Specify the behavior when parsing an argument - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::Set) - /// ); - /// - /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!(matches.occurrences_of("flag"), 0); - /// assert_eq!( - /// matches.get_many::("flag").unwrap_or_default().map(|v| v.as_str()).collect::>(), - /// vec!["value"] - /// ); - /// ``` - #[inline] - #[must_use] - pub fn action(mut self, action: ArgAction) -> Self { - self.action = Some(action); - self - } - - /// Specify the type of the argument. - /// - /// This allows parsing and validating a value before storing it into - /// [`ArgMatches`][crate::ArgMatches]. - /// - /// See also - /// - [`value_parser!`][crate::value_parser!] for auto-selecting a value parser for a given type - /// - [`BoolishValueParser`][crate::builder::BoolishValueParser], and [`FalseyValueParser`][crate::builder::FalseyValueParser] for alternative `bool` implementations - /// - [`NonEmptyStringValueParser`][crate::builder::NonEmptyStringValueParser] for basic validation for strings - /// - [`RangedI64ValueParser`][crate::builder::RangedI64ValueParser] and [`RangedU64ValueParser`][crate::builder::RangedU64ValueParser] for numeric ranges - /// - [`EnumValueParser`][crate::builder::EnumValueParser] and [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values - /// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation - /// - /// ```rust - /// let mut cmd = clap::Command::new("raw") - /// .arg( - /// clap::Arg::new("color") - /// .long("color") - /// .value_parser(["always", "auto", "never"]) - /// .default_value("auto") - /// ) - /// .arg( - /// clap::Arg::new("hostname") - /// .long("hostname") - /// .value_parser(clap::builder::NonEmptyStringValueParser::new()) - /// .takes_value(true) - /// .required(true) - /// ) - /// .arg( - /// clap::Arg::new("port") - /// .long("port") - /// .value_parser(clap::value_parser!(u16).range(3000..)) - /// .takes_value(true) - /// .required(true) - /// ); - /// - /// let m = cmd.try_get_matches_from_mut( - /// ["cmd", "--hostname", "rust-lang.org", "--port", "3001"] - /// ).unwrap(); - /// - /// let color: &String = m.get_one("color") - /// .expect("default"); - /// assert_eq!(color, "auto"); - /// - /// let hostname: &String = m.get_one("hostname") - /// .expect("required"); - /// assert_eq!(hostname, "rust-lang.org"); - /// - /// let port: u16 = *m.get_one("port") - /// .expect("required"); - /// assert_eq!(port, 3001); - /// ``` - pub fn value_parser(mut self, parser: impl Into) -> Self { - self.value_parser = Some(parser.into()); - self - } - - /// Specifies that the argument may have an unknown number of values - /// - /// Without any other settings, this argument may appear only *once*. - /// - /// For example, `--opt val1 val2` is allowed, but `--opt val1 val2 --opt val3` is not. - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`]. - /// - /// **WARNING:** - /// - /// Setting `multiple_values` for an argument that takes a value, but with no other details can - /// be dangerous in some circumstances. Because multiple values are allowed, - /// `--option val1 val2 val3` is perfectly valid. Be careful when designing a CLI where - /// positional arguments are *also* expected as `clap` will continue parsing *values* until one - /// of the following happens: - /// - /// - It reaches the [maximum number of values] - /// - It reaches a [specific number of values] - /// - It finds another flag or option (i.e. something that starts with a `-`) - /// - It reaches a [value terminator][Arg::value_terminator] is reached - /// - /// Alternatively, [require a delimiter between values][Arg::require_delimiter]. - /// - /// **WARNING:** - /// - /// When using args with `multiple_values` and [`subcommands`], one needs to consider the - /// possibility of an argument value being the same as a valid subcommand. By default `clap` will - /// parse the argument in question as a value *only if* a value is possible at that moment. - /// Otherwise it will be parsed as a subcommand. In effect, this means using `multiple_values` with no - /// additional parameters and a value that coincides with a subcommand name, the subcommand - /// cannot be called unless another argument is passed between them. - /// - /// As an example, consider a CLI with an option `--ui-paths=...` and subcommand `signer` - /// - /// The following would be parsed as values to `--ui-paths`. - /// - /// ```text - /// $ program --ui-paths path1 path2 signer - /// ``` - /// - /// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values - /// until another argument is reached and it knows `--ui-paths` is done parsing. - /// - /// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding - /// [`Arg::number_of_values(1)`] or using *only* [`ArgAction::Append`]. The following are all - /// valid, and `signer` is parsed as a subcommand in the first case, but a value in the second - /// case. - /// - /// ```text - /// $ program --ui-paths path1 signer - /// $ program --ui-paths path1 --ui-paths signer signer - /// ``` - /// - /// # Examples - /// - /// An example with options - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .multiple_values(true) - /// .short('F')) - /// .get_matches_from(vec![ - /// "prog", "-F", "file1", "file2", "file3" - /// ]); - /// - /// assert!(m.contains_id("file")); - /// let files: Vec<_> = m.values_of("file").unwrap().collect(); - /// assert_eq!(files, ["file1", "file2", "file3"]); - /// ``` - /// - /// Although `multiple_values` has been specified, we cannot use the argument more than once. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .multiple_values(true) - /// .short('F')) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1", "-F", "file2", "-F", "file3" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage) - /// ``` - /// - /// A common mistake is to define an option which allows multiple values, and a positional - /// argument. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .multiple_values(true) - /// .short('F')) - /// .arg(Arg::new("word")) - /// .get_matches_from(vec![ - /// "prog", "-F", "file1", "file2", "file3", "word" - /// ]); - /// - /// assert!(m.contains_id("file")); - /// let files: Vec<_> = m.values_of("file").unwrap().collect(); - /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?! - /// assert!(!m.contains_id("word")); // but we clearly used word! - /// ``` - /// - /// The problem is `clap` doesn't know when to stop parsing values for "files". This is further - /// compounded by if we'd said `word -F file1 file2` it would have worked fine, so it would - /// appear to only fail sometimes...not good! - /// - /// A solution for the example above is to limit how many values with a [maximum], or [specific] - /// number, or to say [`ArgAction::Append`] is ok, but multiple values is not. - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .action(ArgAction::Append) - /// .short('F')) - /// .arg(Arg::new("word")) - /// .get_matches_from(vec![ - /// "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word" - /// ]); - /// - /// assert!(m.contains_id("file")); - /// let files: Vec<_> = m.values_of("file").unwrap().collect(); - /// assert_eq!(files, ["file1", "file2", "file3"]); - /// assert!(m.contains_id("word")); - /// assert_eq!(m.value_of("word"), Some("word")); - /// ``` - /// - /// As a final example, let's fix the above error and get a pretty message to the user :) - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind, ArgAction}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .action(ArgAction::Append) - /// .short('F')) - /// .arg(Arg::new("word")) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1", "file2", "file3", "word" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - /// - /// [`subcommands`]: crate::Command::subcommand() - /// [`Arg::number_of_values(1)`]: Arg::number_of_values() - /// [maximum number of values]: Arg::max_values() - /// [specific number of values]: Arg::number_of_values() - /// [maximum]: Arg::max_values() - /// [specific]: Arg::number_of_values() - #[inline] - #[must_use] - pub fn multiple_values(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::MultipleValues) - } else { - self.unset_setting(ArgSettings::MultipleValues) - } - } - - /// The number of values allowed for this argument. - /// - /// For example, if you had a - /// `-f ` argument where you wanted exactly 3 'files' you would set - /// `.number_of_values(3)`, and this argument wouldn't be satisfied unless the user provided - /// 3 and only 3 values. - /// - /// **NOTE:** Does *not* require [`Arg::multiple_occurrences(true)`] to be set. Setting - /// [`Arg::multiple_occurrences(true)`] would allow `-f -f ` where - /// as *not* setting it would only allow one occurrence of this argument. - /// - /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] and [`Arg::multiple_values(true)`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("file") - /// .short('f') - /// .number_of_values(3); - /// ``` - /// - /// Not supplying the correct number of values is an error - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .number_of_values(2) - /// .short('F')) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::WrongNumberOfValues); - /// ``` - /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences() - #[inline] - #[must_use] - pub fn number_of_values(mut self, qty: usize) -> Self { - self.num_vals = Some(qty); - self.takes_value(true).multiple_values(true) - } - - /// The *maximum* number of values are for this argument. - /// - /// For example, if you had a - /// `-f ` argument where you wanted up to 3 'files' you would set `.max_values(3)`, and - /// this argument would be satisfied if the user provided, 1, 2, or 3 values. - /// - /// **NOTE:** This does *not* implicitly set [`Arg::multiple_occurrences(true)`]. This is because - /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single - /// occurrence with multiple values. For positional arguments this **does** set - /// [`Arg::multiple_occurrences(true)`] because there is no way to determine the difference between multiple - /// occurrences and multiple values. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("file") - /// .short('f') - /// .max_values(3); - /// ``` - /// - /// Supplying less than the maximum number of values is allowed - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .max_values(3) - /// .short('F')) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1", "file2" - /// ]); - /// - /// assert!(res.is_ok()); - /// let m = res.unwrap(); - /// let files: Vec<_> = m.values_of("file").unwrap().collect(); - /// assert_eq!(files, ["file1", "file2"]); - /// ``` - /// - /// Supplying more than the maximum number of values is an error - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .max_values(2) - /// .short('F')) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1", "file2", "file3" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences() - #[inline] - #[must_use] - pub fn max_values(mut self, qty: usize) -> Self { - self.max_vals = Some(qty); - self.takes_value(true).multiple_values(true) - } - - /// The *minimum* number of values for this argument. - /// - /// For example, if you had a - /// `-f ` argument where you wanted at least 2 'files' you would set - /// `.min_values(2)`, and this argument would be satisfied if the user provided, 2 or more - /// values. - /// - /// **NOTE:** This does not implicitly set [`Arg::multiple_occurrences(true)`]. This is because - /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single - /// occurrence with multiple values. For positional arguments this **does** set - /// [`Arg::multiple_occurrences(true)`] because there is no way to determine the difference between multiple - /// occurrences and multiple values. - /// - /// **NOTE:** Passing a non-zero value is not the same as specifying [`Arg::required(true)`]. - /// This is due to min and max validation only being performed for present arguments, - /// marking them as required will thus perform validation and a min value of 1 - /// is unnecessary, ignored if not required. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("file") - /// .short('f') - /// .min_values(3); - /// ``` - /// - /// Supplying more than the minimum number of values is allowed - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .min_values(2) - /// .short('F')) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1", "file2", "file3" - /// ]); - /// - /// assert!(res.is_ok()); - /// let m = res.unwrap(); - /// let files: Vec<_> = m.values_of("file").unwrap().collect(); - /// assert_eq!(files, ["file1", "file2", "file3"]); - /// ``` - /// - /// Supplying less than the minimum number of values is an error - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("file") - /// .takes_value(true) - /// .min_values(2) - /// .short('F')) - /// .try_get_matches_from(vec![ - /// "prog", "-F", "file1" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::TooFewValues); - /// ``` - /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences() - /// [`Arg::required(true)`]: Arg::required() - #[inline] - #[must_use] - pub fn min_values(mut self, qty: usize) -> Self { - self.min_vals = Some(qty); - self.takes_value(true).multiple_values(true) - } - - /// Placeholder for the argument's value in the help message / usage. - /// - /// This name is cosmetic only; the name is **not** used to access arguments. - /// This setting can be very helpful when describing the type of input the user should be - /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to - /// use all capital letters for the value name. - /// - /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("cfg") - /// .long("config") - /// .value_name("FILE") - /// # ; - /// ``` - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("config") - /// .long("config") - /// .value_name("FILE") - /// .help("Some help text")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// Running the above program produces the following output - /// - /// ```text - /// valnames - /// - /// USAGE: - /// valnames [OPTIONS] - /// - /// OPTIONS: - /// --config Some help text - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - /// [option]: Arg::takes_value() - /// [positional]: Arg::index() - /// [`Arg::takes_value(true)`]: Arg::takes_value() - #[inline] - #[must_use] - pub fn value_name(self, name: &'help str) -> Self { - self.value_names(&[name]) - } - - /// Placeholders for the argument's values in the help message / usage. - /// - /// These names are cosmetic only, used for help and usage strings only. The names are **not** - /// used to access arguments. The values of the arguments are accessed in numeric order (i.e. - /// if you specify two names `one` and `two` `one` will be the first matched value, `two` will - /// be the second). - /// - /// This setting can be very helpful when describing the type of input the user should be - /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to - /// use all capital letters for the value name. - /// - /// **Pro Tip:** It may help to use [`Arg::next_line_help(true)`] if there are long, or - /// multiple value names in order to not throw off the help text alignment of all options. - /// - /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] and [`Arg::multiple_values(true)`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("speed") - /// .short('s') - /// .value_names(&["fast", "slow"]); - /// ``` - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("io") - /// .long("io-files") - /// .value_names(&["INFILE", "OUTFILE"])) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// Running the above program produces the following output - /// - /// ```text - /// valnames - /// - /// USAGE: - /// valnames [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// --io-files Some help text - /// -V, --version Print version information - /// ``` - /// [`Arg::next_line_help(true)`]: Arg::next_line_help() - /// [`Arg::number_of_values`]: Arg::number_of_values() - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`Arg::multiple_values(true)`]: Arg::multiple_values() - #[must_use] - pub fn value_names(mut self, names: &[&'help str]) -> Self { - self.val_names = names.to_vec(); - self.takes_value(true) - } - - /// Provide the shell a hint about how to complete this argument. - /// - /// See [`ValueHint`][crate::ValueHint] for more information. - /// - /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]. - /// - /// For example, to take a username as argument: - /// - /// ``` - /// # use clap::{Arg, ValueHint}; - /// Arg::new("user") - /// .short('u') - /// .long("user") - /// .value_hint(ValueHint::Username); - /// ``` - /// - /// To take a full command line and its arguments (for example, when writing a command wrapper): - /// - /// ``` - /// # use clap::{Command, Arg, ValueHint}; - /// Command::new("prog") - /// .trailing_var_arg(true) - /// .arg( - /// Arg::new("command") - /// .takes_value(true) - /// .multiple_values(true) - /// .value_hint(ValueHint::CommandWithArguments) - /// ); - /// ``` - #[must_use] - pub fn value_hint(mut self, value_hint: ValueHint) -> Self { - self.value_hint = Some(value_hint); - self.takes_value(true) - } - - /// Deprecated, replaced with [`Arg::value_parser(...)`] - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::value_parser(...)`") - )] - pub fn validator(mut self, mut f: F) -> Self - where - F: FnMut(&str) -> Result + Send + 'help, - E: Into>, - { - self.validator = Some(Arc::new(Mutex::new(move |s: &str| { - f(s).map(|_| ()).map_err(|e| e.into()) - }))); - self - } - - /// Deprecated, replaced with [`Arg::value_parser(...)`] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::value_parser(...)`") - )] - pub fn validator_os(mut self, mut f: F) -> Self - where - F: FnMut(&OsStr) -> Result + Send + 'help, - E: Into>, - { - self.validator_os = Some(Arc::new(Mutex::new(move |s: &OsStr| { - f(s).map(|_| ()).map_err(|e| e.into()) - }))); - self - } - - /// Deprecated in [Issue #3743](https://github.com/clap-rs/clap/issues/3743), replaced with [`Arg::value_parser(...)`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Deprecated in Issue #3743; eplaced with `Arg::value_parser(...)`" - ) - )] - #[cfg(feature = "regex")] - #[must_use] - pub fn validator_regex( - self, - regex: impl Into>, - err_message: &'help str, - ) -> Self { - let regex = regex.into(); - self.validator(move |s: &str| { - if regex.is_match(s) { - Ok(()) - } else { - Err(err_message) - } - }) - } - - /// Deprecated, replaced with [`Arg::value_parser(PossibleValuesParser::new(...))`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `Arg::value_parser(PossibleValuesParser::new(...)).takes_value(true)`" - ) - )] - #[must_use] - pub fn possible_value(mut self, value: T) -> Self - where - T: Into>, - { - self.possible_vals.push(value.into()); - self.takes_value(true) - } - - /// Deprecated, replaced with [`Arg::value_parser(PossibleValuesParser::new(...))`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `Arg::value_parser(PossibleValuesParser::new(...)).takes_value(true)`" - ) - )] - #[must_use] - pub fn possible_values(mut self, values: I) -> Self - where - I: IntoIterator, - T: Into>, - { - self.possible_vals - .extend(values.into_iter().map(|value| value.into())); - self.takes_value(true) - } - - /// Match values against [`Arg::possible_values`] without matching case. - /// - /// When other arguments are conditionally required based on the - /// value of a case-insensitive argument, the equality check done - /// by [`Arg::required_if_eq`], [`Arg::required_if_eq_any`], or - /// [`Arg::required_if_eq_all`] is case-insensitive. - /// - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`] - /// - /// **NOTE:** To do unicode case folding, enable the `unicode` feature flag. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("pv") - /// .arg(Arg::new("option") - /// .long("option") - /// .takes_value(true) - /// .ignore_case(true) - /// .value_parser(["test123"])) - /// .get_matches_from(vec![ - /// "pv", "--option", "TeSt123", - /// ]); - /// - /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123")); - /// ``` - /// - /// This setting also works when multiple values can be defined: - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("pv") - /// .arg(Arg::new("option") - /// .short('o') - /// .long("option") - /// .takes_value(true) - /// .ignore_case(true) - /// .multiple_values(true) - /// .value_parser(["test123", "test321"])) - /// .get_matches_from(vec![ - /// "pv", "--option", "TeSt123", "teST123", "tESt321" - /// ]); - /// - /// let matched_vals = m.values_of("option").unwrap().collect::>(); - /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]); - /// ``` - #[inline] - #[must_use] - pub fn ignore_case(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::IgnoreCase) - } else { - self.unset_setting(ArgSettings::IgnoreCase) - } - } - - /// Allows values which start with a leading hyphen (`-`) - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`] - /// - /// **WARNING**: Take caution when using this setting combined with - /// [`Arg::multiple_values`], as this becomes ambiguous `$ prog --arg -- -- val`. All - /// three `--, --, val` will be values when the user may have thought the second `--` would - /// constitute the normal, "Only positional args follow" idiom. To fix this, consider using - /// [`Arg::multiple_occurrences`] which only allows a single value at a time. - /// - /// **WARNING**: When building your CLIs, consider the effects of allowing leading hyphens and - /// the user passing in a value that matches a valid short. For example, `prog -opt -F` where - /// `-F` is supposed to be a value, yet `-F` is *also* a valid short for another arg. - /// Care should be taken when designing these args. This is compounded by the ability to "stack" - /// short args. I.e. if `-val` is supposed to be a value, but `-v`, `-a`, and `-l` are all valid - /// shorts. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("pat") - /// .takes_value(true) - /// .allow_hyphen_values(true) - /// .long("pattern")) - /// .get_matches_from(vec![ - /// "prog", "--pattern", "-file" - /// ]); - /// - /// assert_eq!(m.value_of("pat"), Some("-file")); - /// ``` - /// - /// Not setting `Arg::allow_hyphen_values(true)` and supplying a value which starts with a - /// hyphen is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("pat") - /// .takes_value(true) - /// .long("pattern")) - /// .try_get_matches_from(vec![ - /// "prog", "--pattern", "-file" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - /// [`Arg::number_of_values(1)`]: Arg::number_of_values() - #[inline] - #[must_use] - pub fn allow_hyphen_values(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::AllowHyphenValues) - } else { - self.unset_setting(ArgSettings::AllowHyphenValues) - } - } - - /// Deprecated, replaced with [`Arg::value_parser(...)`] with either [`ValueParser::os_string()`][crate::builder::ValueParser::os_string] - /// or [`ValueParser::path_buf()`][crate::builder::ValueParser::path_buf] - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `Arg::value_parser(...)` with either `ValueParser::os_string()` or `ValueParser::path_buf()`" - ) - )] - pub fn allow_invalid_utf8(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::AllowInvalidUtf8) - } else { - self.unset_setting(ArgSettings::AllowInvalidUtf8) - } - } - - /// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`] - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`" - ) - )] - pub fn forbid_empty_values(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::ForbidEmptyValues) - } else { - self.unset_setting(ArgSettings::ForbidEmptyValues) - } - } - - /// Requires that options use the `--option=val` syntax - /// - /// i.e. an equals between the option and associated value. - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`] - /// - /// # Examples - /// - /// Setting `require_equals` requires that the option have an equals sign between - /// it and the associated value. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .require_equals(true) - /// .long("config")) - /// .try_get_matches_from(vec![ - /// "prog", "--config=file.conf" - /// ]); - /// - /// assert!(res.is_ok()); - /// ``` - /// - /// Setting `require_equals` and *not* supplying the equals will cause an - /// error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .require_equals(true) - /// .long("config")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "file.conf" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals); - /// ``` - #[inline] - #[must_use] - pub fn require_equals(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::RequireEquals) - } else { - self.unset_setting(ArgSettings::RequireEquals) - } - } - - /// Specifies that an argument should allow grouping of multiple values via a - /// delimiter. - /// - /// i.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`, - /// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the - /// value delimiter for all arguments that accept values (options and positional arguments) - /// - /// **NOTE:** When this setting is used, it will default [`Arg::value_delimiter`] - /// to the comma `,`. - /// - /// **NOTE:** Implicitly sets [`Arg::takes_value`] - /// - /// # Examples - /// - /// The following example shows the default behavior. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let delims = Command::new("prog") - /// .arg(Arg::new("option") - /// .long("option") - /// .use_value_delimiter(true) - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--option=val1,val2,val3", - /// ]); - /// - /// assert!(delims.contains_id("option")); - /// assert_eq!(delims.values_of("option").unwrap().collect::>(), ["val1", "val2", "val3"]); - /// ``` - /// The next example shows the difference when turning delimiters off. This is the default - /// behavior - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let nodelims = Command::new("prog") - /// .arg(Arg::new("option") - /// .long("option") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--option=val1,val2,val3", - /// ]); - /// - /// assert!(nodelims.contains_id("option")); - /// assert_eq!(nodelims.value_of("option").unwrap(), "val1,val2,val3"); - /// ``` - /// [`Arg::value_delimiter`]: Arg::value_delimiter() - #[inline] - #[must_use] - pub fn use_value_delimiter(mut self, yes: bool) -> Self { - if yes { - if self.val_delim.is_none() { - self.val_delim = Some(','); - } - self.takes_value(true) - .setting(ArgSettings::UseValueDelimiter) - } else { - self.val_delim = None; - self.unset_setting(ArgSettings::UseValueDelimiter) - } - } - - /// Deprecated, replaced with [`Arg::use_value_delimiter`] - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Arg::use_value_delimiter`") - )] - pub fn use_delimiter(self, yes: bool) -> Self { - self.use_value_delimiter(yes) - } - - /// Separator between the arguments values, defaults to `,` (comma). - /// - /// **NOTE:** implicitly sets [`Arg::use_value_delimiter(true)`] - /// - /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("config") - /// .short('c') - /// .long("config") - /// .value_delimiter(';')) - /// .get_matches_from(vec![ - /// "prog", "--config=val1;val2;val3" - /// ]); - /// - /// assert_eq!(m.values_of("config").unwrap().collect::>(), ["val1", "val2", "val3"]) - /// ``` - /// [`Arg::use_value_delimiter(true)`]: Arg::use_value_delimiter() - /// [`Arg::takes_value(true)`]: Arg::takes_value() - #[inline] - #[must_use] - pub fn value_delimiter(mut self, d: char) -> Self { - self.val_delim = Some(d); - self.takes_value(true).use_value_delimiter(true) - } - - /// Specifies that *multiple values* may only be set using the delimiter. - /// - /// This means if an option is encountered, and no delimiter is found, it is assumed that no - /// additional values for that option follow. This is unlike the default, where it is generally - /// assumed that more values will follow regardless of whether or not a delimiter is used. - /// - /// **NOTE:** The default is `false`. - /// - /// **NOTE:** Setting this requires [`Arg::use_value_delimiter`] and - /// [`Arg::takes_value`] - /// - /// **NOTE:** It's a good idea to inform the user that use of a delimiter is required, either - /// through help text or other means. - /// - /// # Examples - /// - /// These examples demonstrate what happens when `require_delimiter(true)` is used. Notice - /// everything works in this first example, as we use a delimiter, as expected. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let delims = Command::new("prog") - /// .arg(Arg::new("opt") - /// .short('o') - /// .takes_value(true) - /// .use_value_delimiter(true) - /// .require_delimiter(true) - /// .multiple_values(true)) - /// .get_matches_from(vec![ - /// "prog", "-o", "val1,val2,val3", - /// ]); - /// - /// assert!(delims.contains_id("opt")); - /// assert_eq!(delims.values_of("opt").unwrap().collect::>(), ["val1", "val2", "val3"]); - /// ``` - /// - /// In this next example, we will *not* use a delimiter. Notice it's now an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("opt") - /// .short('o') - /// .takes_value(true) - /// .use_value_delimiter(true) - /// .require_delimiter(true)) - /// .try_get_matches_from(vec![ - /// "prog", "-o", "val1", "val2", "val3", - /// ]); - /// - /// assert!(res.is_err()); - /// let err = res.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::UnknownArgument); - /// ``` - /// - /// What's happening is `-o` is getting `val1`, and because delimiters are required yet none - /// were present, it stops parsing `-o`. At this point it reaches `val2` and because no - /// positional arguments have been defined, it's an error of an unexpected argument. - /// - /// In this final example, we contrast the above with `clap`'s default behavior where the above - /// is *not* an error. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let delims = Command::new("prog") - /// .arg(Arg::new("opt") - /// .short('o') - /// .takes_value(true) - /// .multiple_values(true)) - /// .get_matches_from(vec![ - /// "prog", "-o", "val1", "val2", "val3", - /// ]); - /// - /// assert!(delims.contains_id("opt")); - /// assert_eq!(delims.values_of("opt").unwrap().collect::>(), ["val1", "val2", "val3"]); - /// ``` - #[inline] - #[must_use] - pub fn require_value_delimiter(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::RequireDelimiter) - } else { - self.unset_setting(ArgSettings::RequireDelimiter) - } - } - - /// Deprecated, replaced with [`Arg::require_value_delimiter`] - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Arg::require_value_delimiter`") - )] - pub fn require_delimiter(self, yes: bool) -> Self { - self.require_value_delimiter(yes) - } - - /// Sentinel to **stop** parsing multiple values of a give argument. - /// - /// By default when - /// one sets [`multiple_values(true)`] on an argument, clap will continue parsing values for that - /// argument until it reaches another valid argument, or one of the other more specific settings - /// for multiple values is used (such as [`min_values`], [`max_values`] or - /// [`number_of_values`]). - /// - /// **NOTE:** This setting only applies to [options] and [positional arguments] - /// - /// **NOTE:** When the terminator is passed in on the command line, it is **not** stored as one - /// of the values - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("vals") - /// .takes_value(true) - /// .multiple_values(true) - /// .value_terminator(";") - /// # ; - /// ``` - /// - /// The following example uses two arguments, a sequence of commands, and the location in which - /// to perform them - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cmds") - /// .takes_value(true) - /// .multiple_values(true) - /// .allow_hyphen_values(true) - /// .value_terminator(";")) - /// .arg(Arg::new("location")) - /// .get_matches_from(vec![ - /// "prog", "find", "-type", "f", "-name", "special", ";", "/home/clap" - /// ]); - /// let cmds: Vec<_> = m.values_of("cmds").unwrap().collect(); - /// assert_eq!(&cmds, &["find", "-type", "f", "-name", "special"]); - /// assert_eq!(m.value_of("location"), Some("/home/clap")); - /// ``` - /// [options]: Arg::takes_value() - /// [positional arguments]: Arg::index() - /// [`multiple_values(true)`]: Arg::multiple_values() - /// [`min_values`]: Arg::min_values() - /// [`number_of_values`]: Arg::number_of_values() - /// [`max_values`]: Arg::max_values() - #[inline] - #[must_use] - pub fn value_terminator(mut self, term: &'help str) -> Self { - self.terminator = Some(term); - self.takes_value(true) - } - - /// Consume all following arguments. - /// - /// Do not be parse them individually, but rather pass them in entirety. - /// - /// It is worth noting that setting this requires all values to come after a `--` to indicate - /// they should all be captured. For example: - /// - /// ```text - /// --foo something -- -v -v -v -b -b -b --baz -q -u -x - /// ``` - /// - /// Will result in everything after `--` to be considered one raw argument. This behavior - /// may not be exactly what you are expecting and using [`crate::Command::trailing_var_arg`] - /// may be more appropriate. - /// - /// **NOTE:** Implicitly sets [`Arg::takes_value(true)`] [`Arg::multiple_values(true)`], - /// [`Arg::allow_hyphen_values(true)`], and [`Arg::last(true)`] when set to `true`. - /// - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`Arg::multiple_values(true)`]: Arg::multiple_values() - /// [`Arg::allow_hyphen_values(true)`]: Arg::allow_hyphen_values() - /// [`Arg::last(true)`]: Arg::last() - #[inline] - #[must_use] - pub fn raw(self, yes: bool) -> Self { - self.takes_value(yes) - .multiple_values(yes) - .allow_hyphen_values(yes) - .last(yes) - } - - /// Value for the argument when not present. - /// - /// **NOTE:** If the user *does not* use this argument at runtime, [`ArgMatches::occurrences_of`] - /// will return `0` even though the [`ArgMatches::value_of`] will return the default specified. - /// - /// **NOTE:** If the user *does not* use this argument at runtime [`ArgMatches::contains_id`] will - /// still return `true`. If you wish to determine whether the argument was used at runtime or - /// not, consider [`ArgMatches::value_source`][crate::ArgMatches::value_source]. - /// - /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value_if`] but slightly - /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg - /// at runtime. `Arg::default_value_if` however only takes effect when the user has not provided - /// a value at runtime **and** these other conditions are met as well. If you have set - /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide this arg - /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value` - /// will be applied. - /// - /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`]. - /// - /// # Examples - /// - /// First we use the default value without providing any value at runtime. - /// - /// ```rust - /// # use clap::{Command, Arg, ValueSource}; - /// let m = Command::new("prog") - /// .arg(Arg::new("opt") - /// .long("myopt") - /// .default_value("myval")) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert_eq!(m.value_of("opt"), Some("myval")); - /// assert!(m.contains_id("opt")); - /// assert_eq!(m.value_source("opt"), Some(ValueSource::DefaultValue)); - /// ``` - /// - /// Next we provide a value at runtime to override the default. - /// - /// ```rust - /// # use clap::{Command, Arg, ValueSource}; - /// let m = Command::new("prog") - /// .arg(Arg::new("opt") - /// .long("myopt") - /// .default_value("myval")) - /// .get_matches_from(vec![ - /// "prog", "--myopt=non_default" - /// ]); - /// - /// assert_eq!(m.value_of("opt"), Some("non_default")); - /// assert!(m.contains_id("opt")); - /// assert_eq!(m.value_source("opt"), Some(ValueSource::CommandLine)); - /// ``` - /// [`ArgMatches::occurrences_of`]: crate::ArgMatches::occurrences_of() - /// [`ArgMatches::value_of`]: crate::ArgMatches::value_of() - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`ArgMatches::contains_id`]: crate::ArgMatches::contains_id() - /// [`Arg::default_value_if`]: Arg::default_value_if() - #[inline] - #[must_use] - pub fn default_value(self, val: &'help str) -> Self { - self.default_values_os(&[OsStr::new(val)]) - } - - /// Value for the argument when not present. - /// - /// See [`Arg::default_value`]. - /// - /// [`Arg::default_value`]: Arg::default_value() - /// [`OsStr`]: std::ffi::OsStr - #[inline] - #[must_use] - pub fn default_value_os(self, val: &'help OsStr) -> Self { - self.default_values_os(&[val]) - } - - /// Value for the argument when not present. - /// - /// See [`Arg::default_value`]. - /// - /// [`Arg::default_value`]: Arg::default_value() - #[inline] - #[must_use] - pub fn default_values(self, vals: &[&'help str]) -> Self { - let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect(); - self.default_values_os(&vals_vec[..]) - } - - /// Value for the argument when not present. - /// - /// See [`Arg::default_values`]. - /// - /// [`Arg::default_values`]: Arg::default_values() - /// [`OsStr`]: std::ffi::OsStr - #[inline] - #[must_use] - pub fn default_values_os(mut self, vals: &[&'help OsStr]) -> Self { - self.default_vals = vals.to_vec(); - self.takes_value(true) - } - - /// Value for the argument when the flag is present but no value is specified. - /// - /// This configuration option is often used to give the user a shortcut and allow them to - /// efficiently specify an option argument without requiring an explicitly value. The `--color` - /// argument is a common example. By, supplying an default, such as `default_missing_value("always")`, - /// the user can quickly just add `--color` to the command line to produce the desired color output. - /// - /// **NOTE:** using this configuration option requires the use of the `.min_values(0)` and the - /// `.require_equals(true)` configuration option. These are required in order to unambiguously - /// determine what, if any, value was supplied for the argument. - /// - /// # Examples - /// - /// For POSIX style `--color`: - /// ```rust - /// # use clap::{Command, Arg, ValueSource}; - /// fn cli() -> Command<'static> { - /// Command::new("prog") - /// .arg(Arg::new("color").long("color") - /// .value_name("WHEN") - /// .value_parser(["always", "auto", "never"]) - /// .default_value("auto") - /// .min_values(0) - /// .require_equals(true) - /// .default_missing_value("always") - /// .help("Specify WHEN to colorize output.") - /// ) - /// } - /// - /// // first, we'll provide no arguments - /// let m = cli().get_matches_from(vec![ - /// "prog" - /// ]); - /// assert_eq!(m.value_of("color"), Some("auto")); - /// assert_eq!(m.value_source("color"), Some(ValueSource::DefaultValue)); - /// - /// // next, we'll provide a runtime value to override the default (as usually done). - /// let m = cli().get_matches_from(vec![ - /// "prog", "--color=never" - /// ]); - /// assert_eq!(m.value_of("color"), Some("never")); - /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine)); - /// - /// // finally, we will use the shortcut and only provide the argument without a value. - /// let m = cli().get_matches_from(vec![ - /// "prog", "--color" - /// ]); - /// assert_eq!(m.value_of("color"), Some("always")); - /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine)); - /// ``` - /// - /// For bool literals: - /// ```rust - /// # use clap::{Command, Arg, ValueSource, value_parser}; - /// fn cli() -> Command<'static> { - /// Command::new("prog") - /// .arg(Arg::new("create").long("create") - /// .value_name("BOOL") - /// .value_parser(value_parser!(bool)) - /// .min_values(0) - /// .require_equals(true) - /// .default_missing_value("true") - /// ) - /// } - /// - /// // first, we'll provide no arguments - /// let m = cli().get_matches_from(vec![ - /// "prog" - /// ]); - /// assert_eq!(m.get_one::("create").copied(), None); - /// - /// // next, we'll provide a runtime value to override the default (as usually done). - /// let m = cli().get_matches_from(vec![ - /// "prog", "--create=false" - /// ]); - /// assert_eq!(m.get_one::("create").copied(), Some(false)); - /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine)); - /// - /// // finally, we will use the shortcut and only provide the argument without a value. - /// let m = cli().get_matches_from(vec![ - /// "prog", "--create" - /// ]); - /// assert_eq!(m.get_one::("create").copied(), Some(true)); - /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine)); - /// ``` - /// - /// [`ArgMatches::value_of`]: ArgMatches::value_of() - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`Arg::default_value`]: Arg::default_value() - #[inline] - #[must_use] - pub fn default_missing_value(self, val: &'help str) -> Self { - self.default_missing_values_os(&[OsStr::new(val)]) - } - - /// Value for the argument when the flag is present but no value is specified. - /// - /// See [`Arg::default_missing_value`]. - /// - /// [`Arg::default_missing_value`]: Arg::default_missing_value() - /// [`OsStr`]: std::ffi::OsStr - #[inline] - #[must_use] - pub fn default_missing_value_os(self, val: &'help OsStr) -> Self { - self.default_missing_values_os(&[val]) - } - - /// Value for the argument when the flag is present but no value is specified. - /// - /// See [`Arg::default_missing_value`]. - /// - /// [`Arg::default_missing_value`]: Arg::default_missing_value() - #[inline] - #[must_use] - pub fn default_missing_values(self, vals: &[&'help str]) -> Self { - let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect(); - self.default_missing_values_os(&vals_vec[..]) - } - - /// Value for the argument when the flag is present but no value is specified. - /// - /// See [`Arg::default_missing_values`]. - /// - /// [`Arg::default_missing_values`]: Arg::default_missing_values() - /// [`OsStr`]: std::ffi::OsStr - #[inline] - #[must_use] - pub fn default_missing_values_os(mut self, vals: &[&'help OsStr]) -> Self { - self.default_missing_vals = vals.to_vec(); - self.takes_value(true) - } - - /// Read from `name` environment variable when argument is not present. - /// - /// If it is not present in the environment, then default - /// rules will apply. - /// - /// If user sets the argument in the environment: - /// - When [`Arg::takes_value(true)`] is not set, the flag is considered raised. - /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will - /// return value of the environment variable. - /// - /// If user doesn't set the argument in the environment: - /// - When [`Arg::takes_value(true)`] is not set, the flag is considered off. - /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will - /// return the default specified. - /// - /// # Examples - /// - /// In this example, we show the variable coming from the environment: - /// - /// ```rust - /// # use std::env; - /// # use clap::{Command, Arg}; - /// - /// env::set_var("MY_FLAG", "env"); - /// - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag") - /// .env("MY_FLAG") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert_eq!(m.value_of("flag"), Some("env")); - /// ``` - /// - /// In this example, because [`Arg::takes_value(false)`] (by default), - /// `prog` is a flag that accepts an optional, case-insensitive boolean literal. - /// A `false` literal is `n`, `no`, `f`, `false`, `off` or `0`. - /// An absent environment variable will also be considered as `false`. - /// Anything else will considered as `true`. - /// - /// ```rust - /// # use std::env; - /// # use clap::{Command, Arg}; - /// - /// env::set_var("TRUE_FLAG", "true"); - /// env::set_var("FALSE_FLAG", "0"); - /// - /// let m = Command::new("prog") - /// .arg(Arg::new("true_flag") - /// .long("true_flag") - /// .env("TRUE_FLAG")) - /// .arg(Arg::new("false_flag") - /// .long("false_flag") - /// .env("FALSE_FLAG")) - /// .arg(Arg::new("absent_flag") - /// .long("absent_flag") - /// .env("ABSENT_FLAG")) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(m.is_present("true_flag")); - /// assert_eq!(m.value_of("true_flag"), None); - /// assert!(!m.is_present("false_flag")); - /// assert!(!m.is_present("absent_flag")); - /// ``` - /// - /// In this example, we show the variable coming from an option on the CLI: - /// - /// ```rust - /// # use std::env; - /// # use clap::{Command, Arg}; - /// - /// env::set_var("MY_FLAG", "env"); - /// - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag") - /// .env("MY_FLAG") - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "prog", "--flag", "opt" - /// ]); - /// - /// assert_eq!(m.value_of("flag"), Some("opt")); - /// ``` - /// - /// In this example, we show the variable coming from the environment even with the - /// presence of a default: - /// - /// ```rust - /// # use std::env; - /// # use clap::{Command, Arg}; - /// - /// env::set_var("MY_FLAG", "env"); - /// - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag") - /// .env("MY_FLAG") - /// .takes_value(true) - /// .default_value("default")) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert_eq!(m.value_of("flag"), Some("env")); - /// ``` - /// - /// In this example, we show the use of multiple values in a single environment variable: - /// - /// ```rust - /// # use std::env; - /// # use clap::{Command, Arg}; - /// - /// env::set_var("MY_FLAG_MULTI", "env1,env2"); - /// - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag") - /// .env("MY_FLAG_MULTI") - /// .takes_value(true) - /// .multiple_values(true) - /// .use_value_delimiter(true)) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert_eq!(m.values_of("flag").unwrap().collect::>(), vec!["env1", "env2"]); - /// ``` - /// [`ArgMatches::value_of`]: crate::ArgMatches::value_of() - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`Arg::use_value_delimiter(true)`]: Arg::use_value_delimiter() - #[cfg(feature = "env")] - #[inline] - #[must_use] - pub fn env(self, name: &'help str) -> Self { - self.env_os(OsStr::new(name)) - } - - /// Read from `name` environment variable when argument is not present. - /// - /// See [`Arg::env`]. - #[cfg(feature = "env")] - #[inline] - #[must_use] - pub fn env_os(mut self, name: &'help OsStr) -> Self { - self.env = Some((name, env::var_os(name))); - self - } -} - -/// # Help -impl<'help> Arg<'help> { - /// Sets the description of the argument for short help (`-h`). - /// - /// Typically, this is a short (one line) description of the arg. - /// - /// If [`Arg::long_help`] is not specified, this message will be displayed for `--help`. - /// - /// **NOTE:** Only `Arg::help` is used in completion script generation in order to be concise - /// - /// # Examples - /// - /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to - /// include a newline in the help text and have the following text be properly aligned with all - /// the other help text. - /// - /// Setting `help` displays a short message to the side of the argument when the user passes - /// `-h` or `--help` (by default). - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .help("Some help text describing the --config arg")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// The above example displays - /// - /// ```notrust - /// helptest - /// - /// USAGE: - /// helptest [OPTIONS] - /// - /// OPTIONS: - /// --config Some help text describing the --config arg - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - /// [`Arg::long_help`]: Arg::long_help() - #[inline] - #[must_use] - pub fn help(mut self, h: impl Into>) -> Self { - self.help = h.into(); - self - } - - /// Sets the description of the argument for long help (`--help`). - /// - /// Typically this a more detailed (multi-line) message - /// that describes the arg. - /// - /// If [`Arg::help`] is not specified, this message will be displayed for `-h`. - /// - /// **NOTE:** Only [`Arg::help`] is used in completion script generation in order to be concise - /// - /// # Examples - /// - /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to - /// include a newline in the help text and have the following text be properly aligned with all - /// the other help text. - /// - /// Setting `help` displays a short message to the side of the argument when the user passes - /// `-h` or `--help` (by default). - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .long_help( - /// "The config file used by the myprog must be in JSON format - /// with only valid keys and may not contain other nonsense - /// that cannot be read by this program. Obviously I'm going on - /// and on, so I'll stop now.")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// The above example displays - /// - /// ```text - /// prog - /// - /// USAGE: - /// prog [OPTIONS] - /// - /// OPTIONS: - /// --config - /// The config file used by the myprog must be in JSON format - /// with only valid keys and may not contain other nonsense - /// that cannot be read by this program. Obviously I'm going on - /// and on, so I'll stop now. - /// - /// -h, --help - /// Print help information - /// - /// -V, --version - /// Print version information - /// ``` - /// [`Arg::help`]: Arg::help() - #[inline] - #[must_use] - pub fn long_help(mut self, h: impl Into>) -> Self { - self.long_help = h.into(); - self - } - - /// Allows custom ordering of args within the help message. - /// - /// Args with a lower value will be displayed first in the help message. This is helpful when - /// one would like to emphasise frequently used args, or prioritize those towards the top of - /// the list. Args with duplicate display orders will be displayed in alphabetical order. - /// - /// **NOTE:** The default is 999 for all arguments. - /// - /// **NOTE:** This setting is ignored for [positional arguments] which are always displayed in - /// [index] order. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("a") // Typically args are grouped alphabetically by name. - /// // Args without a display_order have a value of 999 and are - /// // displayed alphabetically with all other 999 valued args. - /// .long("long-option") - /// .short('o') - /// .takes_value(true) - /// .help("Some help and text")) - /// .arg(Arg::new("b") - /// .long("other-option") - /// .short('O') - /// .takes_value(true) - /// .display_order(1) // In order to force this arg to appear *first* - /// // all we have to do is give it a value lower than 999. - /// // Any other args with a value of 1 will be displayed - /// // alphabetically with this one...then 2 values, then 3, etc. - /// .help("I should be first!")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// The above example displays the following help message - /// - /// ```text - /// cust-ord - /// - /// USAGE: - /// cust-ord [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// -O, --other-option I should be first! - /// -o, --long-option Some help and text - /// ``` - /// [positional arguments]: Arg::index() - /// [index]: Arg::index() - #[inline] - #[must_use] - pub fn display_order(mut self, ord: usize) -> Self { - self.disp_ord.set_explicit(ord); - self - } - - /// Override the [current] help section. - /// - /// [current]: crate::Command::help_heading - #[inline] - #[must_use] - pub fn help_heading(mut self, heading: O) -> Self - where - O: Into>, - { - self.help_heading = Some(heading.into()); - self - } - - /// Render the [help][Arg::help] on the line after the argument. - /// - /// This can be helpful for arguments with very long or complex help messages. - /// This can also be helpful for arguments with very long flag names, or many/long value names. - /// - /// **NOTE:** To apply this setting to all arguments and subcommands, consider using - /// [`crate::Command::next_line_help`] - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("opt") - /// .long("long-option-flag") - /// .short('o') - /// .takes_value(true) - /// .next_line_help(true) - /// .value_names(&["value1", "value2"]) - /// .help("Some really long help and complex\n\ - /// help that makes more sense to be\n\ - /// on a line after the option")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// The above example displays the following help message - /// - /// ```text - /// nlh - /// - /// USAGE: - /// nlh [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// -o, --long-option-flag - /// Some really long help and complex - /// help that makes more sense to be - /// on a line after the option - /// ``` - #[inline] - #[must_use] - pub fn next_line_help(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::NextLineHelp) - } else { - self.unset_setting(ArgSettings::NextLineHelp) - } - } - - /// Do not display the argument in help message. - /// - /// **NOTE:** This does **not** hide the argument from usage strings on error - /// - /// # Examples - /// - /// Setting `Hidden` will hide the argument when displaying help text - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .hide(true) - /// .help("Some help text describing the --config arg")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// The above example displays - /// - /// ```text - /// helptest - /// - /// USAGE: - /// helptest [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - #[inline] - #[must_use] - pub fn hide(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::Hidden) - } else { - self.unset_setting(ArgSettings::Hidden) - } - } - - /// Do not display the [possible values][crate::builder::ValueParser::possible_values] in the help message. - /// - /// This is useful for args with many values, or ones which are explained elsewhere in the - /// help text. - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`] - /// - /// To set this for all arguments, see - /// [`Command::hide_possible_values`][crate::Command::hide_possible_values]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("mode") - /// .long("mode") - /// .value_parser(["fast", "slow"]) - /// .takes_value(true) - /// .hide_possible_values(true)); - /// ``` - /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of - /// the help text would be omitted. - #[inline] - #[must_use] - pub fn hide_possible_values(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::HidePossibleValues) - } else { - self.unset_setting(ArgSettings::HidePossibleValues) - } - } - - /// Do not display the default value of the argument in the help message. - /// - /// This is useful when default behavior of an arg is explained elsewhere in the help text. - /// - /// **NOTE:** Setting this requires [`Arg::takes_value`] - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("connect") - /// .arg(Arg::new("host") - /// .long("host") - /// .default_value("localhost") - /// .takes_value(true) - /// .hide_default_value(true)); - /// - /// ``` - /// - /// If we were to run the above program with `--help` the `[default: localhost]` portion of - /// the help text would be omitted. - #[inline] - #[must_use] - pub fn hide_default_value(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::HideDefaultValue) - } else { - self.unset_setting(ArgSettings::HideDefaultValue) - } - } - - /// Do not display in help the environment variable name. - /// - /// This is useful when the variable option is explained elsewhere in the help text. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("mode") - /// .long("mode") - /// .env("MODE") - /// .takes_value(true) - /// .hide_env(true)); - /// ``` - /// - /// If we were to run the above program with `--help` the `[env: MODE]` portion of the help - /// text would be omitted. - #[cfg(feature = "env")] - #[inline] - #[must_use] - pub fn hide_env(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::HideEnv) - } else { - self.unset_setting(ArgSettings::HideEnv) - } - } - - /// Do not display in help any values inside the associated ENV variables for the argument. - /// - /// This is useful when ENV vars contain sensitive values. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("connect") - /// .arg(Arg::new("host") - /// .long("host") - /// .env("CONNECT") - /// .takes_value(true) - /// .hide_env_values(true)); - /// - /// ``` - /// - /// If we were to run the above program with `$ CONNECT=super_secret connect --help` the - /// `[default: CONNECT=super_secret]` portion of the help text would be omitted. - #[cfg(feature = "env")] - #[inline] - #[must_use] - pub fn hide_env_values(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::HideEnvValues) - } else { - self.unset_setting(ArgSettings::HideEnvValues) - } - } - - /// Hides an argument from short help (`-h`). - /// - /// **NOTE:** This does **not** hide the argument from usage strings on error - /// - /// **NOTE:** Setting this option will cause next-line-help output style to be used - /// when long help (`--help`) is called. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("debug") - /// .hide_short_help(true); - /// ``` - /// - /// Setting `hide_short_help(true)` will hide the argument when displaying short help text - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .hide_short_help(true) - /// .help("Some help text describing the --config arg")) - /// .get_matches_from(vec![ - /// "prog", "-h" - /// ]); - /// ``` - /// - /// The above example displays - /// - /// ```text - /// helptest - /// - /// USAGE: - /// helptest [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - /// - /// However, when --help is called - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .hide_short_help(true) - /// .help("Some help text describing the --config arg")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// Then the following would be displayed - /// - /// ```text - /// helptest - /// - /// USAGE: - /// helptest [OPTIONS] - /// - /// OPTIONS: - /// --config Some help text describing the --config arg - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - #[inline] - #[must_use] - pub fn hide_short_help(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::HiddenShortHelp) - } else { - self.unset_setting(ArgSettings::HiddenShortHelp) - } - } - - /// Hides an argument from long help (`--help`). - /// - /// **NOTE:** This does **not** hide the argument from usage strings on error - /// - /// **NOTE:** Setting this option will cause next-line-help output style to be used - /// when long help (`--help`) is called. - /// - /// # Examples - /// - /// Setting `hide_long_help(true)` will hide the argument when displaying long help text - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .hide_long_help(true) - /// .help("Some help text describing the --config arg")) - /// .get_matches_from(vec![ - /// "prog", "--help" - /// ]); - /// ``` - /// - /// The above example displays - /// - /// ```text - /// helptest - /// - /// USAGE: - /// helptest [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - /// - /// However, when -h is called - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .long("config") - /// .hide_long_help(true) - /// .help("Some help text describing the --config arg")) - /// .get_matches_from(vec![ - /// "prog", "-h" - /// ]); - /// ``` - /// - /// Then the following would be displayed - /// - /// ```text - /// helptest - /// - /// USAGE: - /// helptest [OPTIONS] - /// - /// OPTIONS: - /// --config Some help text describing the --config arg - /// -h, --help Print help information - /// -V, --version Print version information - /// ``` - #[inline] - #[must_use] - pub fn hide_long_help(self, yes: bool) -> Self { - if yes { - self.setting(ArgSettings::HiddenLongHelp) - } else { - self.unset_setting(ArgSettings::HiddenLongHelp) - } - } -} - -/// # Advanced Argument Relations -impl<'help> Arg<'help> { - /// The name of the [`ArgGroup`] the argument belongs to. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("debug") - /// .long("debug") - /// .group("mode") - /// # ; - /// ``` - /// - /// Multiple arguments can be a member of a single group and then the group checked as if it - /// was one of said arguments. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("debug") - /// .long("debug") - /// .group("mode")) - /// .arg(Arg::new("verbose") - /// .long("verbose") - /// .group("mode")) - /// .get_matches_from(vec![ - /// "prog", "--debug" - /// ]); - /// assert!(m.contains_id("mode")); - /// ``` - /// - /// [`ArgGroup`]: crate::ArgGroup - #[must_use] - pub fn group(mut self, group_id: T) -> Self { - self.groups.push(group_id.into()); - self - } - - /// The names of [`ArgGroup`]'s the argument belongs to. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Arg::new("debug") - /// .long("debug") - /// .groups(&["mode", "verbosity"]) - /// # ; - /// ``` - /// - /// Arguments can be members of multiple groups and then the group checked as if it - /// was one of said arguments. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("debug") - /// .long("debug") - /// .groups(&["mode", "verbosity"])) - /// .arg(Arg::new("verbose") - /// .long("verbose") - /// .groups(&["mode", "verbosity"])) - /// .get_matches_from(vec![ - /// "prog", "--debug" - /// ]); - /// assert!(m.contains_id("mode")); - /// assert!(m.contains_id("verbosity")); - /// ``` - /// - /// [`ArgGroup`]: crate::ArgGroup - #[must_use] - pub fn groups(mut self, group_ids: &[T]) -> Self { - self.groups.extend(group_ids.iter().map(Id::from)); - self - } - - /// Specifies the value of the argument if `arg` has been used at runtime. - /// - /// If `val` is set to `None`, `arg` only needs to be present. If `val` is set to `"some-val"` - /// then `arg` must be present at runtime **and** have the value `val`. - /// - /// If `default` is set to `None`, `default_value` will be removed. - /// - /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value`] but slightly - /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg - /// at runtime. This setting however only takes effect when the user has not provided a value at - /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value` - /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were - /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied. - /// - /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`]. - /// - /// # Examples - /// - /// First we use the default value only if another arg is present at runtime. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag")) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_if("flag", None, Some("default"))) - /// .get_matches_from(vec![ - /// "prog", "--flag" - /// ]); - /// - /// assert_eq!(m.value_of("other"), Some("default")); - /// ``` - /// - /// Next we run the same test, but without providing `--flag`. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag")) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_if("flag", None, Some("default"))) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert_eq!(m.value_of("other"), None); - /// ``` - /// - /// Now lets only use the default value if `--opt` contains the value `special`. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("opt") - /// .takes_value(true) - /// .long("opt")) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_if("opt", Some("special"), Some("default"))) - /// .get_matches_from(vec![ - /// "prog", "--opt", "special" - /// ]); - /// - /// assert_eq!(m.value_of("other"), Some("default")); - /// ``` - /// - /// We can run the same test and provide any value *other than* `special` and we won't get a - /// default value. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("opt") - /// .takes_value(true) - /// .long("opt")) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_if("opt", Some("special"), Some("default"))) - /// .get_matches_from(vec![ - /// "prog", "--opt", "hahaha" - /// ]); - /// - /// assert_eq!(m.value_of("other"), None); - /// ``` - /// - /// If we want to unset the default value for an Arg based on the presence or - /// value of some other Arg. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag")) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value("default") - /// .default_value_if("flag", None, None)) - /// .get_matches_from(vec![ - /// "prog", "--flag" - /// ]); - /// - /// assert_eq!(m.value_of("other"), None); - /// ``` - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`Arg::default_value`]: Arg::default_value() - #[must_use] - pub fn default_value_if( - self, - arg_id: T, - val: Option<&'help str>, - default: Option<&'help str>, - ) -> Self { - self.default_value_if_os(arg_id, val.map(OsStr::new), default.map(OsStr::new)) - } - - /// Provides a conditional default value in the exact same manner as [`Arg::default_value_if`] - /// only using [`OsStr`]s instead. - /// - /// [`Arg::default_value_if`]: Arg::default_value_if() - /// [`OsStr`]: std::ffi::OsStr - #[must_use] - pub fn default_value_if_os( - mut self, - arg_id: T, - val: Option<&'help OsStr>, - default: Option<&'help OsStr>, - ) -> Self { - self.default_vals_ifs - .push((arg_id.into(), val.into(), default)); - self.takes_value(true) - } - - /// Specifies multiple values and conditions in the same manner as [`Arg::default_value_if`]. - /// - /// The method takes a slice of tuples in the `(arg, Option, default)` format. - /// - /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first - /// if multiple conditions are true, the first one found will be applied and the ultimate value. - /// - /// # Examples - /// - /// First we use the default value only if another arg is present at runtime. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag")) - /// .arg(Arg::new("opt") - /// .long("opt") - /// .takes_value(true)) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_ifs(&[ - /// ("flag", None, Some("default")), - /// ("opt", Some("channal"), Some("chan")), - /// ])) - /// .get_matches_from(vec![ - /// "prog", "--opt", "channal" - /// ]); - /// - /// assert_eq!(m.value_of("other"), Some("chan")); - /// ``` - /// - /// Next we run the same test, but without providing `--flag`. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag")) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_ifs(&[ - /// ("flag", None, Some("default")), - /// ("opt", Some("channal"), Some("chan")), - /// ])) - /// .get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert_eq!(m.value_of("other"), None); - /// ``` - /// - /// We can also see that these values are applied in order, and if more than one condition is - /// true, only the first evaluated "wins" - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("flag") - /// .long("flag")) - /// .arg(Arg::new("opt") - /// .long("opt") - /// .takes_value(true)) - /// .arg(Arg::new("other") - /// .long("other") - /// .default_value_ifs(&[ - /// ("flag", None, Some("default")), - /// ("opt", Some("channal"), Some("chan")), - /// ])) - /// .get_matches_from(vec![ - /// "prog", "--opt", "channal", "--flag" - /// ]); - /// - /// assert_eq!(m.value_of("other"), Some("default")); - /// ``` - /// [`Arg::takes_value(true)`]: Arg::takes_value() - /// [`Arg::default_value_if`]: Arg::default_value_if() - #[must_use] - pub fn default_value_ifs( - mut self, - ifs: &[(T, Option<&'help str>, Option<&'help str>)], - ) -> Self { - for (arg, val, default) in ifs { - self = self.default_value_if_os(arg, val.map(OsStr::new), default.map(OsStr::new)); - } - self - } - - /// Provides multiple conditional default values in the exact same manner as - /// [`Arg::default_value_ifs`] only using [`OsStr`]s instead. - /// - /// [`Arg::default_value_ifs`]: Arg::default_value_ifs() - /// [`OsStr`]: std::ffi::OsStr - #[must_use] - pub fn default_value_ifs_os( - mut self, - ifs: &[(T, Option<&'help OsStr>, Option<&'help OsStr>)], - ) -> Self { - for (arg, val, default) in ifs { - self = self.default_value_if_os(arg, *val, *default); - } - self - } - - /// Set this arg as [required] as long as the specified argument is not present at runtime. - /// - /// **Pro Tip:** Using `Arg::required_unless_present` implies [`Arg::required`] and is therefore not - /// mandatory to also set. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required_unless_present("debug") - /// # ; - /// ``` - /// - /// In the following example, the required argument is *not* provided, - /// but it's not an error because the `unless` arg has been supplied. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_unless_present("dbg") - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("dbg") - /// .long("debug")) - /// .try_get_matches_from(vec![ - /// "prog", "--debug" - /// ]); - /// - /// assert!(res.is_ok()); - /// ``` - /// - /// Setting `Arg::required_unless_present(name)` and *not* supplying `name` or this arg is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_unless_present("dbg") - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("dbg") - /// .long("debug")) - /// .try_get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [required]: Arg::required() - #[must_use] - pub fn required_unless_present(mut self, arg_id: T) -> Self { - self.r_unless.push(arg_id.into()); - self - } - - /// Sets this arg as [required] unless *all* of the specified arguments are present at runtime. - /// - /// In other words, parsing will succeed only if user either - /// * supplies the `self` arg. - /// * supplies *all* of the `names` arguments. - /// - /// **NOTE:** If you wish for this argument to only be required unless *any of* these args are - /// present see [`Arg::required_unless_present_any`] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required_unless_present_all(&["cfg", "dbg"]) - /// # ; - /// ``` - /// - /// In the following example, the required argument is *not* provided, but it's not an error - /// because *all* of the `names` args have been supplied. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_unless_present_all(&["dbg", "infile"]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("dbg") - /// .long("debug")) - /// .arg(Arg::new("infile") - /// .short('i') - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog", "--debug", "-i", "file" - /// ]); - /// - /// assert!(res.is_ok()); - /// ``` - /// - /// Setting [`Arg::required_unless_present_all(names)`] and *not* supplying - /// either *all* of `unless` args or the `self` arg is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_unless_present_all(&["dbg", "infile"]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("dbg") - /// .long("debug")) - /// .arg(Arg::new("infile") - /// .short('i') - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [required]: Arg::required() - /// [`Arg::required_unless_present_any`]: Arg::required_unless_present_any() - /// [`Arg::required_unless_present_all(names)`]: Arg::required_unless_present_all() - #[must_use] - pub fn required_unless_present_all(mut self, names: I) -> Self - where - I: IntoIterator, - T: Key, - { - self.r_unless_all.extend(names.into_iter().map(Id::from)); - self - } - - /// Sets this arg as [required] unless *any* of the specified arguments are present at runtime. - /// - /// In other words, parsing will succeed only if user either - /// * supplies the `self` arg. - /// * supplies *one or more* of the `unless` arguments. - /// - /// **NOTE:** If you wish for this argument to be required unless *all of* these args are - /// present see [`Arg::required_unless_present_all`] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required_unless_present_any(&["cfg", "dbg"]) - /// # ; - /// ``` - /// - /// Setting [`Arg::required_unless_present_any(names)`] requires that the argument be used at runtime - /// *unless* *at least one of* the args in `names` are present. In the following example, the - /// required argument is *not* provided, but it's not an error because one the `unless` args - /// have been supplied. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_unless_present_any(&["dbg", "infile"]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("dbg") - /// .long("debug")) - /// .arg(Arg::new("infile") - /// .short('i') - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog", "--debug" - /// ]); - /// - /// assert!(res.is_ok()); - /// ``` - /// - /// Setting [`Arg::required_unless_present_any(names)`] and *not* supplying *at least one of* `names` - /// or this arg is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_unless_present_any(&["dbg", "infile"]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("dbg") - /// .long("debug")) - /// .arg(Arg::new("infile") - /// .short('i') - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [required]: Arg::required() - /// [`Arg::required_unless_present_any(names)`]: Arg::required_unless_present_any() - /// [`Arg::required_unless_present_all`]: Arg::required_unless_present_all() - #[must_use] - pub fn required_unless_present_any(mut self, names: I) -> Self - where - I: IntoIterator, - T: Key, - { - self.r_unless.extend(names.into_iter().map(Id::from)); - self - } - - /// This argument is [required] only if the specified `arg` is present at runtime and its value - /// equals `val`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required_if_eq("other_arg", "value") - /// # ; - /// ``` - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .required_if_eq("other", "special") - /// .long("config")) - /// .arg(Arg::new("other") - /// .long("other") - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog", "--other", "not-special" - /// ]); - /// - /// assert!(res.is_ok()); // We didn't use --other=special, so "cfg" wasn't required - /// - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .required_if_eq("other", "special") - /// .long("config")) - /// .arg(Arg::new("other") - /// .long("other") - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog", "--other", "special" - /// ]); - /// - /// // We did use --other=special so "cfg" had become required but was missing. - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .required_if_eq("other", "special") - /// .long("config")) - /// .arg(Arg::new("other") - /// .long("other") - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog", "--other", "SPECIAL" - /// ]); - /// - /// // By default, the comparison is case-sensitive, so "cfg" wasn't required - /// assert!(res.is_ok()); - /// - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .required_if_eq("other", "special") - /// .long("config")) - /// .arg(Arg::new("other") - /// .long("other") - /// .ignore_case(true) - /// .takes_value(true)) - /// .try_get_matches_from(vec![ - /// "prog", "--other", "SPECIAL" - /// ]); - /// - /// // However, case-insensitive comparisons can be enabled. This typically occurs when using Arg::possible_values(). - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [`Arg::requires(name)`]: Arg::requires() - /// [Conflicting]: Arg::conflicts_with() - /// [required]: Arg::required() - #[must_use] - pub fn required_if_eq(mut self, arg_id: T, val: &'help str) -> Self { - self.r_ifs.push((arg_id.into(), val)); - self - } - - /// Specify this argument is [required] based on multiple conditions. - /// - /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become - /// valid if one of the specified `arg`'s value equals its corresponding `val`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required_if_eq_any(&[ - /// ("extra", "val"), - /// ("option", "spec") - /// ]) - /// # ; - /// ``` - /// - /// Setting `Arg::required_if_eq_any(&[(arg, val)])` makes this arg required if any of the `arg`s - /// are used at runtime and it's corresponding value is equal to `val`. If the `arg`'s value is - /// anything other than `val`, this argument isn't required. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_if_eq_any(&[ - /// ("extra", "val"), - /// ("option", "spec") - /// ]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("extra") - /// .takes_value(true) - /// .long("extra")) - /// .arg(Arg::new("option") - /// .takes_value(true) - /// .long("option")) - /// .try_get_matches_from(vec![ - /// "prog", "--option", "other" - /// ]); - /// - /// assert!(res.is_ok()); // We didn't use --option=spec, or --extra=val so "cfg" isn't required - /// ``` - /// - /// Setting `Arg::required_if_eq_any(&[(arg, val)])` and having any of the `arg`s used with its - /// value of `val` but *not* using this arg is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_if_eq_any(&[ - /// ("extra", "val"), - /// ("option", "spec") - /// ]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("extra") - /// .takes_value(true) - /// .long("extra")) - /// .arg(Arg::new("option") - /// .takes_value(true) - /// .long("option")) - /// .try_get_matches_from(vec![ - /// "prog", "--option", "spec" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [`Arg::requires(name)`]: Arg::requires() - /// [Conflicting]: Arg::conflicts_with() - /// [required]: Arg::required() - #[must_use] - pub fn required_if_eq_any(mut self, ifs: &[(T, &'help str)]) -> Self { - self.r_ifs - .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val))); - self - } - - /// Specify this argument is [required] based on multiple conditions. - /// - /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become - /// valid if every one of the specified `arg`'s value equals its corresponding `val`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .required_if_eq_all(&[ - /// ("extra", "val"), - /// ("option", "spec") - /// ]) - /// # ; - /// ``` - /// - /// Setting `Arg::required_if_eq_all(&[(arg, val)])` makes this arg required if all of the `arg`s - /// are used at runtime and every value is equal to its corresponding `val`. If the `arg`'s value is - /// anything other than `val`, this argument isn't required. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_if_eq_all(&[ - /// ("extra", "val"), - /// ("option", "spec") - /// ]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("extra") - /// .takes_value(true) - /// .long("extra")) - /// .arg(Arg::new("option") - /// .takes_value(true) - /// .long("option")) - /// .try_get_matches_from(vec![ - /// "prog", "--option", "spec" - /// ]); - /// - /// assert!(res.is_ok()); // We didn't use --option=spec --extra=val so "cfg" isn't required - /// ``` - /// - /// Setting `Arg::required_if_eq_all(&[(arg, val)])` and having all of the `arg`s used with its - /// value of `val` but *not* using this arg is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .required_if_eq_all(&[ - /// ("extra", "val"), - /// ("option", "spec") - /// ]) - /// .takes_value(true) - /// .long("config")) - /// .arg(Arg::new("extra") - /// .takes_value(true) - /// .long("extra")) - /// .arg(Arg::new("option") - /// .takes_value(true) - /// .long("option")) - /// .try_get_matches_from(vec![ - /// "prog", "--extra", "val", "--option", "spec" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [required]: Arg::required() - #[must_use] - pub fn required_if_eq_all(mut self, ifs: &[(T, &'help str)]) -> Self { - self.r_ifs_all - .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val))); - self - } - - /// Require another argument if this arg was present at runtime and its value equals to `val`. - /// - /// This method takes `value, another_arg` pair. At runtime, clap will check - /// if this arg (`self`) is present and its value equals to `val`. - /// If it does, `another_arg` will be marked as required. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .requires_if("val", "arg") - /// # ; - /// ``` - /// - /// Setting `Arg::requires_if(val, arg)` requires that the `arg` be used at runtime if the - /// defining argument's value is equal to `val`. If the defining argument is anything other than - /// `val`, the other argument isn't required. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires_if("my.cfg", "other") - /// .long("config")) - /// .arg(Arg::new("other")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "some.cfg" - /// ]); - /// - /// assert!(res.is_ok()); // We didn't use --config=my.cfg, so other wasn't required - /// ``` - /// - /// Setting `Arg::requires_if(val, arg)` and setting the value to `val` but *not* supplying - /// `arg` is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires_if("my.cfg", "input") - /// .long("config")) - /// .arg(Arg::new("input")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "my.cfg" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [`Arg::requires(name)`]: Arg::requires() - /// [Conflicting]: Arg::conflicts_with() - /// [override]: Arg::overrides_with() - #[must_use] - pub fn requires_if(mut self, val: &'help str, arg_id: T) -> Self { - self.requires - .push((ArgPredicate::Equals(OsStr::new(val)), arg_id.into())); - self - } - - /// Allows multiple conditional requirements. - /// - /// The requirement will only become valid if this arg's value equals `val`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .requires_ifs(&[ - /// ("val", "arg"), - /// ("other_val", "arg2"), - /// ]) - /// # ; - /// ``` - /// - /// Setting `Arg::requires_ifs(&["val", "arg"])` requires that the `arg` be used at runtime if the - /// defining argument's value is equal to `val`. If the defining argument's value is anything other - /// than `val`, `arg` isn't required. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires_ifs(&[ - /// ("special.conf", "opt"), - /// ("other.conf", "other"), - /// ]) - /// .long("config")) - /// .arg(Arg::new("opt") - /// .long("option") - /// .takes_value(true)) - /// .arg(Arg::new("other")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "special.conf" - /// ]); - /// - /// assert!(res.is_err()); // We used --config=special.conf so --option is required - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [`Arg::requires(name)`]: Arg::requires() - /// [Conflicting]: Arg::conflicts_with() - /// [override]: Arg::overrides_with() - #[must_use] - pub fn requires_ifs(mut self, ifs: &[(&'help str, T)]) -> Self { - self.requires.extend( - ifs.iter() - .map(|(val, arg)| (ArgPredicate::Equals(OsStr::new(*val)), Id::from(arg))), - ); - self - } - - /// Require these arguments names when this one is presen - /// - /// i.e. when using this argument, the following arguments *must* be present. - /// - /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required - /// by default. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .requires_all(&["input", "output"]) - /// # ; - /// ``` - /// - /// Setting `Arg::requires_all(&[arg, arg2])` requires that all the arguments be used at - /// runtime if the defining argument is used. If the defining argument isn't used, the other - /// argument isn't required - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires("input") - /// .long("config")) - /// .arg(Arg::new("input")) - /// .arg(Arg::new("output")) - /// .try_get_matches_from(vec![ - /// "prog" - /// ]); - /// - /// assert!(res.is_ok()); // We didn't use cfg, so input and output weren't required - /// ``` - /// - /// Setting `Arg::requires_all(&[arg, arg2])` and *not* supplying all the arguments is an - /// error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .requires_all(&["input", "output"]) - /// .long("config")) - /// .arg(Arg::new("input")) - /// .arg(Arg::new("output")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "file.conf", "in.txt" - /// ]); - /// - /// assert!(res.is_err()); - /// // We didn't use output - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [Conflicting]: Arg::conflicts_with() - /// [override]: Arg::overrides_with() - #[must_use] - pub fn requires_all(mut self, names: &[T]) -> Self { - self.requires - .extend(names.iter().map(|s| (ArgPredicate::IsPresent, s.into()))); - self - } - - /// This argument is mutually exclusive with the specified argument. - /// - /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules - /// only need to be set for one of the two arguments, they do not need to be set for each. - /// - /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments - /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not - /// need to also do B.conflicts_with(A)) - /// - /// **NOTE:** [`Arg::conflicts_with_all(names)`] allows specifying an argument which conflicts with more than one argument. - /// - /// **NOTE** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .conflicts_with("debug") - /// # ; - /// ``` - /// - /// Setting conflicting argument, and having both arguments present at runtime is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .conflicts_with("debug") - /// .long("config")) - /// .arg(Arg::new("debug") - /// .long("debug")) - /// .try_get_matches_from(vec![ - /// "prog", "--debug", "--config", "file.conf" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict); - /// ``` - /// - /// [`Arg::conflicts_with_all(names)`]: Arg::conflicts_with_all() - /// [`Arg::exclusive(true)`]: Arg::exclusive() - #[must_use] - pub fn conflicts_with(mut self, arg_id: T) -> Self { - self.blacklist.push(arg_id.into()); - self - } - - /// This argument is mutually exclusive with the specified arguments. - /// - /// See [`Arg::conflicts_with`]. - /// - /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules - /// only need to be set for one of the two arguments, they do not need to be set for each. - /// - /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments - /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not need - /// need to also do B.conflicts_with(A)) - /// - /// **NOTE:** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// Arg::new("config") - /// .conflicts_with_all(&["debug", "input"]) - /// # ; - /// ``` - /// - /// Setting conflicting argument, and having any of the arguments present at runtime with a - /// conflicting argument is an error. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("cfg") - /// .takes_value(true) - /// .conflicts_with_all(&["debug", "input"]) - /// .long("config")) - /// .arg(Arg::new("debug") - /// .long("debug")) - /// .arg(Arg::new("input")) - /// .try_get_matches_from(vec![ - /// "prog", "--config", "file.conf", "file.txt" - /// ]); - /// - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict); - /// ``` - /// [`Arg::conflicts_with`]: Arg::conflicts_with() - /// [`Arg::exclusive(true)`]: Arg::exclusive() - #[must_use] - pub fn conflicts_with_all(mut self, names: &[&str]) -> Self { - self.blacklist.extend(names.iter().copied().map(Id::from)); - self - } - - /// Sets an overridable argument. - /// - /// i.e. this argument and the following argument - /// will override each other in POSIX style (whichever argument was specified at runtime - /// **last** "wins") - /// - /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any - /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed - /// - /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with`]. - /// - /// **WARNING:** Positional arguments and options which accept - /// [`Arg::multiple_occurrences`] cannot override themselves (or we - /// would never be able to advance to the next positional). If a positional - /// argument or option with one of the [`Arg::multiple_occurrences`] - /// settings lists itself as an override, it is simply ignored. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, arg}; - /// let m = Command::new("prog") - /// .arg(arg!(-f --flag "some flag") - /// .conflicts_with("debug")) - /// .arg(arg!(-d --debug "other flag")) - /// .arg(arg!(-c --color "third flag") - /// .overrides_with("flag")) - /// .get_matches_from(vec![ - /// "prog", "-f", "-d", "-c"]); - /// // ^~~~~~~~~~~~^~~~~ flag is overridden by color - /// - /// assert!(m.is_present("color")); - /// assert!(m.is_present("debug")); // even though flag conflicts with debug, it's as if flag - /// // was never used because it was overridden with color - /// assert!(!m.is_present("flag")); - /// ``` - /// Care must be taken when using this setting, and having an arg override with itself. This - /// is common practice when supporting things like shell aliases, config files, etc. - /// However, when combined with multiple values, it can get dicy. - /// Here is how clap handles such situations: - /// - /// When a flag overrides itself, it's as if the flag was only ever used once (essentially - /// preventing a "Unexpected multiple usage" error): - /// - /// ```rust - /// # use clap::{Command, arg}; - /// let m = Command::new("posix") - /// .arg(arg!(--flag "some flag").overrides_with("flag")) - /// .get_matches_from(vec!["posix", "--flag", "--flag"]); - /// assert!(m.is_present("flag")); - /// ``` - /// - /// Making an arg [`Arg::multiple_occurrences`] and override itself - /// is essentially meaningless. Therefore clap ignores an override of self - /// if it's a flag and it already accepts multiple occurrences. - /// - /// ``` - /// # use clap::{Command, arg}; - /// let m = Command::new("posix") - /// .arg(arg!(--flag ... "some flag").overrides_with("flag")) - /// .get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]); - /// assert!(m.is_present("flag")); - /// ``` - /// - /// Now notice with options (which *do not* set - /// [`Arg::multiple_occurrences`]), it's as if only the last - /// occurrence happened. - /// - /// ``` - /// # use clap::{Command, arg}; - /// let m = Command::new("posix") - /// .arg(arg!(--opt "some option").overrides_with("opt")) - /// .get_matches_from(vec!["", "--opt=some", "--opt=other"]); - /// assert!(m.is_present("opt")); - /// assert_eq!(m.value_of("opt"), Some("other")); - /// ``` - /// - /// This will also work when [`Arg::multiple_values`] is enabled: - /// - /// ``` - /// # use clap::{Command, Arg}; - /// let m = Command::new("posix") - /// .arg( - /// Arg::new("opt") - /// .long("opt") - /// .takes_value(true) - /// .multiple_values(true) - /// .overrides_with("opt") - /// ) - /// .get_matches_from(vec!["", "--opt", "1", "2", "--opt", "3", "4", "5"]); - /// assert!(m.is_present("opt")); - /// assert_eq!(m.values_of("opt").unwrap().collect::>(), &["3", "4", "5"]); - /// ``` - /// - /// Just like flags, options with [`Arg::multiple_occurrences`] set - /// will ignore the "override self" setting. - /// - /// ``` - /// # use clap::{Command, arg}; - /// let m = Command::new("posix") - /// .arg(arg!(--opt ... "some option") - /// .multiple_values(true) - /// .overrides_with("opt")) - /// .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]); - /// assert!(m.is_present("opt")); - /// assert_eq!(m.values_of("opt").unwrap().collect::>(), &["first", "over", "other", "val"]); - /// ``` - #[must_use] - pub fn overrides_with(mut self, arg_id: T) -> Self { - self.overrides.push(arg_id.into()); - self - } - - /// Sets multiple mutually overridable arguments by name. - /// - /// i.e. this argument and the following argument will override each other in POSIX style - /// (whichever argument was specified at runtime **last** "wins") - /// - /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any - /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed - /// - /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with_all`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, arg}; - /// let m = Command::new("prog") - /// .arg(arg!(-f --flag "some flag") - /// .conflicts_with("color")) - /// .arg(arg!(-d --debug "other flag")) - /// .arg(arg!(-c --color "third flag") - /// .overrides_with_all(&["flag", "debug"])) - /// .get_matches_from(vec![ - /// "prog", "-f", "-d", "-c"]); - /// // ^~~~~~^~~~~~~~~ flag and debug are overridden by color - /// - /// assert!(m.is_present("color")); // even though flag conflicts with color, it's as if flag - /// // and debug were never used because they were overridden - /// // with color - /// assert!(!m.is_present("debug")); - /// assert!(!m.is_present("flag")); - /// ``` - #[must_use] - pub fn overrides_with_all(mut self, names: &[T]) -> Self { - self.overrides.extend(names.iter().map(Id::from)); - self - } -} - -/// # Reflection -impl<'help> Arg<'help> { - /// Get the name of the argument - #[inline] - pub fn get_id(&self) -> &'help str { - self.name - } - - /// Deprecated, replaced with [`Arg::get_id`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Arg::get_id`") - )] - pub fn get_name(&self) -> &'help str { - self.get_id() - } - - /// Get the help specified for this argument, if any - #[inline] - pub fn get_help(&self) -> Option<&'help str> { - self.help - } - - /// Get the long help specified for this argument, if any - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// let arg = Arg::new("foo").long_help("long help"); - /// assert_eq!(Some("long help"), arg.get_long_help()); - /// ``` - /// - #[inline] - pub fn get_long_help(&self) -> Option<&'help str> { - self.long_help - } - - /// Get the help heading specified for this argument, if any - #[inline] - pub fn get_help_heading(&self) -> Option<&'help str> { - self.help_heading.unwrap_or_default() - } - - /// Get the short option name for this argument, if any - #[inline] - pub fn get_short(&self) -> Option { - self.short - } - - /// Get visible short aliases for this argument, if any - #[inline] - pub fn get_visible_short_aliases(&self) -> Option> { - if self.short_aliases.is_empty() { - None - } else { - Some( - self.short_aliases - .iter() - .filter_map(|(c, v)| if *v { Some(c) } else { None }) - .copied() - .collect(), - ) - } - } - - /// Get *all* short aliases for this argument, if any, both visible and hidden. - #[inline] - pub fn get_all_short_aliases(&self) -> Option> { - if self.short_aliases.is_empty() { - None - } else { - Some(self.short_aliases.iter().map(|(s, _)| s).copied().collect()) - } - } - - /// Get the short option name and its visible aliases, if any - #[inline] - pub fn get_short_and_visible_aliases(&self) -> Option> { - let mut shorts = match self.short { - Some(short) => vec![short], - None => return None, - }; - if let Some(aliases) = self.get_visible_short_aliases() { - shorts.extend(aliases); - } - Some(shorts) - } - - /// Get the long option name for this argument, if any - #[inline] - pub fn get_long(&self) -> Option<&'help str> { - self.long - } - - /// Get visible aliases for this argument, if any - #[inline] - pub fn get_visible_aliases(&self) -> Option> { - if self.aliases.is_empty() { - None - } else { - Some( - self.aliases - .iter() - .filter_map(|(s, v)| if *v { Some(s) } else { None }) - .copied() - .collect(), - ) - } - } - - /// Get *all* aliases for this argument, if any, both visible and hidden. - #[inline] - pub fn get_all_aliases(&self) -> Option> { - if self.aliases.is_empty() { - None - } else { - Some(self.aliases.iter().map(|(s, _)| s).copied().collect()) - } - } - - /// Get the long option name and its visible aliases, if any - #[inline] - pub fn get_long_and_visible_aliases(&self) -> Option> { - let mut longs = match self.long { - Some(long) => vec![long], - None => return None, - }; - if let Some(aliases) = self.get_visible_aliases() { - longs.extend(aliases); - } - Some(longs) - } - - /// Deprecated, replaced with [`Arg::get_value_parser().possible_values()`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with `Arg::get_value_parser().possible_values()`" - ) - )] - pub fn get_possible_values(&self) -> Option<&[PossibleValue<'help>]> { - if self.possible_vals.is_empty() { - None - } else { - Some(&self.possible_vals) - } - } - - pub(crate) fn get_possible_values2(&self) -> Vec> { - #![allow(deprecated)] - if !self.is_takes_value_set() { - vec![] - } else if let Some(pvs) = self.get_possible_values() { - // Check old first in case the user explicitly set possible values and the derive inferred - // a `ValueParser` with some. - pvs.to_vec() - } else { - self.get_value_parser() - .possible_values() - .map(|pvs| pvs.collect()) - .unwrap_or_default() - } - } - - /// Get the names of values for this argument. - #[inline] - pub fn get_value_names(&self) -> Option<&[&'help str]> { - if self.val_names.is_empty() { - None - } else { - Some(&self.val_names) - } - } - - /// Get the number of values for this argument. - #[inline] - pub fn get_num_vals(&self) -> Option { - self.num_vals - } - - /// Get the delimiter between multiple values - #[inline] - pub fn get_value_delimiter(&self) -> Option { - self.val_delim - } - - /// Get the index of this argument, if any - #[inline] - pub fn get_index(&self) -> Option { - self.index - } - - /// Get the value hint of this argument - pub fn get_value_hint(&self) -> ValueHint { - self.value_hint.unwrap_or_else(|| { - if self.is_takes_value_set() { - let type_id = self.get_value_parser().type_id(); - if type_id == crate::parser::AnyValueId::of::() { - ValueHint::AnyPath - } else { - ValueHint::default() - } - } else { - ValueHint::default() - } - }) - } - - /// Deprecated, replaced with [`Arg::is_global_set`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Arg::is_global_set`") - )] - pub fn get_global(&self) -> bool { - self.is_global_set() - } - - /// Get the environment variable name specified for this argument, if any - /// - /// # Examples - /// - /// ```rust - /// # use std::ffi::OsStr; - /// # use clap::Arg; - /// let arg = Arg::new("foo").env("ENVIRONMENT"); - /// assert_eq!(Some(OsStr::new("ENVIRONMENT")), arg.get_env()); - /// ``` - #[cfg(feature = "env")] - pub fn get_env(&self) -> Option<&OsStr> { - self.env.as_ref().map(|x| x.0) - } - - /// Get the default values specified for this argument, if any - /// - /// # Examples - /// - /// ```rust - /// # use clap::Arg; - /// let arg = Arg::new("foo").default_value("default value"); - /// assert_eq!(&["default value"], arg.get_default_values()); - /// ``` - pub fn get_default_values(&self) -> &[&OsStr] { - &self.default_vals - } - - /// Checks whether this argument is a positional or not. - /// - /// # Examples - /// - /// ``` - /// # use clap::Arg; - /// let arg = Arg::new("foo"); - /// assert_eq!(true, arg.is_positional()); - /// - /// let arg = Arg::new("foo").long("foo"); - /// assert_eq!(false, arg.is_positional()); - /// ``` - pub fn is_positional(&self) -> bool { - self.long.is_none() && self.short.is_none() - } - - /// Reports whether [`Arg::required`] is set - pub fn is_required_set(&self) -> bool { - self.is_set(ArgSettings::Required) - } - - /// Report whether [`Arg::multiple_values`] is set - pub fn is_multiple_values_set(&self) -> bool { - self.is_set(ArgSettings::MultipleValues) - } - - /// [`Arg::multiple_occurrences`] is going away ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "`multiple_occurrences` away (Issue #3772)") - )] - pub fn is_multiple_occurrences_set(&self) -> bool { - self.is_set(ArgSettings::MultipleOccurrences) - } - - /// Report whether [`Arg::is_takes_value_set`] is set - pub fn is_takes_value_set(&self) -> bool { - self.is_set(ArgSettings::TakesValue) - } - - /// Report whether [`Arg::allow_hyphen_values`] is set - pub fn is_allow_hyphen_values_set(&self) -> bool { - self.is_set(ArgSettings::AllowHyphenValues) - } - - /// Deprecated, replaced with [`Arg::get_value_parser()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::get_value_parser()`") - )] - pub fn is_forbid_empty_values_set(&self) -> bool { - self.is_set(ArgSettings::ForbidEmptyValues) - } - - /// Deprecated, replaced with [`Arg::get_value_parser()` - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::get_value_parser()`") - )] - pub fn is_allow_invalid_utf8_set(&self) -> bool { - self.is_set(ArgSettings::AllowInvalidUtf8) - } - - /// Behavior when parsing the argument - pub fn get_action(&self) -> &super::ArgAction { - const DEFAULT: super::ArgAction = super::ArgAction::StoreValue; - self.action.as_ref().unwrap_or(&DEFAULT) - } - - /// Configured parser for argument values - /// - /// # Example - /// - /// ```rust - /// let cmd = clap::Command::new("raw") - /// .arg( - /// clap::Arg::new("port") - /// .value_parser(clap::value_parser!(usize)) - /// ); - /// let value_parser = cmd.get_arguments() - /// .find(|a| a.get_id() == "port").unwrap() - /// .get_value_parser(); - /// println!("{:?}", value_parser); - /// ``` - pub fn get_value_parser(&self) -> &super::ValueParser { - if let Some(value_parser) = self.value_parser.as_ref() { - value_parser - } else if self.is_allow_invalid_utf8_set() { - static DEFAULT: super::ValueParser = super::ValueParser::os_string(); - &DEFAULT - } else { - static DEFAULT: super::ValueParser = super::ValueParser::string(); - &DEFAULT - } - } - - /// Report whether [`Arg::global`] is set - pub fn is_global_set(&self) -> bool { - self.is_set(ArgSettings::Global) - } - - /// Report whether [`Arg::next_line_help`] is set - pub fn is_next_line_help_set(&self) -> bool { - self.is_set(ArgSettings::NextLineHelp) - } - - /// Report whether [`Arg::hide`] is set - pub fn is_hide_set(&self) -> bool { - self.is_set(ArgSettings::Hidden) - } - - /// Report whether [`Arg::hide_default_value`] is set - pub fn is_hide_default_value_set(&self) -> bool { - self.is_set(ArgSettings::HideDefaultValue) - } - - /// Report whether [`Arg::hide_possible_values`] is set - pub fn is_hide_possible_values_set(&self) -> bool { - self.is_set(ArgSettings::HidePossibleValues) - } - - /// Report whether [`Arg::hide_env`] is set - #[cfg(feature = "env")] - pub fn is_hide_env_set(&self) -> bool { - self.is_set(ArgSettings::HideEnv) - } - - /// Report whether [`Arg::hide_env_values`] is set - #[cfg(feature = "env")] - pub fn is_hide_env_values_set(&self) -> bool { - self.is_set(ArgSettings::HideEnvValues) - } - - /// Report whether [`Arg::hide_short_help`] is set - pub fn is_hide_short_help_set(&self) -> bool { - self.is_set(ArgSettings::HiddenShortHelp) - } - - /// Report whether [`Arg::hide_long_help`] is set - pub fn is_hide_long_help_set(&self) -> bool { - self.is_set(ArgSettings::HiddenLongHelp) - } - - /// Report whether [`Arg::use_value_delimiter`] is set - pub fn is_use_value_delimiter_set(&self) -> bool { - self.is_set(ArgSettings::UseValueDelimiter) - } - - /// Report whether [`Arg::require_value_delimiter`] is set - pub fn is_require_value_delimiter_set(&self) -> bool { - self.is_set(ArgSettings::RequireDelimiter) - } - - /// Report whether [`Arg::require_equals`] is set - pub fn is_require_equals_set(&self) -> bool { - self.is_set(ArgSettings::RequireEquals) - } - - /// Reports whether [`Arg::exclusive`] is set - pub fn is_exclusive_set(&self) -> bool { - self.is_set(ArgSettings::Exclusive) - } - - /// Reports whether [`Arg::last`] is set - pub fn is_last_set(&self) -> bool { - self.is_set(ArgSettings::Last) - } - - /// Reports whether [`Arg::ignore_case`] is set - pub fn is_ignore_case_set(&self) -> bool { - self.is_set(ArgSettings::IgnoreCase) - } -} - -/// # Deprecated -impl<'help> Arg<'help> { - /// Deprecated, replaced with [`Arg::new`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::new`") - )] - #[doc(hidden)] - pub fn with_name>(n: S) -> Self { - Self::new(n) - } - - /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? - #[cfg(feature = "yaml")] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" - ) - )] - #[doc(hidden)] - pub fn from_yaml(y: &'help Yaml) -> Self { - #![allow(deprecated)] - let yaml_file_hash = y.as_hash().expect("YAML file must be a hash"); - // We WANT this to panic on error...so expect() is good. - let (name_yaml, yaml) = yaml_file_hash - .iter() - .next() - .expect("There must be one arg in the YAML file"); - let name_str = name_yaml.as_str().expect("Arg name must be a string"); - let mut a = Arg::new(name_str); - - for (k, v) in yaml.as_hash().expect("Arg must be a hash") { - a = match k.as_str().expect("Arg fields must be strings") { - "short" => yaml_to_char!(a, v, short), - "long" => yaml_to_str!(a, v, long), - "aliases" => yaml_vec_or_str!(a, v, alias), - "help" => yaml_to_str!(a, v, help), - "long_help" => yaml_to_str!(a, v, long_help), - "required" => yaml_to_bool!(a, v, required), - "required_if" => yaml_tuple2!(a, v, required_if_eq), - "required_ifs" => yaml_tuple2!(a, v, required_if_eq), - "takes_value" => yaml_to_bool!(a, v, takes_value), - "index" => yaml_to_usize!(a, v, index), - "global" => yaml_to_bool!(a, v, global), - "multiple" => yaml_to_bool!(a, v, multiple), - "hidden" => yaml_to_bool!(a, v, hide), - "next_line_help" => yaml_to_bool!(a, v, next_line_help), - "group" => yaml_to_str!(a, v, group), - "number_of_values" => yaml_to_usize!(a, v, number_of_values), - "max_values" => yaml_to_usize!(a, v, max_values), - "min_values" => yaml_to_usize!(a, v, min_values), - "value_name" => yaml_to_str!(a, v, value_name), - "use_delimiter" => yaml_to_bool!(a, v, use_delimiter), - "allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values), - "last" => yaml_to_bool!(a, v, last), - "require_delimiter" => yaml_to_bool!(a, v, require_delimiter), - "value_delimiter" => yaml_to_char!(a, v, value_delimiter), - "required_unless" => yaml_to_str!(a, v, required_unless_present), - "display_order" => yaml_to_usize!(a, v, display_order), - "default_value" => yaml_to_str!(a, v, default_value), - "default_value_if" => yaml_tuple3!(a, v, default_value_if), - "default_value_ifs" => yaml_tuple3!(a, v, default_value_if), - #[cfg(feature = "env")] - "env" => yaml_to_str!(a, v, env), - "value_names" => yaml_vec_or_str!(a, v, value_name), - "groups" => yaml_vec_or_str!(a, v, group), - "requires" => yaml_vec_or_str!(a, v, requires), - "requires_if" => yaml_tuple2!(a, v, requires_if), - "requires_ifs" => yaml_tuple2!(a, v, requires_if), - "conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with), - "overrides_with" => yaml_to_str!(a, v, overrides_with), - "possible_values" => yaml_vec_or_str!(a, v, possible_value), - "case_insensitive" => yaml_to_bool!(a, v, ignore_case), - "required_unless_one" => yaml_vec!(a, v, required_unless_present_any), - "required_unless_all" => yaml_vec!(a, v, required_unless_present_all), - s => { - panic!( - "Unknown setting '{}' in YAML file for arg '{}'", - s, name_str - ) - } - } - } - - a - } - - /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!]. - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!") - )] - #[doc(hidden)] - pub fn from_usage(u: &'help str) -> Self { - UsageParser::from_usage(u).parse() - } - - /// Deprecated, replaced with [`Arg::required_unless_present`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::required_unless_present`") - )] - #[doc(hidden)] - #[must_use] - pub fn required_unless(self, arg_id: T) -> Self { - self.required_unless_present(arg_id) - } - - /// Deprecated, replaced with [`Arg::required_unless_present_all`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Arg::required_unless_present_all`" - ) - )] - #[doc(hidden)] - #[must_use] - pub fn required_unless_all(self, names: I) -> Self - where - I: IntoIterator, - T: Key, - { - self.required_unless_present_all(names) - } - - /// Deprecated, replaced with [`Arg::required_unless_present_any`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Arg::required_unless_present_any`" - ) - )] - #[doc(hidden)] - #[must_use] - pub fn required_unless_one(self, names: I) -> Self - where - I: IntoIterator, - T: Key, - { - self.required_unless_present_any(names) - } - - /// Deprecated, replaced with [`Arg::required_if_eq`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq`") - )] - #[doc(hidden)] - #[must_use] - pub fn required_if(self, arg_id: T, val: &'help str) -> Self { - self.required_if_eq(arg_id, val) - } - - /// Deprecated, replaced with [`Arg::required_if_eq_any`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq_any`") - )] - #[doc(hidden)] - #[must_use] - pub fn required_ifs(self, ifs: &[(T, &'help str)]) -> Self { - self.required_if_eq_any(ifs) - } - - /// Deprecated, replaced with [`Arg::hide`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::hide`") - )] - #[doc(hidden)] - #[inline] - #[must_use] - pub fn hidden(self, yes: bool) -> Self { - self.hide(yes) - } - - /// Deprecated, replaced with [`Arg::ignore_case`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::ignore_case`") - )] - #[doc(hidden)] - #[inline] - #[must_use] - pub fn case_insensitive(self, yes: bool) -> Self { - self.ignore_case(yes) - } - - /// Deprecated, replaced with [`Arg::forbid_empty_values`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::forbid_empty_values`") - )] - #[doc(hidden)] - #[must_use] - pub fn empty_values(self, yes: bool) -> Self { - self.forbid_empty_values(!yes) - } - - /// Deprecated, replaced with [`Arg::multiple_occurrences`] (most likely what you want) and - /// [`Arg::multiple_values`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Split into `Arg::multiple_occurrences` (most likely what you want) and `Arg::multiple_values`" - ) - )] - #[doc(hidden)] - #[must_use] - pub fn multiple(self, yes: bool) -> Self { - self.multiple_occurrences(yes).multiple_values(yes) - } - - /// Deprecated, replaced with [`Arg::hide_short_help`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::hide_short_help`") - )] - #[doc(hidden)] - #[inline] - #[must_use] - pub fn hidden_short_help(self, yes: bool) -> Self { - self.hide_short_help(yes) - } - - /// Deprecated, replaced with [`Arg::hide_long_help`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::hide_long_help`") - )] - #[doc(hidden)] - #[inline] - #[must_use] - pub fn hidden_long_help(self, yes: bool) -> Self { - self.hide_long_help(yes) - } - - /// Deprecated, replaced with [`Arg::setting`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::setting`") - )] - #[doc(hidden)] - #[must_use] - pub fn set(self, s: ArgSettings) -> Self { - self.setting(s) - } - - /// Deprecated, replaced with [`Arg::unset_setting`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Arg::unset_setting`") - )] - #[doc(hidden)] - #[must_use] - pub fn unset(self, s: ArgSettings) -> Self { - self.unset_setting(s) - } -} - -/// # Internally used only -impl<'help> Arg<'help> { - pub(crate) fn _build(&mut self) { - if self.is_positional() { - self.settings.set(ArgSettings::TakesValue); - } - if let Some(action) = self.action.as_ref() { - if let Some(default_value) = action.default_value() { - if self.default_vals.is_empty() { - self.default_vals = vec![default_value]; - } - } - if action.takes_values() { - self.settings.set(ArgSettings::TakesValue); - } else { - self.settings.unset(ArgSettings::TakesValue); - } - match action { - ArgAction::StoreValue - | ArgAction::IncOccurrence - | ArgAction::Help - | ArgAction::Version => {} - ArgAction::Set - | ArgAction::Append - | ArgAction::SetTrue - | ArgAction::SetFalse - | ArgAction::Count => { - if !self.is_positional() { - self.settings.set(ArgSettings::MultipleOccurrences); - } - } - } - } - - if self.value_parser.is_none() { - if let Some(default) = self.action.as_ref().and_then(|a| a.default_value_parser()) { - self.value_parser = Some(default); - } else if self.is_allow_invalid_utf8_set() { - self.value_parser = Some(super::ValueParser::os_string()); - } else { - self.value_parser = Some(super::ValueParser::string()); - } - } - - if (self.is_use_value_delimiter_set() || self.is_require_value_delimiter_set()) - && self.val_delim.is_none() - { - self.val_delim = Some(','); - } - - let val_names_len = self.val_names.len(); - - if val_names_len > 1 { - self.settings.set(ArgSettings::MultipleValues); - - if self.num_vals.is_none() { - self.num_vals = Some(val_names_len); - } - } - - let self_id = self.id.clone(); - if self.is_positional() || self.is_multiple_occurrences_set() { - // Remove self-overrides where they don't make sense. - // - // We can evaluate switching this to a debug assert at a later time (though it will - // require changing propagation of `AllArgsOverrideSelf`). Being conservative for now - // due to where we are at in the release. - self.overrides.retain(|e| *e != self_id); - } - } - - pub(crate) fn generated(mut self) -> Self { - self.provider = ArgProvider::Generated; - self - } - - pub(crate) fn longest_filter(&self) -> bool { - self.is_takes_value_set() || self.long.is_some() || self.short.is_none() - } - - // Used for positionals when printing - pub(crate) fn multiple_str(&self) -> &str { - let mult_vals = self.val_names.len() > 1; - if (self.is_multiple_values_set() || self.is_multiple_occurrences_set()) && !mult_vals { - "..." - } else { - "" - } - } - - // Used for positionals when printing - pub(crate) fn name_no_brackets(&self) -> Cow { - debug!("Arg::name_no_brackets:{}", self.name); - let delim = if self.is_require_value_delimiter_set() { - self.val_delim.expect(INTERNAL_ERROR_MSG) - } else { - ' ' - } - .to_string(); - if !self.val_names.is_empty() { - debug!("Arg::name_no_brackets: val_names={:#?}", self.val_names); - - if self.val_names.len() > 1 { - Cow::Owned( - self.val_names - .iter() - .map(|n| format!("<{}>", n)) - .collect::>() - .join(&*delim), - ) - } else { - Cow::Borrowed(self.val_names.get(0).expect(INTERNAL_ERROR_MSG)) - } - } else { - debug!("Arg::name_no_brackets: just name"); - Cow::Borrowed(self.name) - } - } - - /// Either multiple values or occurrences - pub(crate) fn is_multiple(&self) -> bool { - self.is_multiple_values_set() | self.is_multiple_occurrences_set() - } - - pub(crate) fn get_display_order(&self) -> usize { - self.disp_ord.get_explicit() - } -} - -impl<'help> From<&'_ Arg<'help>> for Arg<'help> { - fn from(a: &Arg<'help>) -> Self { - a.clone() - } -} - -impl<'help> PartialEq for Arg<'help> { - fn eq(&self, other: &Arg<'help>) -> bool { - self.name == other.name - } -} - -impl<'help> PartialOrd for Arg<'help> { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl<'help> Ord for Arg<'help> { - fn cmp(&self, other: &Arg) -> Ordering { - self.name.cmp(other.name) - } -} - -impl<'help> Eq for Arg<'help> {} - -impl<'help> Display for Arg<'help> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - // Write the name such --long or -l - if let Some(l) = self.long { - write!(f, "--{}", l)?; - } else if let Some(s) = self.short { - write!(f, "-{}", s)?; - } - let mut need_closing_bracket = false; - if !self.is_positional() && self.is_takes_value_set() { - let is_optional_val = self.min_vals == Some(0); - let sep = if self.is_require_equals_set() { - if is_optional_val { - need_closing_bracket = true; - "[=" - } else { - "=" - } - } else if is_optional_val { - need_closing_bracket = true; - " [" - } else { - " " - }; - f.write_str(sep)?; - } - if self.is_takes_value_set() || self.is_positional() { - display_arg_val(self, |s, _| f.write_str(s))?; - } - if need_closing_bracket { - f.write_str("]")?; - } - - Ok(()) - } -} - -impl<'help> fmt::Debug for Arg<'help> { - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - let mut ds = f.debug_struct("Arg"); - - #[allow(unused_mut)] - let mut ds = ds - .field("id", &self.id) - .field("provider", &self.provider) - .field("name", &self.name) - .field("help", &self.help) - .field("long_help", &self.long_help) - .field("action", &self.action) - .field("value_parser", &self.value_parser) - .field("blacklist", &self.blacklist) - .field("settings", &self.settings) - .field("overrides", &self.overrides) - .field("groups", &self.groups) - .field("requires", &self.requires) - .field("r_ifs", &self.r_ifs) - .field("r_unless", &self.r_unless) - .field("short", &self.short) - .field("long", &self.long) - .field("aliases", &self.aliases) - .field("short_aliases", &self.short_aliases) - .field("disp_ord", &self.disp_ord) - .field("possible_vals", &self.possible_vals) - .field("val_names", &self.val_names) - .field("num_vals", &self.num_vals) - .field("max_vals", &self.max_vals) - .field("min_vals", &self.min_vals) - .field( - "validator", - &self.validator.as_ref().map_or("None", |_| "Some(FnMut)"), - ) - .field( - "validator_os", - &self.validator_os.as_ref().map_or("None", |_| "Some(FnMut)"), - ) - .field("val_delim", &self.val_delim) - .field("default_vals", &self.default_vals) - .field("default_vals_ifs", &self.default_vals_ifs) - .field("terminator", &self.terminator) - .field("index", &self.index) - .field("help_heading", &self.help_heading) - .field("value_hint", &self.value_hint) - .field("default_missing_vals", &self.default_missing_vals); - - #[cfg(feature = "env")] - { - ds = ds.field("env", &self.env); - } - - ds.finish() - } -} - -type Validator<'a> = dyn FnMut(&str) -> Result<(), Box> + Send + 'a; -type ValidatorOs<'a> = dyn FnMut(&OsStr) -> Result<(), Box> + Send + 'a; - -#[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) enum ArgProvider { - Generated, - GeneratedMutated, - User, -} - -impl Default for ArgProvider { - fn default() -> Self { - ArgProvider::User - } -} - -/// Write the values such as -pub(crate) fn display_arg_val(arg: &Arg, mut write: F) -> Result<(), E> -where - F: FnMut(&str, bool) -> Result, -{ - let mult_val = arg.is_multiple_values_set(); - let mult_occ = arg.is_multiple_occurrences_set(); - let delim = if arg.is_require_value_delimiter_set() { - arg.val_delim.expect(INTERNAL_ERROR_MSG) - } else { - ' ' - } - .to_string(); - if !arg.val_names.is_empty() { - // If have val_name. - match (arg.val_names.len(), arg.num_vals) { - (1, Some(num_vals)) => { - // If single value name with multiple num_of_vals, display all - // the values with the single value name. - let arg_name = format!("<{}>", arg.val_names.get(0).unwrap()); - for n in 1..=num_vals { - write(&arg_name, true)?; - if n != num_vals { - write(&delim, false)?; - } - } - } - (num_val_names, _) => { - // If multiple value names, display them sequentially(ignore num of vals). - let mut it = arg.val_names.iter().peekable(); - while let Some(val) = it.next() { - write(&format!("<{}>", val), true)?; - if it.peek().is_some() { - write(&delim, false)?; - } - } - if (num_val_names == 1 && mult_val) - || (arg.is_positional() && mult_occ) - || num_val_names < arg.num_vals.unwrap_or(0) - { - write("...", true)?; - } - } - } - } else if let Some(num_vals) = arg.num_vals { - // If number_of_values is specified, display the value multiple times. - let arg_name = format!("<{}>", arg.name); - for n in 1..=num_vals { - write(&arg_name, true)?; - if n != num_vals { - write(&delim, false)?; - } - } - } else if arg.is_positional() { - // Value of positional argument with no num_vals and val_names. - write(&format!("<{}>", arg.name), true)?; - - if mult_val || mult_occ { - write("...", true)?; - } - } else { - // value of flag argument with no num_vals and val_names. - write(&format!("<{}>", arg.name), true)?; - if mult_val { - write("...", true)?; - } - } - Ok(()) -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) enum DisplayOrder { - None, - Implicit(usize), - Explicit(usize), -} - -impl DisplayOrder { - pub(crate) fn set_explicit(&mut self, explicit: usize) { - *self = Self::Explicit(explicit) - } - - pub(crate) fn set_implicit(&mut self, implicit: usize) { - *self = (*self).max(Self::Implicit(implicit)) - } - - pub(crate) fn make_explicit(&mut self) { - match *self { - Self::None | Self::Explicit(_) => {} - Self::Implicit(disp) => self.set_explicit(disp), - } - } - - pub(crate) fn get_explicit(self) -> usize { - match self { - Self::None | Self::Implicit(_) => 999, - Self::Explicit(disp) => disp, - } - } -} - -impl Default for DisplayOrder { - fn default() -> Self { - Self::None - } -} - -// Flags -#[cfg(test)] -mod test { - use super::Arg; - - #[test] - fn flag_display() { - let mut f = Arg::new("flg").multiple_occurrences(true); - f.long = Some("flag"); - - assert_eq!(f.to_string(), "--flag"); - - let mut f2 = Arg::new("flg"); - f2.short = Some('f'); - - assert_eq!(f2.to_string(), "-f"); - } - - #[test] - fn flag_display_single_alias() { - let mut f = Arg::new("flg"); - f.long = Some("flag"); - f.aliases = vec![("als", true)]; - - assert_eq!(f.to_string(), "--flag") - } - - #[test] - fn flag_display_multiple_aliases() { - let mut f = Arg::new("flg"); - f.short = Some('f'); - f.aliases = vec![ - ("alias_not_visible", false), - ("f2", true), - ("f3", true), - ("f4", true), - ]; - assert_eq!(f.to_string(), "-f"); - } - - #[test] - fn flag_display_single_short_alias() { - let mut f = Arg::new("flg"); - f.short = Some('a'); - f.short_aliases = vec![('b', true)]; - - assert_eq!(f.to_string(), "-a") - } - - #[test] - fn flag_display_multiple_short_aliases() { - let mut f = Arg::new("flg"); - f.short = Some('a'); - f.short_aliases = vec![('b', false), ('c', true), ('d', true), ('e', true)]; - assert_eq!(f.to_string(), "-a"); - } - - // Options - - #[test] - fn option_display_multiple_occurrences() { - let o = Arg::new("opt") - .long("option") - .takes_value(true) - .multiple_occurrences(true); - - assert_eq!(o.to_string(), "--option "); - } - - #[test] - fn option_display_multiple_values() { - let o = Arg::new("opt") - .long("option") - .takes_value(true) - .multiple_values(true); - - assert_eq!(o.to_string(), "--option ..."); - } - - #[test] - fn option_display2() { - let o2 = Arg::new("opt").short('o').value_names(&["file", "name"]); - - assert_eq!(o2.to_string(), "-o "); - } - - #[test] - fn option_display3() { - let o2 = Arg::new("opt") - .short('o') - .takes_value(true) - .multiple_values(true) - .value_names(&["file", "name"]); - - assert_eq!(o2.to_string(), "-o "); - } - - #[test] - fn option_display_single_alias() { - let o = Arg::new("opt") - .takes_value(true) - .long("option") - .visible_alias("als"); - - assert_eq!(o.to_string(), "--option "); - } - - #[test] - fn option_display_multiple_aliases() { - let o = Arg::new("opt") - .long("option") - .takes_value(true) - .visible_aliases(&["als2", "als3", "als4"]) - .alias("als_not_visible"); - - assert_eq!(o.to_string(), "--option "); - } - - #[test] - fn option_display_single_short_alias() { - let o = Arg::new("opt") - .takes_value(true) - .short('a') - .visible_short_alias('b'); - - assert_eq!(o.to_string(), "-a "); - } - - #[test] - fn option_display_multiple_short_aliases() { - let o = Arg::new("opt") - .short('a') - .takes_value(true) - .visible_short_aliases(&['b', 'c', 'd']) - .short_alias('e'); - - assert_eq!(o.to_string(), "-a "); - } - - // Positionals - - #[test] - fn positional_display_multiple_values() { - let p = Arg::new("pos") - .index(1) - .takes_value(true) - .multiple_values(true); - - assert_eq!(p.to_string(), "..."); - } - - #[test] - fn positional_display_multiple_occurrences() { - let p = Arg::new("pos") - .index(1) - .takes_value(true) - .multiple_occurrences(true); - - assert_eq!(p.to_string(), "..."); - } - - #[test] - fn positional_display_required() { - let p2 = Arg::new("pos").index(1).required(true); - - assert_eq!(p2.to_string(), ""); - } - - #[test] - fn positional_display_val_names() { - let p2 = Arg::new("pos").index(1).value_names(&["file1", "file2"]); - - assert_eq!(p2.to_string(), " "); - } - - #[test] - fn positional_display_val_names_req() { - let p2 = Arg::new("pos") - .index(1) - .required(true) - .value_names(&["file1", "file2"]); - - assert_eq!(p2.to_string(), " "); - } -} diff --git a/vendor/clap/src/builder/arg_group.rs b/vendor/clap/src/builder/arg_group.rs deleted file mode 100644 index 0fe317109..000000000 --- a/vendor/clap/src/builder/arg_group.rs +++ /dev/null @@ -1,633 +0,0 @@ -// Internal -use crate::util::{Id, Key}; - -#[cfg(feature = "yaml")] -use yaml_rust::Yaml; - -/// Family of related [arguments]. -/// -/// By placing arguments in a logical group, you can create easier requirement and -/// exclusion rules instead of having to list each argument individually, or when you want a rule -/// to apply "any but not all" arguments. -/// -/// For instance, you can make an entire `ArgGroup` required. If [`ArgGroup::multiple(true)`] is -/// set, this means that at least one argument from that group must be present. If -/// [`ArgGroup::multiple(false)`] is set (the default), one and *only* one must be present. -/// -/// You can also do things such as name an entire `ArgGroup` as a [conflict] or [requirement] for -/// another argument, meaning any of the arguments that belong to that group will cause a failure -/// if present, or must be present respectively. -/// -/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be -/// present out of a given set. Imagine that you had multiple arguments, and you want one of them -/// to be required, but making all of them required isn't feasible because perhaps they conflict -/// with each other. For example, lets say that you were building an application where one could -/// set a given version number by supplying a string with an option argument, i.e. -/// `--set-ver v1.2.3`, you also wanted to support automatically using a previous version number -/// and simply incrementing one of the three numbers. So you create three flags `--major`, -/// `--minor`, and `--patch`. All of these arguments shouldn't be used at one time but you want to -/// specify that *at least one* of them is used. For this, you can create a group. -/// -/// Finally, you may use `ArgGroup`s to pull a value from a group of arguments when you don't care -/// exactly which argument was actually used at runtime. -/// -/// # Examples -/// -/// The following example demonstrates using an `ArgGroup` to ensure that one, and only one, of -/// the arguments from the specified group is present at runtime. -/// -/// ```rust -/// # use clap::{Command, arg, ArgGroup, ErrorKind}; -/// let result = Command::new("cmd") -/// .arg(arg!(--"set-ver" "set the version manually").required(false)) -/// .arg(arg!(--major "auto increase major")) -/// .arg(arg!(--minor "auto increase minor")) -/// .arg(arg!(--patch "auto increase patch")) -/// .group(ArgGroup::new("vers") -/// .args(&["set-ver", "major", "minor", "patch"]) -/// .required(true)) -/// .try_get_matches_from(vec!["cmd", "--major", "--patch"]); -/// // Because we used two args in the group it's an error -/// assert!(result.is_err()); -/// let err = result.unwrap_err(); -/// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); -/// ``` -/// This next example shows a passing parse of the same scenario -/// -/// ```rust -/// # use clap::{Command, arg, ArgGroup}; -/// let result = Command::new("cmd") -/// .arg(arg!(--"set-ver" "set the version manually").required(false)) -/// .arg(arg!(--major "auto increase major")) -/// .arg(arg!(--minor "auto increase minor")) -/// .arg(arg!(--patch "auto increase patch")) -/// .group(ArgGroup::new("vers") -/// .args(&["set-ver", "major", "minor","patch"]) -/// .required(true)) -/// .try_get_matches_from(vec!["cmd", "--major"]); -/// assert!(result.is_ok()); -/// let matches = result.unwrap(); -/// // We may not know which of the args was used, so we can test for the group... -/// assert!(matches.contains_id("vers")); -/// // we could also alternatively check each arg individually (not shown here) -/// ``` -/// [`ArgGroup::multiple(true)`]: ArgGroup::multiple() -/// -/// [`ArgGroup::multiple(false)`]: ArgGroup::multiple() -/// [arguments]: crate::Arg -/// [conflict]: crate::Arg::conflicts_with() -/// [requirement]: crate::Arg::requires() -#[derive(Default, Debug, PartialEq, Eq)] -pub struct ArgGroup<'help> { - pub(crate) id: Id, - pub(crate) name: &'help str, - pub(crate) args: Vec, - pub(crate) required: bool, - pub(crate) requires: Vec, - pub(crate) conflicts: Vec, - pub(crate) multiple: bool, -} - -impl<'help> ArgGroup<'help> { - pub(crate) fn with_id(id: Id) -> Self { - ArgGroup { - id, - ..ArgGroup::default() - } - } - - /// Create a `ArgGroup` using a unique name. - /// - /// The name will be used to get values from the group or refer to the group inside of conflict - /// and requirement rules. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ArgGroup}; - /// ArgGroup::new("config") - /// # ; - /// ``` - pub fn new>(n: S) -> Self { - ArgGroup::default().id(n) - } - - /// Sets the group name. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ArgGroup}; - /// ArgGroup::default().name("config") - /// # ; - /// ``` - #[must_use] - pub fn id>(mut self, n: S) -> Self { - self.name = n.into(); - self.id = Id::from(self.name); - self - } - - /// Deprecated, replaced with [`ArgGroup::id`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `ArgGroup::id`") - )] - pub fn name>(self, n: S) -> Self { - self.id(n) - } - - /// Adds an [argument] to this group by name - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .group(ArgGroup::new("req_flags") - /// .arg("flag") - /// .arg("color")) - /// .get_matches_from(vec!["myprog", "-f"]); - /// // maybe we don't know which of the two flags was used... - /// assert!(m.contains_id("req_flags")); - /// // but we can also check individually if needed - /// assert!(m.contains_id("flag")); - /// ``` - /// [argument]: crate::Arg - #[must_use] - pub fn arg(mut self, arg_id: T) -> Self { - self.args.push(arg_id.into()); - self - } - - /// Adds multiple [arguments] to this group by name - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"])) - /// .get_matches_from(vec!["myprog", "-f"]); - /// // maybe we don't know which of the two flags was used... - /// assert!(m.contains_id("req_flags")); - /// // but we can also check individually if needed - /// assert!(m.contains_id("flag")); - /// ``` - /// [arguments]: crate::Arg - #[must_use] - pub fn args(mut self, ns: &[T]) -> Self { - for n in ns { - self = self.arg(n); - } - self - } - - /// Allows more than one of the [`Arg`]s in this group to be used. (Default: `false`) - /// - /// # Examples - /// - /// Notice in this example we use *both* the `-f` and `-c` flags which are both part of the - /// group - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"]) - /// .multiple(true)) - /// .get_matches_from(vec!["myprog", "-f", "-c"]); - /// // maybe we don't know which of the two flags was used... - /// assert!(m.contains_id("req_flags")); - /// ``` - /// In this next example, we show the default behavior (i.e. `multiple(false)) which will throw - /// an error if more than one of the args in the group was used. - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; - /// let result = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"])) - /// .try_get_matches_from(vec!["myprog", "-f", "-c"]); - /// // Because we used both args in the group it's an error - /// assert!(result.is_err()); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); - /// ``` - /// - /// [`Arg`]: crate::Arg - #[inline] - #[must_use] - pub fn multiple(mut self, yes: bool) -> Self { - self.multiple = yes; - self - } - - /// Require an argument from the group to be present when parsing. - /// - /// This is unless conflicting with another argument. A required group will be displayed in - /// the usage string of the application in the format ``. - /// - /// **NOTE:** This setting only applies to the current [`Command`] / [`Subcommand`]s, and not - /// globally. - /// - /// **NOTE:** By default, [`ArgGroup::multiple`] is set to `false` which when combined with - /// `ArgGroup::required(true)` states, "One and *only one* arg must be used from this group. - /// Use of more than one arg is an error." Vice setting `ArgGroup::multiple(true)` which - /// states, '*At least* one arg from this group must be used. Using multiple is OK." - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; - /// let result = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"]) - /// .required(true)) - /// .try_get_matches_from(vec!["myprog"]); - /// // Because we didn't use any of the args in the group, it's an error - /// assert!(result.is_err()); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// - /// [`Subcommand`]: crate::Subcommand - /// [`ArgGroup::multiple`]: ArgGroup::multiple() - /// [`Command`]: crate::Command - #[inline] - #[must_use] - pub fn required(mut self, yes: bool) -> Self { - self.required = yes; - self - } - - /// Specify an argument or group that must be present when this group is. - /// - /// This is not to be confused with a [required group]. Requirement rules function just like - /// [argument requirement rules], you can name other arguments or groups that must be present - /// when any one of the arguments from this group is used. - /// - /// **NOTE:** The name provided may be an argument or group name - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; - /// let result = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .arg(Arg::new("debug") - /// .short('d')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"]) - /// .requires("debug")) - /// .try_get_matches_from(vec!["myprog", "-c"]); - /// // because we used an arg from the group, and the group requires "-d" to be used, it's an - /// // error - /// assert!(result.is_err()); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [required group]: ArgGroup::required() - /// [argument requirement rules]: crate::Arg::requires() - #[must_use] - pub fn requires(mut self, id: T) -> Self { - self.requires.push(id.into()); - self - } - - /// Specify arguments or groups that must be present when this group is. - /// - /// This is not to be confused with a [required group]. Requirement rules function just like - /// [argument requirement rules], you can name other arguments or groups that must be present - /// when one of the arguments from this group is used. - /// - /// **NOTE:** The names provided may be an argument or group name - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; - /// let result = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .arg(Arg::new("debug") - /// .short('d')) - /// .arg(Arg::new("verb") - /// .short('v')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"]) - /// .requires_all(&["debug", "verb"])) - /// .try_get_matches_from(vec!["myprog", "-c", "-d"]); - /// // because we used an arg from the group, and the group requires "-d" and "-v" to be used, - /// // yet we only used "-d" it's an error - /// assert!(result.is_err()); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); - /// ``` - /// [required group]: ArgGroup::required() - /// [argument requirement rules]: crate::Arg::requires_all() - #[must_use] - pub fn requires_all(mut self, ns: &[&'help str]) -> Self { - for n in ns { - self = self.requires(n); - } - self - } - - /// Specify an argument or group that must **not** be present when this group is. - /// - /// Exclusion (aka conflict) rules function just like [argument exclusion rules], you can name - /// other arguments or groups that must *not* be present when one of the arguments from this - /// group are used. - /// - /// **NOTE:** The name provided may be an argument, or group name - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; - /// let result = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .arg(Arg::new("debug") - /// .short('d')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"]) - /// .conflicts_with("debug")) - /// .try_get_matches_from(vec!["myprog", "-c", "-d"]); - /// // because we used an arg from the group, and the group conflicts with "-d", it's an error - /// assert!(result.is_err()); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); - /// ``` - /// [argument exclusion rules]: crate::Arg::conflicts_with() - #[must_use] - pub fn conflicts_with(mut self, id: T) -> Self { - self.conflicts.push(id.into()); - self - } - - /// Specify arguments or groups that must **not** be present when this group is. - /// - /// Exclusion rules function just like [argument exclusion rules], you can name other arguments - /// or groups that must *not* be present when one of the arguments from this group are used. - /// - /// **NOTE:** The names provided may be an argument, or group name - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgGroup, ErrorKind}; - /// let result = Command::new("myprog") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("color") - /// .short('c')) - /// .arg(Arg::new("debug") - /// .short('d')) - /// .arg(Arg::new("verb") - /// .short('v')) - /// .group(ArgGroup::new("req_flags") - /// .args(&["flag", "color"]) - /// .conflicts_with_all(&["debug", "verb"])) - /// .try_get_matches_from(vec!["myprog", "-c", "-v"]); - /// // because we used an arg from the group, and the group conflicts with either "-v" or "-d" - /// // it's an error - /// assert!(result.is_err()); - /// let err = result.unwrap_err(); - /// assert_eq!(err.kind(), ErrorKind::ArgumentConflict); - /// ``` - /// - /// [argument exclusion rules]: crate::Arg::conflicts_with_all() - #[must_use] - pub fn conflicts_with_all(mut self, ns: &[&'help str]) -> Self { - for n in ns { - self = self.conflicts_with(n); - } - self - } - - /// Deprecated, replaced with [`ArgGroup::new`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ArgGroup::new`") - )] - #[doc(hidden)] - pub fn with_name>(n: S) -> Self { - Self::new(n) - } - - /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? - #[cfg(feature = "yaml")] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Maybe clap::Parser would fit your use case? (Issue #3087)" - ) - )] - #[doc(hidden)] - pub fn from_yaml(yaml: &'help Yaml) -> Self { - Self::from(yaml) - } -} - -impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> { - fn from(g: &ArgGroup<'help>) -> Self { - ArgGroup { - id: g.id.clone(), - name: g.name, - required: g.required, - args: g.args.clone(), - requires: g.requires.clone(), - conflicts: g.conflicts.clone(), - multiple: g.multiple, - } - } -} - -/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? -#[cfg(feature = "yaml")] -impl<'help> From<&'help Yaml> for ArgGroup<'help> { - /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? - fn from(y: &'help Yaml) -> Self { - let b = y.as_hash().expect("ArgGroup::from:: expects a table"); - // We WANT this to panic on error...so expect() is good. - let mut a = ArgGroup::default(); - let group_settings = if b.len() == 1 { - let name_yaml = b.keys().next().expect("failed to get name"); - let name_str = name_yaml - .as_str() - .expect("failed to convert arg YAML name to str"); - a.name = name_str; - a.id = Id::from(&a.name); - b.get(name_yaml) - .expect("failed to get name_str") - .as_hash() - .expect("failed to convert to a hash") - } else { - b - }; - - for (k, v) in group_settings { - a = match k.as_str().unwrap() { - "required" => a.required(v.as_bool().unwrap()), - "multiple" => a.multiple(v.as_bool().unwrap()), - "args" => yaml_vec_or_str!(a, v, arg), - "arg" => { - if let Some(ys) = v.as_str() { - a = a.arg(ys); - } - a - } - "requires" => yaml_vec_or_str!(a, v, requires), - "conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with), - "name" => { - if let Some(ys) = v.as_str() { - a = a.id(ys); - } - a - } - s => panic!( - "Unknown ArgGroup setting '{}' in YAML file for \ - ArgGroup '{}'", - s, a.name - ), - } - } - - a - } -} - -#[cfg(test)] -mod test { - use super::ArgGroup; - #[cfg(feature = "yaml")] - use yaml_rust::YamlLoader; - - #[test] - fn groups() { - let g = ArgGroup::new("test") - .arg("a1") - .arg("a4") - .args(&["a2", "a3"]) - .required(true) - .conflicts_with("c1") - .conflicts_with_all(&["c2", "c3"]) - .conflicts_with("c4") - .requires("r1") - .requires_all(&["r2", "r3"]) - .requires("r4"); - - let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()]; - let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()]; - let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()]; - - assert_eq!(g.args, args); - assert_eq!(g.requires, reqs); - assert_eq!(g.conflicts, confs); - } - - #[test] - fn test_from() { - let g = ArgGroup::new("test") - .arg("a1") - .arg("a4") - .args(&["a2", "a3"]) - .required(true) - .conflicts_with("c1") - .conflicts_with_all(&["c2", "c3"]) - .conflicts_with("c4") - .requires("r1") - .requires_all(&["r2", "r3"]) - .requires("r4"); - - let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()]; - let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()]; - let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()]; - - let g2 = ArgGroup::from(&g); - assert_eq!(g2.args, args); - assert_eq!(g2.requires, reqs); - assert_eq!(g2.conflicts, confs); - } - - #[cfg(feature = "yaml")] - #[test] - fn test_yaml() { - let g_yaml = "name: test -args: -- a1 -- a4 -- a2 -- a3 -conflicts_with: -- c1 -- c2 -- c3 -- c4 -requires: -- r1 -- r2 -- r3 -- r4"; - let yaml = &YamlLoader::load_from_str(g_yaml).expect("failed to load YAML file")[0]; - let g = ArgGroup::from(yaml); - let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()]; - let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()]; - let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()]; - assert_eq!(g.args, args); - assert_eq!(g.requires, reqs); - assert_eq!(g.conflicts, confs); - } - - // This test will *fail to compile* if ArgGroup is not Send + Sync - #[test] - fn arg_group_send_sync() { - fn foo(_: T) {} - foo(ArgGroup::new("test")) - } -} - -impl Clone for ArgGroup<'_> { - fn clone(&self) -> Self { - ArgGroup { - id: self.id.clone(), - name: self.name, - required: self.required, - args: self.args.clone(), - requires: self.requires.clone(), - conflicts: self.conflicts.clone(), - multiple: self.multiple, - } - } -} diff --git a/vendor/clap/src/builder/arg_predicate.rs b/vendor/clap/src/builder/arg_predicate.rs deleted file mode 100644 index 58eb5494c..000000000 --- a/vendor/clap/src/builder/arg_predicate.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub(crate) enum ArgPredicate<'help> { - IsPresent, - Equals(&'help std::ffi::OsStr), -} - -impl<'help> From> for ArgPredicate<'help> { - fn from(other: Option<&'help std::ffi::OsStr>) -> Self { - match other { - Some(other) => Self::Equals(other), - None => Self::IsPresent, - } - } -} diff --git a/vendor/clap/src/builder/arg_settings.rs b/vendor/clap/src/builder/arg_settings.rs deleted file mode 100644 index ecc064caa..000000000 --- a/vendor/clap/src/builder/arg_settings.rs +++ /dev/null @@ -1,456 +0,0 @@ -#![allow(deprecated)] - -// Std -use std::ops::BitOr; -#[cfg(feature = "yaml")] -use std::str::FromStr; - -// Third party -use bitflags::bitflags; - -#[allow(unused)] -use crate::Arg; - -#[doc(hidden)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ArgFlags(Flags); - -impl Default for ArgFlags { - fn default() -> Self { - Self::empty() - } -} - -/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter -/// methods [`Arg::setting`], [`Arg::unset_setting`], and [`Arg::is_set`]. This is what the -/// [`Arg`] methods which accept a `bool` use internally. -/// -/// [`Arg`]: crate::Arg -/// [`Arg::setting`]: crate::Arg::setting() -/// [`Arg::unset_setting`]: crate::Arg::unset_setting() -/// [`Arg::is_set`]: crate::Arg::is_set() -#[derive(Debug, PartialEq, Copy, Clone)] -#[non_exhaustive] -pub enum ArgSettings { - /// Deprecated, replaced with [`Arg::required`] and [`Arg::is_required_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::required` and `Arg::is_required_set`" - ) - )] - Required, - /// Deprecated, replaced with [`Arg::multiple_values`] and [`Arg::is_multiple_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::multiple_values` and `Arg::`is_multiple_values_set`" - ) - )] - MultipleValues, - /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Arg::action` (Issue #3772)") - )] - MultipleOccurrences, - /// Deprecated, see [`ArgSettings::MultipleOccurrences`] (most likely what you want) and - /// [`ArgSettings::MultipleValues`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Split into `Arg::multiple_occurrences` (most likely what you want) and `Arg::multiple_values`" - ) - )] - #[doc(hidden)] - Multiple, - /// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`" - ) - )] - ForbidEmptyValues, - /// Deprecated, replaced with [`Arg::global`] and [`Arg::is_global_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::global` and `Arg::is_global_set`" - ) - )] - Global, - /// Deprecated, replaced with [`Arg::hide`] and [`Arg::is_hide_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide` and `Arg::is_hide_set`" - ) - )] - Hidden, - /// Deprecated, replaced with [`Arg::takes_value`] and [`Arg::is_takes_value_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::takes_value` and `Arg::is_takes_value_set`" - ) - )] - TakesValue, - /// Deprecated, replaced with [`Arg::use_value_delimiter`] and - /// [`Arg::is_use_value_delimiter_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::use_value_delimiter` and `Arg::is_use_value_delimiter_set`" - ) - )] - UseValueDelimiter, - /// Deprecated, replaced with [`Arg::next_line_help`] and [`Arg::is_next_line_help_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::next_line_help` and `Arg::is_next_line_help_set`" - ) - )] - NextLineHelp, - /// Deprecated, replaced with [`Arg::require_value_delimiter`] and - /// [`Arg::is_require_value_delimiter_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::require_value_delimiter` and `Arg::is_require_value_delimiter_set`" - ) - )] - RequireDelimiter, - /// Deprecated, replaced with [`Arg::hide_possible_values`] and - /// [`Arg::is_hide_possible_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide_possible_values` and `Arg::is_hide_possible_values_set`" - ) - )] - HidePossibleValues, - /// Deprecated, replaced with [`Arg::allow_hyphen_values`] and - /// [`Arg::is_allow_hyphen_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`" - ) - )] - AllowHyphenValues, - /// Deprecated, replaced with [`Arg::allow_hyphen_values`] and - /// [`Arg::is_allow_hyphen_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`" - ) - )] - #[doc(hidden)] - AllowLeadingHyphen, - /// Deprecated, replaced with [`Arg::require_equals`] and [`Arg::is_require_equals_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::require_equals` and `Arg::is_require_equals_set`" - ) - )] - RequireEquals, - /// Deprecated, replaced with [`Arg::last`] and [`Arg::is_last_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::last` and `Arg::is_last_set`" - ) - )] - Last, - /// Deprecated, replaced with [`Arg::hide_default_value`] and [`Arg::is_hide_default_value_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide_default_value` and `Arg::is_hide_default_value_set`" - ) - )] - HideDefaultValue, - /// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`" - ) - )] - IgnoreCase, - /// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`" - ) - )] - #[doc(hidden)] - CaseInsensitive, - /// Deprecated, replaced with [`Arg::hide_env`] and [`Arg::is_hide_env_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide_env` and `Arg::is_hide_env_set`" - ) - )] - #[cfg(feature = "env")] - HideEnv, - /// Deprecated, replaced with [`Arg::hide_env_values`] and [`Arg::is_hide_env_values_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide_env_values` and `Arg::is_hide_env_values_set`" - ) - )] - #[cfg(feature = "env")] - HideEnvValues, - /// Deprecated, replaced with [`Arg::hide_short_help`] and [`Arg::is_hide_short_help_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide_short_help` and `Arg::is_hide_short_help_set`" - ) - )] - HiddenShortHelp, - /// Deprecated, replaced with [`Arg::hide_long_help`] and [`Arg::is_hide_long_help_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::hide_long_help` and `Arg::is_hide_long_help_set`" - ) - )] - HiddenLongHelp, - /// Deprecated, replaced with [`Arg::allow_invalid_utf8`] and [`Arg::is_allow_invalid_utf8_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::allow_invalid_utf8` and `Arg::is_allow_invalid_utf8_set`" - ) - )] - AllowInvalidUtf8, - /// Deprecated, replaced with [`Arg::exclusive`] and [`Arg::is_exclusive_set`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `Arg::exclusive` and `Arg::is_exclusive_set`" - ) - )] - Exclusive, -} - -bitflags! { - struct Flags: u32 { - const REQUIRED = 1; - const MULTIPLE_OCC = 1 << 1; - const NO_EMPTY_VALS = 1 << 2; - const GLOBAL = 1 << 3; - const HIDDEN = 1 << 4; - const TAKES_VAL = 1 << 5; - const USE_DELIM = 1 << 6; - const NEXT_LINE_HELP = 1 << 7; - const REQ_DELIM = 1 << 9; - const DELIM_NOT_SET = 1 << 10; - const HIDE_POS_VALS = 1 << 11; - const ALLOW_TAC_VALS = 1 << 12; - const REQUIRE_EQUALS = 1 << 13; - const LAST = 1 << 14; - const HIDE_DEFAULT_VAL = 1 << 15; - const CASE_INSENSITIVE = 1 << 16; - #[cfg(feature = "env")] - const HIDE_ENV_VALS = 1 << 17; - const HIDDEN_SHORT_H = 1 << 18; - const HIDDEN_LONG_H = 1 << 19; - const MULTIPLE_VALS = 1 << 20; - const MULTIPLE = Self::MULTIPLE_OCC.bits | Self::MULTIPLE_VALS.bits; - #[cfg(feature = "env")] - const HIDE_ENV = 1 << 21; - const UTF8_NONE = 1 << 22; - const EXCLUSIVE = 1 << 23; - const NO_OP = 0; - } -} - -impl_settings! { ArgSettings, ArgFlags, - Required => Flags::REQUIRED, - MultipleOccurrences => Flags::MULTIPLE_OCC, - MultipleValues => Flags::MULTIPLE_VALS, - Multiple => Flags::MULTIPLE, - ForbidEmptyValues => Flags::NO_EMPTY_VALS, - Global => Flags::GLOBAL, - Hidden => Flags::HIDDEN, - TakesValue => Flags::TAKES_VAL, - UseValueDelimiter => Flags::USE_DELIM, - NextLineHelp => Flags::NEXT_LINE_HELP, - RequireDelimiter => Flags::REQ_DELIM, - HidePossibleValues => Flags::HIDE_POS_VALS, - AllowHyphenValues => Flags::ALLOW_TAC_VALS, - AllowLeadingHyphen => Flags::ALLOW_TAC_VALS, - RequireEquals => Flags::REQUIRE_EQUALS, - Last => Flags::LAST, - IgnoreCase => Flags::CASE_INSENSITIVE, - CaseInsensitive => Flags::CASE_INSENSITIVE, - #[cfg(feature = "env")] - HideEnv => Flags::HIDE_ENV, - #[cfg(feature = "env")] - HideEnvValues => Flags::HIDE_ENV_VALS, - HideDefaultValue => Flags::HIDE_DEFAULT_VAL, - HiddenShortHelp => Flags::HIDDEN_SHORT_H, - HiddenLongHelp => Flags::HIDDEN_LONG_H, - AllowInvalidUtf8 => Flags::UTF8_NONE, - Exclusive => Flags::EXCLUSIVE -} - -/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? -#[cfg(feature = "yaml")] -impl FromStr for ArgSettings { - type Err = String; - fn from_str(s: &str) -> Result::Err> { - #[allow(deprecated)] - #[allow(unreachable_patterns)] - match &*s.to_ascii_lowercase() { - "required" => Ok(ArgSettings::Required), - "multipleoccurrences" => Ok(ArgSettings::MultipleOccurrences), - "multiplevalues" => Ok(ArgSettings::MultipleValues), - "multiple" => Ok(ArgSettings::Multiple), - "forbidemptyvalues" => Ok(ArgSettings::ForbidEmptyValues), - "global" => Ok(ArgSettings::Global), - "hidden" => Ok(ArgSettings::Hidden), - "takesvalue" => Ok(ArgSettings::TakesValue), - "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter), - "nextlinehelp" => Ok(ArgSettings::NextLineHelp), - "requiredelimiter" => Ok(ArgSettings::RequireDelimiter), - "hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues), - "allowhyphenvalues" => Ok(ArgSettings::AllowHyphenValues), - "allowleadinghypyhen" => Ok(ArgSettings::AllowLeadingHyphen), - "requireequals" => Ok(ArgSettings::RequireEquals), - "last" => Ok(ArgSettings::Last), - "ignorecase" => Ok(ArgSettings::IgnoreCase), - "caseinsensitive" => Ok(ArgSettings::CaseInsensitive), - #[cfg(feature = "env")] - "hideenv" => Ok(ArgSettings::HideEnv), - #[cfg(feature = "env")] - "hideenvvalues" => Ok(ArgSettings::HideEnvValues), - "hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue), - "hiddenshorthelp" => Ok(ArgSettings::HiddenShortHelp), - "hiddenlonghelp" => Ok(ArgSettings::HiddenLongHelp), - "allowinvalidutf8" => Ok(ArgSettings::AllowInvalidUtf8), - "exclusive" => Ok(ArgSettings::Exclusive), - _ => Err(format!("unknown AppSetting: `{}`", s)), - } - } -} - -#[cfg(test)] -mod test { - #[test] - #[cfg(feature = "yaml")] - fn arg_settings_fromstr() { - use super::ArgSettings; - - assert_eq!( - "allowhyphenvalues".parse::().unwrap(), - ArgSettings::AllowHyphenValues - ); - assert_eq!( - "forbidemptyvalues".parse::().unwrap(), - ArgSettings::ForbidEmptyValues - ); - assert_eq!( - "hidepossiblevalues".parse::().unwrap(), - ArgSettings::HidePossibleValues - ); - assert_eq!( - "hidden".parse::().unwrap(), - ArgSettings::Hidden - ); - assert_eq!( - "nextlinehelp".parse::().unwrap(), - ArgSettings::NextLineHelp - ); - assert_eq!( - "requiredelimiter".parse::().unwrap(), - ArgSettings::RequireDelimiter - ); - assert_eq!( - "required".parse::().unwrap(), - ArgSettings::Required - ); - assert_eq!( - "takesvalue".parse::().unwrap(), - ArgSettings::TakesValue - ); - assert_eq!( - "usevaluedelimiter".parse::().unwrap(), - ArgSettings::UseValueDelimiter - ); - assert_eq!( - "requireequals".parse::().unwrap(), - ArgSettings::RequireEquals - ); - assert_eq!("last".parse::().unwrap(), ArgSettings::Last); - assert_eq!( - "hidedefaultvalue".parse::().unwrap(), - ArgSettings::HideDefaultValue - ); - assert_eq!( - "ignorecase".parse::().unwrap(), - ArgSettings::IgnoreCase - ); - #[cfg(feature = "env")] - assert_eq!( - "hideenv".parse::().unwrap(), - ArgSettings::HideEnv - ); - #[cfg(feature = "env")] - assert_eq!( - "hideenvvalues".parse::().unwrap(), - ArgSettings::HideEnvValues - ); - assert_eq!( - "hiddenshorthelp".parse::().unwrap(), - ArgSettings::HiddenShortHelp - ); - assert_eq!( - "hiddenlonghelp".parse::().unwrap(), - ArgSettings::HiddenLongHelp - ); - assert_eq!( - "allowinvalidutf8".parse::().unwrap(), - ArgSettings::AllowInvalidUtf8 - ); - assert_eq!( - "exclusive".parse::().unwrap(), - ArgSettings::Exclusive - ); - assert!("hahahaha".parse::().is_err()); - } -} diff --git a/vendor/clap/src/builder/command.rs b/vendor/clap/src/builder/command.rs deleted file mode 100644 index de59ad8cd..000000000 --- a/vendor/clap/src/builder/command.rs +++ /dev/null @@ -1,5189 +0,0 @@ -#![allow(deprecated)] - -// Std -use std::collections::HashMap; -use std::env; -use std::ffi::OsString; -use std::fmt; -use std::io; -use std::ops::Index; -use std::path::Path; - -// Third Party -#[cfg(feature = "yaml")] -use yaml_rust::Yaml; - -// Internal -use crate::builder::app_settings::{AppFlags, AppSettings}; -use crate::builder::arg_settings::ArgSettings; -use crate::builder::{arg::ArgProvider, Arg, ArgGroup, ArgPredicate}; -use crate::error::ErrorKind; -use crate::error::Result as ClapResult; -use crate::mkeymap::MKeyMap; -use crate::output::fmt::Stream; -use crate::output::{fmt::Colorizer, Help, HelpWriter, Usage}; -use crate::parser::{ArgMatcher, ArgMatches, Parser}; -use crate::util::ChildGraph; -use crate::util::{color::ColorChoice, Id, Key}; -use crate::PossibleValue; -use crate::{Error, INTERNAL_ERROR_MSG}; - -#[cfg(debug_assertions)] -use crate::builder::debug_asserts::assert_app; - -/// Build a command-line interface. -/// -/// This includes defining arguments, subcommands, parser behavior, and help output. -/// Once all configuration is complete, -/// the [`Command::get_matches`] family of methods starts the runtime-parsing -/// process. These methods then return information about the user supplied -/// arguments (or lack thereof). -/// -/// When deriving a [`Parser`][crate::Parser], you can use -/// [`CommandFactory::command`][crate::CommandFactory::command] to access the -/// `Command`. -/// -/// - [Basic API][crate::App#basic-api] -/// - [Application-wide Settings][crate::App#application-wide-settings] -/// - [Command-specific Settings][crate::App#command-specific-settings] -/// - [Subcommand-specific Settings][crate::App#subcommand-specific-settings] -/// - [Reflection][crate::App#reflection] -/// -/// # Examples -/// -/// ```no_run -/// # use clap::{Command, Arg}; -/// let m = Command::new("My Program") -/// .author("Me, me@mail.com") -/// .version("1.0.2") -/// .about("Explains in brief what the program does") -/// .arg( -/// Arg::new("in_file") -/// ) -/// .after_help("Longer explanation to appear after the options when \ -/// displaying the help information from --help or -h") -/// .get_matches(); -/// -/// // Your program logic starts here... -/// ``` -/// [`App::get_matches`]: Command::get_matches() -pub type Command<'help> = App<'help>; - -/// Deprecated, replaced with [`Command`] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Command`") -)] -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct App<'help> { - id: Id, - name: String, - long_flag: Option<&'help str>, - short_flag: Option, - display_name: Option, - bin_name: Option, - author: Option<&'help str>, - version: Option<&'help str>, - long_version: Option<&'help str>, - about: Option<&'help str>, - long_about: Option<&'help str>, - before_help: Option<&'help str>, - before_long_help: Option<&'help str>, - after_help: Option<&'help str>, - after_long_help: Option<&'help str>, - aliases: Vec<(&'help str, bool)>, // (name, visible) - short_flag_aliases: Vec<(char, bool)>, // (name, visible) - long_flag_aliases: Vec<(&'help str, bool)>, // (name, visible) - usage_str: Option<&'help str>, - usage_name: Option, - help_str: Option<&'help str>, - disp_ord: Option, - term_w: Option, - max_w: Option, - template: Option<&'help str>, - settings: AppFlags, - g_settings: AppFlags, - args: MKeyMap<'help>, - subcommands: Vec>, - replacers: HashMap<&'help str, &'help [&'help str]>, - groups: Vec>, - current_help_heading: Option<&'help str>, - current_disp_ord: Option, - subcommand_value_name: Option<&'help str>, - subcommand_heading: Option<&'help str>, -} - -/// # Basic API -impl<'help> App<'help> { - /// Creates a new instance of an `Command`. - /// - /// It is common, but not required, to use binary name as the `name`. This - /// name will only be displayed to the user when they request to print - /// version or help and usage information. - /// - /// See also [`command!`](crate::command!) and [`crate_name!`](crate::crate_name!). - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("My Program") - /// # ; - /// ``` - pub fn new>(name: S) -> Self { - /// The actual implementation of `new`, non-generic to save code size. - /// - /// If we don't do this rustc will unnecessarily generate multiple versions - /// of this code. - fn new_inner<'help>(name: String) -> App<'help> { - App { - id: Id::from(&*name), - name, - ..Default::default() - } - .arg( - Arg::new("help") - .long("help") - .help("Print help information") - .global(true) - .generated(), - ) - .arg( - Arg::new("version") - .long("version") - .help("Print version information") - .global(true) - .generated(), - ) - } - - new_inner(name.into()) - } - - /// Adds an [argument] to the list of valid possibilities. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, arg, Arg}; - /// Command::new("myprog") - /// // Adding a single "flag" argument with a short and help text, using Arg::new() - /// .arg( - /// Arg::new("debug") - /// .short('d') - /// .help("turns on debugging mode") - /// ) - /// // Adding a single "option" argument with a short, a long, and help text using the less - /// // verbose Arg::from() - /// .arg( - /// arg!(-c --config "Optionally sets a config file to use") - /// ) - /// # ; - /// ``` - /// [argument]: Arg - #[must_use] - pub fn arg>>(mut self, a: A) -> Self { - let mut arg = a.into(); - if let Some(current_disp_ord) = self.current_disp_ord.as_mut() { - if !arg.is_positional() && arg.provider != ArgProvider::Generated { - let current = *current_disp_ord; - arg.disp_ord.set_implicit(current); - *current_disp_ord = current + 1; - } - } - - arg.help_heading.get_or_insert(self.current_help_heading); - self.args.push(arg); - self - } - - /// Adds multiple [arguments] to the list of valid possibilities. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, arg, Arg}; - /// Command::new("myprog") - /// .args(&[ - /// arg!("[debug] -d 'turns on debugging info'"), - /// Arg::new("input").help("the input file to use") - /// ]) - /// # ; - /// ``` - /// [arguments]: Arg - #[must_use] - pub fn args(mut self, args: I) -> Self - where - I: IntoIterator, - T: Into>, - { - let args = args.into_iter(); - let (lower, _) = args.size_hint(); - self.args.reserve(lower); - - for arg in args { - self = self.arg(arg); - } - self - } - - /// Allows one to mutate an [`Arg`] after it's been added to a [`Command`]. - /// - /// This can be useful for modifying the auto-generated help or version arguments. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// - /// let mut cmd = Command::new("foo") - /// .arg(Arg::new("bar") - /// .short('b')) - /// .mut_arg("bar", |a| a.short('B')); - /// - /// let res = cmd.try_get_matches_from_mut(vec!["foo", "-b"]); - /// - /// // Since we changed `bar`'s short to "B" this should err as there - /// // is no `-b` anymore, only `-B` - /// - /// assert!(res.is_err()); - /// - /// let res = cmd.try_get_matches_from_mut(vec!["foo", "-B"]); - /// assert!(res.is_ok()); - /// ``` - #[must_use] - pub fn mut_arg(mut self, arg_id: T, f: F) -> Self - where - F: FnOnce(Arg<'help>) -> Arg<'help>, - T: Key + Into<&'help str>, - { - let arg_id: &str = arg_id.into(); - let id = Id::from(arg_id); - - let mut a = self.args.remove_by_name(&id).unwrap_or_else(|| Arg { - id, - name: arg_id, - ..Arg::default() - }); - - if a.provider == ArgProvider::Generated { - a.provider = ArgProvider::GeneratedMutated; - } - - self.args.push(f(a)); - self - } - - /// Allows one to mutate a [`Command`] after it's been added as a subcommand. - /// - /// This can be useful for modifying auto-generated arguments of nested subcommands with - /// [`Command::mut_arg`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// - /// let mut cmd = Command::new("foo") - /// .subcommand(Command::new("bar")) - /// .mut_subcommand("bar", |subcmd| subcmd.disable_help_flag(true)); - /// - /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar", "--help"]); - /// - /// // Since we disabled the help flag on the "bar" subcommand, this should err. - /// - /// assert!(res.is_err()); - /// - /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar"]); - /// assert!(res.is_ok()); - /// ``` - #[must_use] - pub fn mut_subcommand<'a, T, F>(mut self, subcmd_id: T, f: F) -> Self - where - F: FnOnce(App<'help>) -> App<'help>, - T: Into<&'a str>, - { - let subcmd_id: &str = subcmd_id.into(); - let id = Id::from(subcmd_id); - - let pos = self.subcommands.iter().position(|s| s.id == id); - - let subcmd = if let Some(idx) = pos { - self.subcommands.remove(idx) - } else { - App::new(subcmd_id) - }; - - self.subcommands.push(f(subcmd)); - self - } - - /// Adds an [`ArgGroup`] to the application. - /// - /// [`ArgGroup`]s are a family of related arguments. - /// By placing them in a logical group, you can build easier requirement and exclusion rules. - /// - /// Example use cases: - /// - Make an entire [`ArgGroup`] required, meaning that one (and *only* - /// one) argument from that group must be present at runtime. - /// - Name an [`ArgGroup`] as a conflict to another argument. - /// Meaning any of the arguments that belong to that group will cause a failure if present with - /// the conflicting argument. - /// - Ensure exclusion between arguments. - /// - Extract a value from a group instead of determining exactly which argument was used. - /// - /// # Examples - /// - /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one, - /// of the arguments from the specified group is present at runtime. - /// - /// ```no_run - /// # use clap::{Command, arg, ArgGroup}; - /// Command::new("cmd") - /// .arg(arg!("--set-ver [ver] 'set the version manually'")) - /// .arg(arg!("--major 'auto increase major'")) - /// .arg(arg!("--minor 'auto increase minor'")) - /// .arg(arg!("--patch 'auto increase patch'")) - /// .group(ArgGroup::new("vers") - /// .args(&["set-ver", "major", "minor","patch"]) - /// .required(true)) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn group>>(mut self, group: G) -> Self { - self.groups.push(group.into()); - self - } - - /// Adds multiple [`ArgGroup`]s to the [`Command`] at once. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, arg, ArgGroup}; - /// Command::new("cmd") - /// .arg(arg!("--set-ver [ver] 'set the version manually'")) - /// .arg(arg!("--major 'auto increase major'")) - /// .arg(arg!("--minor 'auto increase minor'")) - /// .arg(arg!("--patch 'auto increase patch'")) - /// .arg(arg!("-c [FILE] 'a config file'")) - /// .arg(arg!("-i [IFACE] 'an interface'")) - /// .groups(&[ - /// ArgGroup::new("vers") - /// .args(&["set-ver", "major", "minor","patch"]) - /// .required(true), - /// ArgGroup::new("input") - /// .args(&["c", "i"]) - /// ]) - /// # ; - /// ``` - #[must_use] - pub fn groups(mut self, groups: I) -> Self - where - I: IntoIterator, - T: Into>, - { - for g in groups.into_iter() { - self = self.group(g.into()); - } - self - } - - /// Adds a subcommand to the list of valid possibilities. - /// - /// Subcommands are effectively sub-[`Command`]s, because they can contain their own arguments, - /// subcommands, version, usage, etc. They also function just like [`Command`]s, in that they get - /// their own auto generated help, version, and usage. - /// - /// A subcommand's [`Command::name`] will be used for: - /// - The argument the user passes in - /// - Programmatically looking up the subcommand - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, arg}; - /// Command::new("myprog") - /// .subcommand(Command::new("config") - /// .about("Controls configuration features") - /// .arg(arg!(" 'Required configuration file to use'"))) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn subcommand>>(mut self, subcmd: S) -> Self { - self.subcommands.push(subcmd.into()); - self - } - - /// Adds multiple subcommands to the list of valid possibilities. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, }; - /// # Command::new("myprog") - /// .subcommands( vec![ - /// Command::new("config").about("Controls configuration functionality") - /// .arg(Arg::new("config_file")), - /// Command::new("debug").about("Controls debug functionality")]) - /// # ; - /// ``` - /// [`IntoIterator`]: std::iter::IntoIterator - #[must_use] - pub fn subcommands(mut self, subcmds: I) -> Self - where - I: IntoIterator, - T: Into>, - { - for subcmd in subcmds.into_iter() { - self.subcommands.push(subcmd.into()); - } - self - } - - /// Catch problems earlier in the development cycle. - /// - /// Most error states are handled as asserts under the assumption they are programming mistake - /// and not something to handle at runtime. Rather than relying on tests (manual or automated) - /// that exhaustively test your CLI to ensure the asserts are evaluated, this will run those - /// asserts in a way convenient for running as a test. - /// - /// **Note::** This will not help with asserts in [`ArgMatches`], those will need exhaustive - /// testing of your CLI. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// fn cmd() -> Command<'static> { - /// Command::new("foo") - /// .arg( - /// Arg::new("bar").short('b').action(ArgAction::SetTrue) - /// ) - /// } - /// - /// #[test] - /// fn verify_app() { - /// cmd().debug_assert(); - /// } - /// - /// fn main() { - /// let m = cmd().get_matches_from(vec!["foo", "-b"]); - /// println!("{}", *m.get_one::("bar").expect("defaulted by clap")); - /// } - /// ``` - pub fn debug_assert(mut self) { - self._build_all(); - } - - /// Custom error message for post-parsing validation - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let mut cmd = Command::new("myprog"); - /// let err = cmd.error(ErrorKind::InvalidValue, "Some failure case"); - /// ``` - pub fn error(&mut self, kind: ErrorKind, message: impl std::fmt::Display) -> Error { - Error::raw(kind, message).format(self) - } - - /// Parse [`env::args_os`], exiting on failure. - /// - /// # Panics - /// - /// If contradictory arguments or settings exist. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let matches = Command::new("myprog") - /// // Args and options go here... - /// .get_matches(); - /// ``` - /// [`env::args_os`]: std::env::args_os() - /// [`App::try_get_matches_from_mut`]: Command::try_get_matches_from_mut() - #[inline] - pub fn get_matches(self) -> ArgMatches { - self.get_matches_from(&mut env::args_os()) - } - - /// Parse [`env::args_os`], exiting on failure. - /// - /// Like [`App::get_matches`] but doesn't consume the `Command`. - /// - /// # Panics - /// - /// If contradictory arguments or settings exist. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let mut cmd = Command::new("myprog") - /// // Args and options go here... - /// ; - /// let matches = cmd.get_matches_mut(); - /// ``` - /// [`env::args_os`]: std::env::args_os() - /// [`App::get_matches`]: Command::get_matches() - pub fn get_matches_mut(&mut self) -> ArgMatches { - self.try_get_matches_from_mut(&mut env::args_os()) - .unwrap_or_else(|e| e.exit()) - } - - /// Parse [`env::args_os`], returning a [`clap::Result`] on failure. - /// - /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are - /// used. It will return a [`clap::Error`], where the [`kind`] is a - /// [`ErrorKind::DisplayHelp`] or [`ErrorKind::DisplayVersion`] respectively. You must call - /// [`Error::exit`] or perform a [`std::process::exit`]. - /// - /// # Panics - /// - /// If contradictory arguments or settings exist. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let matches = Command::new("myprog") - /// // Args and options go here... - /// .try_get_matches() - /// .unwrap_or_else(|e| e.exit()); - /// ``` - /// [`env::args_os`]: std::env::args_os() - /// [`Error::exit`]: crate::Error::exit() - /// [`std::process::exit`]: std::process::exit() - /// [`clap::Result`]: Result - /// [`clap::Error`]: crate::Error - /// [`kind`]: crate::Error - /// [`ErrorKind::DisplayHelp`]: crate::ErrorKind::DisplayHelp - /// [`ErrorKind::DisplayVersion`]: crate::ErrorKind::DisplayVersion - #[inline] - pub fn try_get_matches(self) -> ClapResult { - // Start the parsing - self.try_get_matches_from(&mut env::args_os()) - } - - /// Parse the specified arguments, exiting on failure. - /// - /// **NOTE:** The first argument will be parsed as the binary name unless - /// [`Command::no_binary_name`] is used. - /// - /// # Panics - /// - /// If contradictory arguments or settings exist. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; - /// - /// let matches = Command::new("myprog") - /// // Args and options go here... - /// .get_matches_from(arg_vec); - /// ``` - /// [`App::get_matches`]: Command::get_matches() - /// [`clap::Result`]: Result - /// [`Vec`]: std::vec::Vec - pub fn get_matches_from(mut self, itr: I) -> ArgMatches - where - I: IntoIterator, - T: Into + Clone, - { - self.try_get_matches_from_mut(itr).unwrap_or_else(|e| { - drop(self); - e.exit() - }) - } - - /// Parse the specified arguments, returning a [`clap::Result`] on failure. - /// - /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are - /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`] - /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or - /// perform a [`std::process::exit`] yourself. - /// - /// **NOTE:** The first argument will be parsed as the binary name unless - /// [`Command::no_binary_name`] is used. - /// - /// # Panics - /// - /// If contradictory arguments or settings exist. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; - /// - /// let matches = Command::new("myprog") - /// // Args and options go here... - /// .try_get_matches_from(arg_vec) - /// .unwrap_or_else(|e| e.exit()); - /// ``` - /// [`App::get_matches_from`]: Command::get_matches_from() - /// [`App::try_get_matches`]: Command::try_get_matches() - /// [`Error::exit`]: crate::Error::exit() - /// [`std::process::exit`]: std::process::exit() - /// [`clap::Error`]: crate::Error - /// [`Error::exit`]: crate::Error::exit() - /// [`kind`]: crate::Error - /// [`ErrorKind::DisplayHelp`]: crate::ErrorKind::DisplayHelp - /// [`ErrorKind::DisplayVersion`]: crate::ErrorKind::DisplayVersion - /// [`clap::Result`]: Result - pub fn try_get_matches_from(mut self, itr: I) -> ClapResult - where - I: IntoIterator, - T: Into + Clone, - { - self.try_get_matches_from_mut(itr) - } - - /// Parse the specified arguments, returning a [`clap::Result`] on failure. - /// - /// Like [`App::try_get_matches_from`] but doesn't consume the `Command`. - /// - /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are - /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`] - /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or - /// perform a [`std::process::exit`] yourself. - /// - /// **NOTE:** The first argument will be parsed as the binary name unless - /// [`Command::no_binary_name`] is used. - /// - /// # Panics - /// - /// If contradictory arguments or settings exist. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; - /// - /// let mut cmd = Command::new("myprog"); - /// // Args and options go here... - /// let matches = cmd.try_get_matches_from_mut(arg_vec) - /// .unwrap_or_else(|e| e.exit()); - /// ``` - /// [`App::try_get_matches_from`]: Command::try_get_matches_from() - /// [`clap::Result`]: Result - /// [`clap::Error`]: crate::Error - /// [`kind`]: crate::Error - pub fn try_get_matches_from_mut(&mut self, itr: I) -> ClapResult - where - I: IntoIterator, - T: Into + Clone, - { - let mut raw_args = clap_lex::RawArgs::new(itr.into_iter()); - let mut cursor = raw_args.cursor(); - - if self.settings.is_set(AppSettings::Multicall) { - if let Some(argv0) = raw_args.next_os(&mut cursor) { - let argv0 = Path::new(&argv0); - if let Some(command) = argv0.file_stem().and_then(|f| f.to_str()) { - // Stop borrowing command so we can get another mut ref to it. - let command = command.to_owned(); - debug!( - "Command::try_get_matches_from_mut: Parsed command {} from argv", - command - ); - - debug!("Command::try_get_matches_from_mut: Reinserting command into arguments so subcommand parser matches it"); - raw_args.insert(&cursor, &[&command]); - debug!("Command::try_get_matches_from_mut: Clearing name and bin_name so that displayed command name starts with applet name"); - self.name.clear(); - self.bin_name = None; - return self._do_parse(&mut raw_args, cursor); - } - } - }; - - // Get the name of the program (argument 1 of env::args()) and determine the - // actual file - // that was used to execute the program. This is because a program called - // ./target/release/my_prog -a - // will have two arguments, './target/release/my_prog', '-a' but we don't want - // to display - // the full path when displaying help messages and such - if !self.settings.is_set(AppSettings::NoBinaryName) { - if let Some(name) = raw_args.next_os(&mut cursor) { - let p = Path::new(name); - - if let Some(f) = p.file_name() { - if let Some(s) = f.to_str() { - if self.bin_name.is_none() { - self.bin_name = Some(s.to_owned()); - } - } - } - } - } - - self._do_parse(&mut raw_args, cursor) - } - - /// Prints the short help message (`-h`) to [`io::stdout()`]. - /// - /// See also [`Command::print_long_help`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// let mut cmd = Command::new("myprog"); - /// cmd.print_help(); - /// ``` - /// [`io::stdout()`]: std::io::stdout() - pub fn print_help(&mut self) -> io::Result<()> { - self._build_self(); - let color = self.color_help(); - - let mut c = Colorizer::new(Stream::Stdout, color); - let usage = Usage::new(self); - Help::new(HelpWriter::Buffer(&mut c), self, &usage, false).write_help()?; - c.print() - } - - /// Prints the long help message (`--help`) to [`io::stdout()`]. - /// - /// See also [`Command::print_help`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// let mut cmd = Command::new("myprog"); - /// cmd.print_long_help(); - /// ``` - /// [`io::stdout()`]: std::io::stdout() - /// [`BufWriter`]: std::io::BufWriter - /// [`-h` (short)]: Arg::help() - /// [`--help` (long)]: Arg::long_help() - pub fn print_long_help(&mut self) -> io::Result<()> { - self._build_self(); - let color = self.color_help(); - - let mut c = Colorizer::new(Stream::Stdout, color); - let usage = Usage::new(self); - Help::new(HelpWriter::Buffer(&mut c), self, &usage, true).write_help()?; - c.print() - } - - /// Writes the short help message (`-h`) to a [`io::Write`] object. - /// - /// See also [`Command::write_long_help`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// use std::io; - /// let mut cmd = Command::new("myprog"); - /// let mut out = io::stdout(); - /// cmd.write_help(&mut out).expect("failed to write to stdout"); - /// ``` - /// [`io::Write`]: std::io::Write - /// [`-h` (short)]: Arg::help() - /// [`--help` (long)]: Arg::long_help() - pub fn write_help(&mut self, w: &mut W) -> io::Result<()> { - self._build_self(); - - let usage = Usage::new(self); - Help::new(HelpWriter::Normal(w), self, &usage, false).write_help()?; - w.flush() - } - - /// Writes the long help message (`--help`) to a [`io::Write`] object. - /// - /// See also [`Command::write_help`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// use std::io; - /// let mut cmd = Command::new("myprog"); - /// let mut out = io::stdout(); - /// cmd.write_long_help(&mut out).expect("failed to write to stdout"); - /// ``` - /// [`io::Write`]: std::io::Write - /// [`-h` (short)]: Arg::help() - /// [`--help` (long)]: Arg::long_help() - pub fn write_long_help(&mut self, w: &mut W) -> io::Result<()> { - self._build_self(); - - let usage = Usage::new(self); - Help::new(HelpWriter::Normal(w), self, &usage, true).write_help()?; - w.flush() - } - - /// Version message rendered as if the user ran `-V`. - /// - /// See also [`Command::render_long_version`]. - /// - /// ### Coloring - /// - /// This function does not try to color the message nor it inserts any [ANSI escape codes]. - /// - /// ### Examples - /// - /// ```rust - /// # use clap::Command; - /// use std::io; - /// let cmd = Command::new("myprog"); - /// println!("{}", cmd.render_version()); - /// ``` - /// [`io::Write`]: std::io::Write - /// [`-V` (short)]: Command::version() - /// [`--version` (long)]: Command::long_version() - /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code - pub fn render_version(&self) -> String { - self._render_version(false) - } - - /// Version message rendered as if the user ran `--version`. - /// - /// See also [`Command::render_version`]. - /// - /// ### Coloring - /// - /// This function does not try to color the message nor it inserts any [ANSI escape codes]. - /// - /// ### Examples - /// - /// ```rust - /// # use clap::Command; - /// use std::io; - /// let cmd = Command::new("myprog"); - /// println!("{}", cmd.render_long_version()); - /// ``` - /// [`io::Write`]: std::io::Write - /// [`-V` (short)]: Command::version() - /// [`--version` (long)]: Command::long_version() - /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code - pub fn render_long_version(&self) -> String { - self._render_version(true) - } - - /// Usage statement - /// - /// ### Examples - /// - /// ```rust - /// # use clap::Command; - /// use std::io; - /// let mut cmd = Command::new("myprog"); - /// println!("{}", cmd.render_usage()); - /// ``` - pub fn render_usage(&mut self) -> String { - // If there are global arguments, or settings we need to propagate them down to subcommands - // before parsing incase we run into a subcommand - self._build_self(); - - Usage::new(self).create_usage_with_title(&[]) - } -} - -/// # Application-wide Settings -/// -/// These settings will apply to the top-level command and all subcommands, by default. Some -/// settings can be overridden in subcommands. -impl<'help> App<'help> { - /// Specifies that the parser should not assume the first argument passed is the binary name. - /// - /// This is normally the case when using a "daemon" style mode. For shells / REPLs, see - /// [`Command::multicall`][App::multicall]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, arg}; - /// let m = Command::new("myprog") - /// .no_binary_name(true) - /// .arg(arg!( ... "commands to run")) - /// .get_matches_from(vec!["command", "set"]); - /// - /// let cmds: Vec<&str> = m.values_of("cmd").unwrap().collect(); - /// assert_eq!(cmds, ["command", "set"]); - /// ``` - /// [`try_get_matches_from_mut`]: crate::Command::try_get_matches_from_mut() - #[inline] - pub fn no_binary_name(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::NoBinaryName) - } else { - self.unset_global_setting(AppSettings::NoBinaryName) - } - } - - /// Try not to fail on parse errors, like missing option values. - /// - /// **Note:** Make sure you apply it as `global_setting` if you want this setting - /// to be propagated to subcommands and sub-subcommands! - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, arg}; - /// let cmd = Command::new("cmd") - /// .ignore_errors(true) - /// .arg(arg!(-c --config "Sets a custom config file").required(false)) - /// .arg(arg!(-x --stuff "Sets a custom stuff file").required(false)) - /// .arg(arg!(f: -f "Flag")); - /// - /// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]); - /// - /// assert!(r.is_ok(), "unexpected error: {:?}", r); - /// let m = r.unwrap(); - /// assert_eq!(m.value_of("config"), Some("file")); - /// assert!(m.is_present("f")); - /// assert_eq!(m.value_of("stuff"), None); - /// ``` - #[inline] - pub fn ignore_errors(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::IgnoreErrors) - } else { - self.unset_global_setting(AppSettings::IgnoreErrors) - } - } - - /// Deprecated, replaced with [`ArgAction::Set`][super::ArgAction::Set] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `Arg::action(ArgAction::Set)`") - )] - pub fn args_override_self(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::AllArgsOverrideSelf) - } else { - self.unset_global_setting(AppSettings::AllArgsOverrideSelf) - } - } - - /// Disables the automatic delimiting of values after `--` or when [`Command::trailing_var_arg`] - /// was used. - /// - /// **NOTE:** The same thing can be done manually by setting the final positional argument to - /// [`Arg::use_value_delimiter(false)`]. Using this setting is safer, because it's easier to locate - /// when making changes. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .dont_delimit_trailing_values(true) - /// .get_matches(); - /// ``` - /// - /// [`Arg::use_value_delimiter(false)`]: crate::Arg::use_value_delimiter() - #[inline] - pub fn dont_delimit_trailing_values(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::DontDelimitTrailingValues) - } else { - self.unset_global_setting(AppSettings::DontDelimitTrailingValues) - } - } - - /// Sets when to color output. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// **NOTE:** Default behaviour is [`ColorChoice::Auto`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, ColorChoice}; - /// Command::new("myprog") - /// .color(ColorChoice::Never) - /// .get_matches(); - /// ``` - /// [`ColorChoice::Auto`]: crate::ColorChoice::Auto - #[cfg(feature = "color")] - #[inline] - #[must_use] - pub fn color(self, color: ColorChoice) -> Self { - #![allow(deprecated)] - let cmd = self - .unset_global_setting(AppSettings::ColorAuto) - .unset_global_setting(AppSettings::ColorAlways) - .unset_global_setting(AppSettings::ColorNever); - match color { - ColorChoice::Auto => cmd.global_setting(AppSettings::ColorAuto), - ColorChoice::Always => cmd.global_setting(AppSettings::ColorAlways), - ColorChoice::Never => cmd.global_setting(AppSettings::ColorNever), - } - } - - /// Sets the terminal width at which to wrap help messages. - /// - /// Using `0` will ignore terminal widths and use source formatting. - /// - /// Defaults to current terminal width when `wrap_help` feature flag is enabled. If the flag - /// is disabled or it cannot be determined, the default is 100. - /// - /// **NOTE:** This setting applies globally and *not* on a per-command basis. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .term_width(80) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn term_width(mut self, width: usize) -> Self { - self.term_w = Some(width); - self - } - - /// Sets the maximum terminal width at which to wrap help messages. - /// - /// This only applies when setting the current terminal width. See [`Command::term_width`] for - /// more details. - /// - /// Using `0` will ignore terminal widths and use source formatting. - /// - /// **NOTE:** This setting applies globally and *not* on a per-command basis. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .max_term_width(100) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn max_term_width(mut self, w: usize) -> Self { - self.max_w = Some(w); - self - } - - /// Disables `-V` and `--version` flag. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let res = Command::new("myprog") - /// .disable_version_flag(true) - /// .try_get_matches_from(vec![ - /// "myprog", "-V" - /// ]); - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - #[inline] - pub fn disable_version_flag(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::DisableVersionFlag) - } else { - self.unset_global_setting(AppSettings::DisableVersionFlag) - } - } - - /// Specifies to use the version of the current command for all [`subcommands`]. - /// - /// Defaults to `false`; subcommands have independent version strings from their parents. - /// - /// **Note:** Make sure you apply it as `global_setting` if you want this setting - /// to be propagated to subcommands and sub-subcommands! - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .version("v1.1") - /// .propagate_version(true) - /// .subcommand(Command::new("test")) - /// .get_matches(); - /// // running `$ myprog test --version` will display - /// // "myprog-test v1.1" - /// ``` - /// - /// [`subcommands`]: crate::Command::subcommand() - #[inline] - pub fn propagate_version(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::PropagateVersion) - } else { - self.unset_global_setting(AppSettings::PropagateVersion) - } - } - - /// Places the help string for all arguments and subcommands on the line after them. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .next_line_help(true) - /// .get_matches(); - /// ``` - #[inline] - pub fn next_line_help(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::NextLineHelp) - } else { - self.unset_global_setting(AppSettings::NextLineHelp) - } - } - - /// Disables `-h` and `--help` flag. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let res = Command::new("myprog") - /// .disable_help_flag(true) - /// .try_get_matches_from(vec![ - /// "myprog", "-h" - /// ]); - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - #[inline] - pub fn disable_help_flag(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::DisableHelpFlag) - } else { - self.unset_global_setting(AppSettings::DisableHelpFlag) - } - } - - /// Disables the `help` [`subcommand`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let res = Command::new("myprog") - /// .disable_help_subcommand(true) - /// // Normally, creating a subcommand causes a `help` subcommand to automatically - /// // be generated as well - /// .subcommand(Command::new("test")) - /// .try_get_matches_from(vec![ - /// "myprog", "help" - /// ]); - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - /// - /// [`subcommand`]: crate::Command::subcommand() - #[inline] - pub fn disable_help_subcommand(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::DisableHelpSubcommand) - } else { - self.unset_global_setting(AppSettings::DisableHelpSubcommand) - } - } - - /// Disables colorized help messages. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .disable_colored_help(true) - /// .get_matches(); - /// ``` - #[inline] - pub fn disable_colored_help(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::DisableColoredHelp) - } else { - self.unset_global_setting(AppSettings::DisableColoredHelp) - } - } - - /// Panic if help descriptions are omitted. - /// - /// **NOTE:** When deriving [`Parser`][crate::Parser], you could instead check this at - /// compile-time with `#![deny(missing_docs)]` - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .help_expected(true) - /// .arg( - /// Arg::new("foo").help("It does foo stuff") - /// // As required via `help_expected`, a help message was supplied - /// ) - /// # .get_matches(); - /// ``` - /// - /// # Panics - /// - /// ```rust,no_run - /// # use clap::{Command, Arg}; - /// Command::new("myapp") - /// .help_expected(true) - /// .arg( - /// Arg::new("foo") - /// // Someone forgot to put .about("...") here - /// // Since the setting `help_expected` is activated, this will lead to - /// // a panic (if you are in debug mode) - /// ) - /// # .get_matches(); - ///``` - #[inline] - pub fn help_expected(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::HelpExpected) - } else { - self.unset_global_setting(AppSettings::HelpExpected) - } - } - - /// Disables the automatic collapsing of positional args into `[ARGS]` inside the usage string. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .dont_collapse_args_in_usage(true) - /// .get_matches(); - /// ``` - #[inline] - pub fn dont_collapse_args_in_usage(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::DontCollapseArgsInUsage) - } else { - self.unset_global_setting(AppSettings::DontCollapseArgsInUsage) - } - } - - /// Tells `clap` *not* to print possible values when displaying help information. - /// - /// This can be useful if there are many values, or they are explained elsewhere. - /// - /// To set this per argument, see - /// [`Arg::hide_possible_values`][crate::Arg::hide_possible_values]. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - #[inline] - pub fn hide_possible_values(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::HidePossibleValues) - } else { - self.unset_global_setting(AppSettings::HidePossibleValues) - } - } - - /// Allow partial matches of long arguments or their [aliases]. - /// - /// For example, to match an argument named `--test`, one could use `--t`, `--te`, `--tes`, and - /// `--test`. - /// - /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match - /// `--te` to `--test` there could not also be another argument or alias `--temp` because both - /// start with `--te` - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// [aliases]: crate::Command::aliases() - #[inline] - pub fn infer_long_args(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::InferLongArgs) - } else { - self.unset_global_setting(AppSettings::InferLongArgs) - } - } - - /// Allow partial matches of [subcommand] names and their [aliases]. - /// - /// For example, to match a subcommand named `test`, one could use `t`, `te`, `tes`, and - /// `test`. - /// - /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match `te` - /// to `test` there could not also be a subcommand or alias `temp` because both start with `te` - /// - /// **CAUTION:** This setting can interfere with [positional/free arguments], take care when - /// designing CLIs which allow inferred subcommands and have potential positional/free - /// arguments whose values could start with the same characters as subcommands. If this is the - /// case, it's recommended to use settings such as [`Command::args_conflicts_with_subcommands`] in - /// conjunction with this setting. - /// - /// **NOTE:** This choice is propagated to all child subcommands. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .infer_subcommands(true) - /// .subcommand(Command::new("test")) - /// .get_matches_from(vec![ - /// "prog", "te" - /// ]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// - /// [subcommand]: crate::Command::subcommand() - /// [positional/free arguments]: crate::Arg::index() - /// [aliases]: crate::Command::aliases() - #[inline] - pub fn infer_subcommands(self, yes: bool) -> Self { - if yes { - self.global_setting(AppSettings::InferSubcommands) - } else { - self.unset_global_setting(AppSettings::InferSubcommands) - } - } -} - -/// # Command-specific Settings -/// -/// These apply only to the current command and are not inherited by subcommands. -impl<'help> App<'help> { - /// (Re)Sets the program's name. - /// - /// See [`Command::new`] for more details. - /// - /// # Examples - /// - /// ```ignore - /// # use clap::{Command, load_yaml}; - /// let yaml = load_yaml!("cmd.yaml"); - /// let cmd = Command::from(yaml) - /// .name(crate_name!()); - /// - /// // continued logic goes here, such as `cmd.get_matches()` etc. - /// ``` - #[must_use] - pub fn name>(mut self, name: S) -> Self { - self.name = name.into(); - self - } - - /// Overrides the runtime-determined name of the binary for help and error messages. - /// - /// This should only be used when absolutely necessary, such as when the binary name for your - /// application is misleading, or perhaps *not* how the user should invoke your program. - /// - /// **Pro-tip:** When building things such as third party `cargo` - /// subcommands, this setting **should** be used! - /// - /// **NOTE:** This *does not* change or set the name of the binary file on - /// disk. It only changes what clap thinks the name is for the purposes of - /// error or help messages. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("My Program") - /// .bin_name("my_binary") - /// # ; - /// ``` - #[must_use] - pub fn bin_name>(mut self, name: S) -> Self { - self.bin_name = Some(name.into()); - self - } - - /// Overrides the runtime-determined display name of the program for help and error messages. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("My Program") - /// .display_name("my_program") - /// # ; - /// ``` - #[must_use] - pub fn display_name>(mut self, name: S) -> Self { - self.display_name = Some(name.into()); - self - } - - /// Sets the author(s) for the help message. - /// - /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to - /// automatically set your application's author(s) to the same thing as your - /// crate at compile time. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .author("Me, me@mymain.com") - /// # ; - /// ``` - /// [`crate_authors!`]: ./macro.crate_authors!.html - #[must_use] - pub fn author>(mut self, author: S) -> Self { - self.author = Some(author.into()); - self - } - - /// Sets the program's description for the short help (`-h`). - /// - /// If [`Command::long_about`] is not specified, this message will be displayed for `--help`. - /// - /// **NOTE:** Only `Command::about` (short format) is used in completion - /// script generation in order to be concise. - /// - /// See also [`crate_description!`](crate::crate_description!). - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .about("Does really amazing things for great people") - /// # ; - /// ``` - #[must_use] - pub fn about>>(mut self, about: O) -> Self { - self.about = about.into(); - self - } - - /// Sets the program's description for the long help (`--help`). - /// - /// If [`Command::about`] is not specified, this message will be displayed for `-h`. - /// - /// **NOTE:** Only [`Command::about`] (short format) is used in completion - /// script generation in order to be concise. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .long_about( - /// "Does really amazing things to great people. Now let's talk a little - /// more in depth about how this subcommand really works. It may take about - /// a few lines of text, but that's ok!") - /// # ; - /// ``` - /// [`App::about`]: Command::about() - #[must_use] - pub fn long_about>>(mut self, long_about: O) -> Self { - self.long_about = long_about.into(); - self - } - - /// Free-form help text for after auto-generated short help (`-h`). - /// - /// This is often used to describe how to use the arguments, caveats to be noted, or license - /// and contact information. - /// - /// If [`Command::after_long_help`] is not specified, this message will be displayed for `--help`. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .after_help("Does really amazing things for great people... but be careful with -R!") - /// # ; - /// ``` - /// - #[must_use] - pub fn after_help>(mut self, help: S) -> Self { - self.after_help = Some(help.into()); - self - } - - /// Free-form help text for after auto-generated long help (`--help`). - /// - /// This is often used to describe how to use the arguments, caveats to be noted, or license - /// and contact information. - /// - /// If [`Command::after_help`] is not specified, this message will be displayed for `-h`. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .after_long_help("Does really amazing things to great people... but be careful with -R, \ - /// like, for real, be careful with this!") - /// # ; - /// ``` - #[must_use] - pub fn after_long_help>(mut self, help: S) -> Self { - self.after_long_help = Some(help.into()); - self - } - - /// Free-form help text for before auto-generated short help (`-h`). - /// - /// This is often used for header, copyright, or license information. - /// - /// If [`Command::before_long_help`] is not specified, this message will be displayed for `--help`. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .before_help("Some info I'd like to appear before the help info") - /// # ; - /// ``` - #[must_use] - pub fn before_help>(mut self, help: S) -> Self { - self.before_help = Some(help.into()); - self - } - - /// Free-form help text for before auto-generated long help (`--help`). - /// - /// This is often used for header, copyright, or license information. - /// - /// If [`Command::before_help`] is not specified, this message will be displayed for `-h`. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .before_long_help("Some verbose and long info I'd like to appear before the help info") - /// # ; - /// ``` - #[must_use] - pub fn before_long_help>(mut self, help: S) -> Self { - self.before_long_help = Some(help.into()); - self - } - - /// Sets the version for the short version (`-V`) and help messages. - /// - /// If [`Command::long_version`] is not specified, this message will be displayed for `--version`. - /// - /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to - /// automatically set your application's version to the same thing as your - /// crate at compile time. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .version("v0.1.24") - /// # ; - /// ``` - /// [`crate_version!`]: ./macro.crate_version!.html - #[must_use] - pub fn version>(mut self, ver: S) -> Self { - self.version = Some(ver.into()); - self - } - - /// Sets the version for the long version (`--version`) and help messages. - /// - /// If [`Command::version`] is not specified, this message will be displayed for `-V`. - /// - /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to - /// automatically set your application's version to the same thing as your - /// crate at compile time. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .long_version( - /// "v0.1.24 - /// commit: abcdef89726d - /// revision: 123 - /// release: 2 - /// binary: myprog") - /// # ; - /// ``` - /// [`crate_version!`]: ./macro.crate_version!.html - #[must_use] - pub fn long_version>(mut self, ver: S) -> Self { - self.long_version = Some(ver.into()); - self - } - - /// Overrides the `clap` generated usage string for help and error messages. - /// - /// **NOTE:** Using this setting disables `clap`s "context-aware" usage - /// strings. After this setting is set, this will be *the only* usage string - /// displayed to the user! - /// - /// **NOTE:** Multiple usage lines may be present in the usage argument, but - /// some rules need to be followed to ensure the usage lines are formatted - /// correctly by the default help formatter: - /// - /// - Do not indent the first usage line. - /// - Indent all subsequent usage lines with four spaces. - /// - The last line must not end with a newline. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .override_usage("myapp [-clDas] ") - /// # ; - /// ``` - /// - /// Or for multiple usage lines: - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .override_usage( - /// "myapp -X [-a] [-b] \n \ - /// myapp -Y [-c] \n \ - /// myapp -Z [-d|-e]" - /// ) - /// # ; - /// ``` - /// - /// [`ArgMatches::usage`]: ArgMatches::usage() - #[must_use] - pub fn override_usage>(mut self, usage: S) -> Self { - self.usage_str = Some(usage.into()); - self - } - - /// Overrides the `clap` generated help message (both `-h` and `--help`). - /// - /// This should only be used when the auto-generated message does not suffice. - /// - /// **NOTE:** This **only** replaces the help message for the current - /// command, meaning if you are using subcommands, those help messages will - /// still be auto-generated unless you specify a [`Command::override_help`] for - /// them as well. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myapp") - /// .override_help("myapp v1.0\n\ - /// Does awesome things\n\ - /// (C) me@mail.com\n\n\ - /// - /// USAGE: myapp \n\n\ - /// - /// Options:\n\ - /// -h, --help Display this message\n\ - /// -V, --version Display version info\n\ - /// -s Do something with stuff\n\ - /// -v Be verbose\n\n\ - /// - /// Commands:\n\ - /// help Print this message\n\ - /// work Do some work") - /// # ; - /// ``` - #[must_use] - pub fn override_help>(mut self, help: S) -> Self { - self.help_str = Some(help.into()); - self - } - - /// Sets the help template to be used, overriding the default format. - /// - /// **NOTE:** The template system is by design very simple. Therefore, the - /// tags have to be written in the lowercase and without spacing. - /// - /// Tags are given inside curly brackets. - /// - /// Valid tags are: - /// - /// * `{name}` - Display name for the (sub-)command. - /// * `{bin}` - Binary name. - /// * `{version}` - Version number. - /// * `{author}` - Author information. - /// * `{author-with-newline}` - Author followed by `\n`. - /// * `{author-section}` - Author preceded and followed by `\n`. - /// * `{about}` - General description (from [`Command::about`] or - /// [`Command::long_about`]). - /// * `{about-with-newline}` - About followed by `\n`. - /// * `{about-section}` - About preceded and followed by '\n'. - /// * `{usage-heading}` - Automatically generated usage heading. - /// * `{usage}` - Automatically generated or given usage string. - /// * `{all-args}` - Help for all arguments (options, flags, positional - /// arguments, and subcommands) including titles. - /// * `{options}` - Help for options. - /// * `{positionals}` - Help for positional arguments. - /// * `{subcommands}` - Help for subcommands. - /// * `{after-help}` - Help from [`App::after_help`] or [`Command::after_long_help`]. - /// * `{before-help}` - Help from [`App::before_help`] or [`Command::before_long_help`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::Command; - /// Command::new("myprog") - /// .version("1.0") - /// .help_template("{bin} ({version}) - {usage}") - /// # ; - /// ``` - /// [`App::about`]: Command::about() - /// [`App::long_about`]: Command::long_about() - /// [`App::after_help`]: Command::after_help() - /// [`App::after_long_help`]: Command::after_long_help() - /// [`App::before_help`]: Command::before_help() - /// [`App::before_long_help`]: Command::before_long_help() - #[must_use] - pub fn help_template>(mut self, s: S) -> Self { - self.template = Some(s.into()); - self - } - - /// Apply a setting for the current command or subcommand. - /// - /// See [`Command::global_setting`] to apply a setting to this command and all subcommands. - /// - /// See [`AppSettings`] for a full list of possibilities and examples. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, AppSettings}; - /// Command::new("myprog") - /// .setting(AppSettings::SubcommandRequired) - /// .setting(AppSettings::AllowLeadingHyphen) - /// # ; - /// ``` - /// or - /// ```no_run - /// # use clap::{Command, AppSettings}; - /// Command::new("myprog") - /// .setting(AppSettings::SubcommandRequired | AppSettings::AllowLeadingHyphen) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.insert(setting.into()); - self - } - - /// Remove a setting for the current command or subcommand. - /// - /// See [`AppSettings`] for a full list of possibilities and examples. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, AppSettings}; - /// Command::new("myprog") - /// .unset_setting(AppSettings::SubcommandRequired) - /// .setting(AppSettings::AllowLeadingHyphen) - /// # ; - /// ``` - /// or - /// ```no_run - /// # use clap::{Command, AppSettings}; - /// Command::new("myprog") - /// .unset_setting(AppSettings::SubcommandRequired | AppSettings::AllowLeadingHyphen) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn unset_setting(mut self, setting: F) -> Self - where - F: Into, - { - self.settings.remove(setting.into()); - self - } - - /// Apply a setting for the current command and all subcommands. - /// - /// See [`Command::setting`] to apply a setting only to this command. - /// - /// See [`AppSettings`] for a full list of possibilities and examples. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, AppSettings}; - /// Command::new("myprog") - /// .global_setting(AppSettings::AllowNegativeNumbers) - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn global_setting(mut self, setting: AppSettings) -> Self { - self.settings.set(setting); - self.g_settings.set(setting); - self - } - - /// Remove a setting and stop propagating down to subcommands. - /// - /// See [`AppSettings`] for a full list of possibilities and examples. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, AppSettings}; - /// Command::new("myprog") - /// .unset_global_setting(AppSettings::AllowNegativeNumbers) - /// # ; - /// ``` - /// [global]: Command::global_setting() - #[inline] - #[must_use] - pub fn unset_global_setting(mut self, setting: AppSettings) -> Self { - self.settings.unset(setting); - self.g_settings.unset(setting); - self - } - - /// Deprecated, replaced with [`Command::next_help_heading`] - #[inline] - #[must_use] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `App::next_help_heading`") - )] - pub fn help_heading(self, heading: O) -> Self - where - O: Into>, - { - self.next_help_heading(heading) - } - - /// Set the default section heading for future args. - /// - /// This will be used for any arg that hasn't had [`Arg::help_heading`] called. - /// - /// This is useful if the default `OPTIONS` or `ARGS` headings are - /// not specific enough for one's use case. - /// - /// For subcommands, see [`Command::subcommand_help_heading`] - /// - /// [`App::arg`]: Command::arg() - /// [`Arg::help_heading`]: crate::Arg::help_heading() - #[inline] - #[must_use] - pub fn next_help_heading(mut self, heading: O) -> Self - where - O: Into>, - { - self.current_help_heading = heading.into(); - self - } - - /// Change the starting value for assigning future display orders for ags. - /// - /// This will be used for any arg that hasn't had [`Arg::display_order`] called. - #[inline] - #[must_use] - pub fn next_display_order(mut self, disp_ord: impl Into>) -> Self { - self.current_disp_ord = disp_ord.into(); - self - } - - /// Replaces an argument or subcommand used on the CLI at runtime with other arguments or subcommands. - /// - /// **Note:** This is gated behind [`unstable-replace`](https://github.com/clap-rs/clap/issues/2836) - /// - /// When this method is used, `name` is removed from the CLI, and `target` - /// is inserted in its place. Parsing continues as if the user typed - /// `target` instead of `name`. - /// - /// This can be used to create "shortcuts" for subcommands, or if a - /// particular argument has the semantic meaning of several other specific - /// arguments and values. - /// - /// # Examples - /// - /// We'll start with the "subcommand short" example. In this example, let's - /// assume we have a program with a subcommand `module` which can be invoked - /// via `cmd module`. Now let's also assume `module` also has a subcommand - /// called `install` which can be invoked `cmd module install`. If for some - /// reason users needed to be able to reach `cmd module install` via the - /// short-hand `cmd install`, we'd have several options. - /// - /// We *could* create another sibling subcommand to `module` called - /// `install`, but then we would need to manage another subcommand and manually - /// dispatch to `cmd module install` handling code. This is error prone and - /// tedious. - /// - /// We could instead use [`Command::replace`] so that, when the user types `cmd - /// install`, `clap` will replace `install` with `module install` which will - /// end up getting parsed as if the user typed the entire incantation. - /// - /// ```rust - /// # use clap::Command; - /// let m = Command::new("cmd") - /// .subcommand(Command::new("module") - /// .subcommand(Command::new("install"))) - /// .replace("install", &["module", "install"]) - /// .get_matches_from(vec!["cmd", "install"]); - /// - /// assert!(m.subcommand_matches("module").is_some()); - /// assert!(m.subcommand_matches("module").unwrap().subcommand_matches("install").is_some()); - /// ``` - /// - /// Now let's show an argument example! - /// - /// Let's assume we have an application with two flags `--save-context` and - /// `--save-runtime`. But often users end up needing to do *both* at the - /// same time. We can add a third flag `--save-all` which semantically means - /// the same thing as `cmd --save-context --save-runtime`. To implement that, - /// we have several options. - /// - /// We could create this third argument and manually check if that argument - /// and in our own consumer code handle the fact that both `--save-context` - /// and `--save-runtime` *should* have been used. But again this is error - /// prone and tedious. If we had code relying on checking `--save-context` - /// and we forgot to update that code to *also* check `--save-all` it'd mean - /// an error! - /// - /// Luckily we can use [`Command::replace`] so that when the user types - /// `--save-all`, `clap` will replace that argument with `--save-context - /// --save-runtime`, and parsing will continue like normal. Now all our code - /// that was originally checking for things like `--save-context` doesn't - /// need to change! - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("cmd") - /// .arg(Arg::new("save-context") - /// .long("save-context") - /// .action(ArgAction::SetTrue)) - /// .arg(Arg::new("save-runtime") - /// .long("save-runtime") - /// .action(ArgAction::SetTrue)) - /// .replace("--save-all", &["--save-context", "--save-runtime"]) - /// .get_matches_from(vec!["cmd", "--save-all"]); - /// - /// assert!(*m.get_one::("save-context").expect("defaulted by clap")); - /// assert!(*m.get_one::("save-runtime").expect("defaulted by clap")); - /// ``` - /// - /// This can also be used with options, for example if our application with - /// `--save-*` above also had a `--format=TYPE` option. Let's say it - /// accepted `txt` or `json` values. However, when `--save-all` is used, - /// only `--format=json` is allowed, or valid. We could change the example - /// above to enforce this: - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("cmd") - /// .arg(Arg::new("save-context") - /// .long("save-context") - /// .action(ArgAction::SetTrue)) - /// .arg(Arg::new("save-runtime") - /// .long("save-runtime") - /// .action(ArgAction::SetTrue)) - /// .arg(Arg::new("format") - /// .long("format") - /// .takes_value(true) - /// .value_parser(["txt", "json"])) - /// .replace("--save-all", &["--save-context", "--save-runtime", "--format=json"]) - /// .get_matches_from(vec!["cmd", "--save-all"]); - /// - /// assert!(*m.get_one::("save-context").expect("defaulted by clap")); - /// assert!(*m.get_one::("save-runtime").expect("defaulted by clap")); - /// assert_eq!(m.value_of("format"), Some("json")); - /// ``` - /// - /// [`App::replace`]: Command::replace() - #[inline] - #[cfg(feature = "unstable-replace")] - #[must_use] - pub fn replace(mut self, name: &'help str, target: &'help [&'help str]) -> Self { - self.replacers.insert(name, target); - self - } - - /// Exit gracefully if no arguments are present (e.g. `$ myprog`). - /// - /// **NOTE:** [`subcommands`] count as arguments - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command}; - /// Command::new("myprog") - /// .arg_required_else_help(true); - /// ``` - /// - /// [`subcommands`]: crate::Command::subcommand() - /// [`Arg::default_value`]: crate::Arg::default_value() - #[inline] - pub fn arg_required_else_help(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::ArgRequiredElseHelp) - } else { - self.unset_setting(AppSettings::ArgRequiredElseHelp) - } - } - - /// Specifies that leading hyphens are allowed in all argument *values* (e.g. `-10`). - /// - /// Otherwise they will be parsed as another flag or option. See also - /// [`Command::allow_negative_numbers`]. - /// - /// **NOTE:** Use this setting with caution as it silences certain circumstances which would - /// otherwise be an error (such as accidentally forgetting to specify a value for leading - /// option). It is preferred to set this on a per argument basis, via [`Arg::allow_hyphen_values`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Arg, Command}; - /// // Imagine you needed to represent negative numbers as well, such as -10 - /// let m = Command::new("nums") - /// .allow_hyphen_values(true) - /// .arg(Arg::new("neg")) - /// .get_matches_from(vec![ - /// "nums", "-20" - /// ]); - /// - /// assert_eq!(m.value_of("neg"), Some("-20")); - /// # ; - /// ``` - /// [`Arg::allow_hyphen_values`]: crate::Arg::allow_hyphen_values() - #[inline] - pub fn allow_hyphen_values(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::AllowHyphenValues) - } else { - self.unset_setting(AppSettings::AllowHyphenValues) - } - } - - /// Allows negative numbers to pass as values. - /// - /// This is similar to [`Command::allow_hyphen_values`] except that it only allows numbers, - /// all other undefined leading hyphens will fail to parse. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let res = Command::new("myprog") - /// .allow_negative_numbers(true) - /// .arg(Arg::new("num")) - /// .try_get_matches_from(vec![ - /// "myprog", "-20" - /// ]); - /// assert!(res.is_ok()); - /// let m = res.unwrap(); - /// assert_eq!(m.value_of("num").unwrap(), "-20"); - /// ``` - #[inline] - pub fn allow_negative_numbers(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::AllowNegativeNumbers) - } else { - self.unset_setting(AppSettings::AllowNegativeNumbers) - } - } - - /// Specifies that the final positional argument is a "VarArg" and that `clap` should not - /// attempt to parse any further args. - /// - /// The values of the trailing positional argument will contain all args from itself on. - /// - /// **NOTE:** The final positional argument **must** have [`Arg::multiple_values(true)`] or the usage - /// string equivalent. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, arg}; - /// let m = Command::new("myprog") - /// .trailing_var_arg(true) - /// .arg(arg!( ... "commands to run")) - /// .get_matches_from(vec!["myprog", "arg1", "-r", "val1"]); - /// - /// let trail: Vec<&str> = m.values_of("cmd").unwrap().collect(); - /// assert_eq!(trail, ["arg1", "-r", "val1"]); - /// ``` - /// [`Arg::multiple_values(true)`]: crate::Arg::multiple_values() - pub fn trailing_var_arg(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::TrailingVarArg) - } else { - self.unset_setting(AppSettings::TrailingVarArg) - } - } - - /// Allows one to implement two styles of CLIs where positionals can be used out of order. - /// - /// The first example is a CLI where the second to last positional argument is optional, but - /// the final positional argument is required. Such as `$ prog [optional] ` where one - /// of the two following usages is allowed: - /// - /// * `$ prog [optional] ` - /// * `$ prog ` - /// - /// This would otherwise not be allowed. This is useful when `[optional]` has a default value. - /// - /// **Note:** when using this style of "missing positionals" the final positional *must* be - /// [required] if `--` will not be used to skip to the final positional argument. - /// - /// **Note:** This style also only allows a single positional argument to be "skipped" without - /// the use of `--`. To skip more than one, see the second example. - /// - /// The second example is when one wants to skip multiple optional positional arguments, and use - /// of the `--` operator is OK (but not required if all arguments will be specified anyways). - /// - /// For example, imagine a CLI which has three positional arguments `[foo] [bar] [baz]...` where - /// `baz` accepts multiple values (similar to man `ARGS...` style training arguments). - /// - /// With this setting the following invocations are posisble: - /// - /// * `$ prog foo bar baz1 baz2 baz3` - /// * `$ prog foo -- baz1 baz2 baz3` - /// * `$ prog -- baz1 baz2 baz3` - /// - /// # Examples - /// - /// Style number one from above: - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// // Assume there is an external subcommand named "subcmd" - /// let m = Command::new("myprog") - /// .allow_missing_positional(true) - /// .arg(Arg::new("arg1")) - /// .arg(Arg::new("arg2") - /// .required(true)) - /// .get_matches_from(vec![ - /// "prog", "other" - /// ]); - /// - /// assert_eq!(m.value_of("arg1"), None); - /// assert_eq!(m.value_of("arg2"), Some("other")); - /// ``` - /// - /// Now the same example, but using a default value for the first optional positional argument - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// // Assume there is an external subcommand named "subcmd" - /// let m = Command::new("myprog") - /// .allow_missing_positional(true) - /// .arg(Arg::new("arg1") - /// .default_value("something")) - /// .arg(Arg::new("arg2") - /// .required(true)) - /// .get_matches_from(vec![ - /// "prog", "other" - /// ]); - /// - /// assert_eq!(m.value_of("arg1"), Some("something")); - /// assert_eq!(m.value_of("arg2"), Some("other")); - /// ``` - /// - /// Style number two from above: - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// // Assume there is an external subcommand named "subcmd" - /// let m = Command::new("myprog") - /// .allow_missing_positional(true) - /// .arg(Arg::new("foo")) - /// .arg(Arg::new("bar")) - /// .arg(Arg::new("baz").takes_value(true).multiple_values(true)) - /// .get_matches_from(vec![ - /// "prog", "foo", "bar", "baz1", "baz2", "baz3" - /// ]); - /// - /// assert_eq!(m.value_of("foo"), Some("foo")); - /// assert_eq!(m.value_of("bar"), Some("bar")); - /// assert_eq!(m.values_of("baz").unwrap().collect::>(), &["baz1", "baz2", "baz3"]); - /// ``` - /// - /// Now nofice if we don't specify `foo` or `baz` but use the `--` operator. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// // Assume there is an external subcommand named "subcmd" - /// let m = Command::new("myprog") - /// .allow_missing_positional(true) - /// .arg(Arg::new("foo")) - /// .arg(Arg::new("bar")) - /// .arg(Arg::new("baz").takes_value(true).multiple_values(true)) - /// .get_matches_from(vec![ - /// "prog", "--", "baz1", "baz2", "baz3" - /// ]); - /// - /// assert_eq!(m.value_of("foo"), None); - /// assert_eq!(m.value_of("bar"), None); - /// assert_eq!(m.values_of("baz").unwrap().collect::>(), &["baz1", "baz2", "baz3"]); - /// ``` - /// - /// [required]: crate::Arg::required() - #[inline] - pub fn allow_missing_positional(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::AllowMissingPositional) - } else { - self.unset_setting(AppSettings::AllowMissingPositional) - } - } -} - -/// # Subcommand-specific Settings -impl<'help> App<'help> { - /// Sets the short version of the subcommand flag without the preceding `-`. - /// - /// Allows the subcommand to be used as if it were an [`Arg::short`]. - /// - /// # Examples - /// - /// ``` - /// # use clap::{Command, Arg, ArgAction}; - /// let matches = Command::new("pacman") - /// .subcommand( - /// Command::new("sync").short_flag('S').arg( - /// Arg::new("search") - /// .short('s') - /// .long("search") - /// .action(ArgAction::SetTrue) - /// .help("search remote repositories for matching strings"), - /// ), - /// ) - /// .get_matches_from(vec!["pacman", "-Ss"]); - /// - /// assert_eq!(matches.subcommand_name().unwrap(), "sync"); - /// let sync_matches = matches.subcommand_matches("sync").unwrap(); - /// assert!(*sync_matches.get_one::("search").expect("defaulted by clap")); - /// ``` - /// [`Arg::short`]: Arg::short() - #[must_use] - pub fn short_flag(mut self, short: char) -> Self { - self.short_flag = Some(short); - self - } - - /// Sets the long version of the subcommand flag without the preceding `--`. - /// - /// Allows the subcommand to be used as if it were an [`Arg::long`]. - /// - /// **NOTE:** Any leading `-` characters will be stripped. - /// - /// # Examples - /// - /// To set `long_flag` use a word containing valid UTF-8 codepoints. If you supply a double leading - /// `--` such as `--sync` they will be stripped. Hyphens in the middle of the word; however, - /// will *not* be stripped (i.e. `sync-file` is allowed). - /// - /// ``` - /// # use clap::{Command, Arg, ArgAction}; - /// let matches = Command::new("pacman") - /// .subcommand( - /// Command::new("sync").long_flag("sync").arg( - /// Arg::new("search") - /// .short('s') - /// .long("search") - /// .action(ArgAction::SetTrue) - /// .help("search remote repositories for matching strings"), - /// ), - /// ) - /// .get_matches_from(vec!["pacman", "--sync", "--search"]); - /// - /// assert_eq!(matches.subcommand_name().unwrap(), "sync"); - /// let sync_matches = matches.subcommand_matches("sync").unwrap(); - /// assert!(*sync_matches.get_one::("search").expect("defaulted by clap")); - /// ``` - /// - /// [`Arg::long`]: Arg::long() - #[must_use] - pub fn long_flag(mut self, long: &'help str) -> Self { - #[cfg(feature = "unstable-v4")] - { - self.long_flag = Some(long); - } - #[cfg(not(feature = "unstable-v4"))] - { - self.long_flag = Some(long.trim_start_matches(|c| c == '-')); - } - self - } - - /// Sets a hidden alias to this subcommand. - /// - /// This allows the subcommand to be accessed via *either* the original name, or this given - /// alias. This is more efficient and easier than creating multiple hidden subcommands as one - /// only needs to check for the existence of this command, and not all aliased variants. - /// - /// **NOTE:** Aliases defined with this method are *hidden* from the help - /// message. If you're looking for aliases that will be displayed in the help - /// message, see [`Command::visible_alias`]. - /// - /// **NOTE:** When using aliases and checking for the existence of a - /// particular subcommand within an [`ArgMatches`] struct, one only needs to - /// search for the original name and not all aliases. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test") - /// .alias("do-stuff")) - /// .get_matches_from(vec!["myprog", "do-stuff"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::visible_alias`]: Command::visible_alias() - #[must_use] - pub fn alias>(mut self, name: S) -> Self { - self.aliases.push((name.into(), false)); - self - } - - /// Add an alias, which functions as "hidden" short flag subcommand - /// - /// This will automatically dispatch as if this subcommand was used. This is more efficient, - /// and easier than creating multiple hidden subcommands as one only needs to check for the - /// existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").short_flag('t') - /// .short_flag_alias('d')) - /// .get_matches_from(vec!["myprog", "-d"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - #[must_use] - pub fn short_flag_alias(mut self, name: char) -> Self { - assert!(name != '-', "short alias name cannot be `-`"); - self.short_flag_aliases.push((name, false)); - self - } - - /// Add an alias, which functions as a "hidden" long flag subcommand. - /// - /// This will automatically dispatch as if this subcommand was used. This is more efficient, - /// and easier than creating multiple hidden subcommands as one only needs to check for the - /// existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").long_flag("test") - /// .long_flag_alias("testing")) - /// .get_matches_from(vec!["myprog", "--testing"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - #[must_use] - pub fn long_flag_alias(mut self, name: &'help str) -> Self { - self.long_flag_aliases.push((name, false)); - self - } - - /// Sets multiple hidden aliases to this subcommand. - /// - /// This allows the subcommand to be accessed via *either* the original name or any of the - /// given aliases. This is more efficient, and easier than creating multiple hidden subcommands - /// as one only needs to check for the existence of this command and not all aliased variants. - /// - /// **NOTE:** Aliases defined with this method are *hidden* from the help - /// message. If looking for aliases that will be displayed in the help - /// message, see [`Command::visible_aliases`]. - /// - /// **NOTE:** When using aliases and checking for the existence of a - /// particular subcommand within an [`ArgMatches`] struct, one only needs to - /// search for the original name and not all aliases. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test") - /// .aliases(&["do-stuff", "do-tests", "tests"])) - /// .arg(Arg::new("input") - /// .help("the file to add") - /// .required(false)) - /// .get_matches_from(vec!["myprog", "do-tests"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::visible_aliases`]: Command::visible_aliases() - #[must_use] - pub fn aliases(mut self, names: &[&'help str]) -> Self { - self.aliases.extend(names.iter().map(|n| (*n, false))); - self - } - - /// Add aliases, which function as "hidden" short flag subcommands. - /// - /// These will automatically dispatch as if this subcommand was used. This is more efficient, - /// and easier than creating multiple hidden subcommands as one only needs to check for the - /// existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").short_flag('t') - /// .short_flag_aliases(&['a', 'b', 'c'])) - /// .arg(Arg::new("input") - /// .help("the file to add") - /// .required(false)) - /// .get_matches_from(vec!["myprog", "-a"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - #[must_use] - pub fn short_flag_aliases(mut self, names: &[char]) -> Self { - for s in names { - assert!(s != &'-', "short alias name cannot be `-`"); - self.short_flag_aliases.push((*s, false)); - } - self - } - - /// Add aliases, which function as "hidden" long flag subcommands. - /// - /// These will automatically dispatch as if this subcommand was used. This is more efficient, - /// and easier than creating multiple hidden subcommands as one only needs to check for the - /// existence of this command, and not all variants. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").long_flag("test") - /// .long_flag_aliases(&["testing", "testall", "test_all"])) - /// .arg(Arg::new("input") - /// .help("the file to add") - /// .required(false)) - /// .get_matches_from(vec!["myprog", "--testing"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - #[must_use] - pub fn long_flag_aliases(mut self, names: &[&'help str]) -> Self { - for s in names { - self.long_flag_aliases.push((s, false)); - } - self - } - - /// Sets a visible alias to this subcommand. - /// - /// This allows the subcommand to be accessed via *either* the - /// original name or the given alias. This is more efficient and easier - /// than creating hidden subcommands as one only needs to check for - /// the existence of this command and not all aliased variants. - /// - /// **NOTE:** The alias defined with this method is *visible* from the help - /// message and displayed as if it were just another regular subcommand. If - /// looking for an alias that will not be displayed in the help message, see - /// [`Command::alias`]. - /// - /// **NOTE:** When using aliases and checking for the existence of a - /// particular subcommand within an [`ArgMatches`] struct, one only needs to - /// search for the original name and not all aliases. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test") - /// .visible_alias("do-stuff")) - /// .get_matches_from(vec!["myprog", "do-stuff"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::alias`]: Command::alias() - #[must_use] - pub fn visible_alias>(mut self, name: S) -> Self { - self.aliases.push((name.into(), true)); - self - } - - /// Add an alias, which functions as "visible" short flag subcommand - /// - /// This will automatically dispatch as if this subcommand was used. This is more efficient, - /// and easier than creating multiple hidden subcommands as one only needs to check for the - /// existence of this command, and not all variants. - /// - /// See also [`Command::short_flag_alias`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").short_flag('t') - /// .visible_short_flag_alias('d')) - /// .get_matches_from(vec!["myprog", "-d"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::short_flag_alias`]: Command::short_flag_alias() - #[must_use] - pub fn visible_short_flag_alias(mut self, name: char) -> Self { - assert!(name != '-', "short alias name cannot be `-`"); - self.short_flag_aliases.push((name, true)); - self - } - - /// Add an alias, which functions as a "visible" long flag subcommand. - /// - /// This will automatically dispatch as if this subcommand was used. This is more efficient, - /// and easier than creating multiple hidden subcommands as one only needs to check for the - /// existence of this command, and not all variants. - /// - /// See also [`Command::long_flag_alias`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").long_flag("test") - /// .visible_long_flag_alias("testing")) - /// .get_matches_from(vec!["myprog", "--testing"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::long_flag_alias`]: Command::long_flag_alias() - #[must_use] - pub fn visible_long_flag_alias(mut self, name: &'help str) -> Self { - self.long_flag_aliases.push((name, true)); - self - } - - /// Sets multiple visible aliases to this subcommand. - /// - /// This allows the subcommand to be accessed via *either* the - /// original name or any of the given aliases. This is more efficient and easier - /// than creating multiple hidden subcommands as one only needs to check for - /// the existence of this command and not all aliased variants. - /// - /// **NOTE:** The alias defined with this method is *visible* from the help - /// message and displayed as if it were just another regular subcommand. If - /// looking for an alias that will not be displayed in the help message, see - /// [`Command::alias`]. - /// - /// **NOTE:** When using aliases, and checking for the existence of a - /// particular subcommand within an [`ArgMatches`] struct, one only needs to - /// search for the original name and not all aliases. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test") - /// .visible_aliases(&["do-stuff", "tests"])) - /// .get_matches_from(vec!["myprog", "do-stuff"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::alias`]: Command::alias() - #[must_use] - pub fn visible_aliases(mut self, names: &[&'help str]) -> Self { - self.aliases.extend(names.iter().map(|n| (*n, true))); - self - } - - /// Add aliases, which function as *visible* short flag subcommands. - /// - /// See [`Command::short_flag_aliases`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").short_flag('b') - /// .visible_short_flag_aliases(&['t'])) - /// .get_matches_from(vec!["myprog", "-t"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::short_flag_aliases`]: Command::short_flag_aliases() - #[must_use] - pub fn visible_short_flag_aliases(mut self, names: &[char]) -> Self { - for s in names { - assert!(s != &'-', "short alias name cannot be `-`"); - self.short_flag_aliases.push((*s, true)); - } - self - } - - /// Add aliases, which function as *visible* long flag subcommands. - /// - /// See [`Command::long_flag_aliases`]. - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let m = Command::new("myprog") - /// .subcommand(Command::new("test").long_flag("test") - /// .visible_long_flag_aliases(&["testing", "testall", "test_all"])) - /// .get_matches_from(vec!["myprog", "--testing"]); - /// assert_eq!(m.subcommand_name(), Some("test")); - /// ``` - /// [`App::long_flag_aliases`]: Command::long_flag_aliases() - #[must_use] - pub fn visible_long_flag_aliases(mut self, names: &[&'help str]) -> Self { - for s in names { - self.long_flag_aliases.push((s, true)); - } - self - } - - /// Set the placement of this subcommand within the help. - /// - /// Subcommands with a lower value will be displayed first in the help message. Subcommands - /// with duplicate display orders will be displayed in alphabetical order. - /// - /// This is helpful when one would like to emphasize frequently used subcommands, or prioritize - /// those towards the top of the list. - /// - /// **NOTE:** The default is 999 for all subcommands. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, }; - /// let m = Command::new("cust-ord") - /// .subcommand(Command::new("alpha") // typically subcommands are grouped - /// // alphabetically by name. Subcommands - /// // without a display_order have a value of - /// // 999 and are displayed alphabetically with - /// // all other 999 subcommands - /// .about("Some help and text")) - /// .subcommand(Command::new("beta") - /// .display_order(1) // In order to force this subcommand to appear *first* - /// // all we have to do is give it a value lower than 999. - /// // Any other subcommands with a value of 1 will be displayed - /// // alphabetically with this one...then 2 values, then 3, etc. - /// .about("I should be first!")) - /// .get_matches_from(vec![ - /// "cust-ord", "--help" - /// ]); - /// ``` - /// - /// The above example displays the following help message - /// - /// ```text - /// cust-ord - /// - /// USAGE: - /// cust-ord [OPTIONS] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// - /// SUBCOMMANDS: - /// beta I should be first! - /// alpha Some help and text - /// ``` - #[inline] - #[must_use] - pub fn display_order(mut self, ord: usize) -> Self { - self.disp_ord = Some(ord); - self - } - - /// Specifies that this [`subcommand`] should be hidden from help messages - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .subcommand( - /// Command::new("test").hide(true) - /// ) - /// # ; - /// ``` - /// - /// [`subcommand`]: crate::Command::subcommand() - #[inline] - pub fn hide(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::Hidden) - } else { - self.unset_setting(AppSettings::Hidden) - } - } - - /// If no [`subcommand`] is present at runtime, error and exit gracefully. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let err = Command::new("myprog") - /// .subcommand_required(true) - /// .subcommand(Command::new("test")) - /// .try_get_matches_from(vec![ - /// "myprog", - /// ]); - /// assert!(err.is_err()); - /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand); - /// # ; - /// ``` - /// - /// [`subcommand`]: crate::Command::subcommand() - pub fn subcommand_required(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::SubcommandRequired) - } else { - self.unset_setting(AppSettings::SubcommandRequired) - } - } - - /// Assume unexpected positional arguments are a [`subcommand`]. - /// - /// Arguments will be stored in the `""` argument in the [`ArgMatches`] - /// - /// **NOTE:** Use this setting with caution, - /// as a truly unexpected argument (i.e. one that is *NOT* an external subcommand) - /// will **not** cause an error and instead be treated as a potential subcommand. - /// One should check for such cases manually and inform the user appropriately. - /// - /// **NOTE:** A built-in subcommand will be parsed as an external subcommand when escaped with - /// `--`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// // Assume there is an external subcommand named "subcmd" - /// let m = Command::new("myprog") - /// .allow_external_subcommands(true) - /// .get_matches_from(vec![ - /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" - /// ]); - /// - /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty - /// // string argument name - /// match m.subcommand() { - /// Some((external, ext_m)) => { - /// let ext_args: Vec<&str> = ext_m.values_of("").unwrap().collect(); - /// assert_eq!(external, "subcmd"); - /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); - /// }, - /// _ => {}, - /// } - /// ``` - /// - /// [`subcommand`]: crate::Command::subcommand() - /// [`ArgMatches`]: crate::ArgMatches - /// [`ErrorKind::UnknownArgument`]: crate::ErrorKind::UnknownArgument - pub fn allow_external_subcommands(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::AllowExternalSubcommands) - } else { - self.unset_setting(AppSettings::AllowExternalSubcommands) - } - } - - /// Specifies that external subcommands that are invalid UTF-8 should *not* be treated as an error. - /// - /// **NOTE:** Using external subcommand argument values with invalid UTF-8 requires using - /// [`ArgMatches::values_of_os`] or [`ArgMatches::values_of_lossy`] for those particular - /// arguments which may contain invalid UTF-8 values - /// - /// **NOTE:** Setting this requires [`Command::allow_external_subcommands`] - /// - /// # Platform Specific - /// - /// Non Windows systems only - /// - /// # Examples - /// - #[cfg_attr(not(unix), doc = " ```ignore")] - #[cfg_attr(unix, doc = " ```")] - /// # use clap::Command; - /// // Assume there is an external subcommand named "subcmd" - /// let m = Command::new("myprog") - /// .allow_invalid_utf8_for_external_subcommands(true) - /// .allow_external_subcommands(true) - /// .get_matches_from(vec![ - /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" - /// ]); - /// - /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty - /// // string argument name - /// match m.subcommand() { - /// Some((external, ext_m)) => { - /// let ext_args: Vec<&std::ffi::OsStr> = ext_m.values_of_os("").unwrap().collect(); - /// assert_eq!(external, "subcmd"); - /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); - /// }, - /// _ => {}, - /// } - /// ``` - /// - /// [`ArgMatches::values_of_os`]: crate::ArgMatches::values_of_os() - /// [`ArgMatches::values_of_lossy`]: crate::ArgMatches::values_of_lossy() - /// [`subcommands`]: crate::Command::subcommand() - pub fn allow_invalid_utf8_for_external_subcommands(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::AllowInvalidUtf8ForExternalSubcommands) - } else { - self.unset_setting(AppSettings::AllowInvalidUtf8ForExternalSubcommands) - } - } - - /// Specifies that use of an argument prevents the use of [`subcommands`]. - /// - /// By default `clap` allows arguments between subcommands such - /// as ` [cmd_args] [subcmd_args] [subsubcmd_args]`. - /// - /// This setting disables that functionality and says that arguments can - /// only follow the *final* subcommand. For instance using this setting - /// makes only the following invocations possible: - /// - /// * ` [subsubcmd_args]` - /// * ` [subcmd_args]` - /// * ` [cmd_args]` - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// Command::new("myprog") - /// .args_conflicts_with_subcommands(true); - /// ``` - /// - /// [`subcommands`]: crate::Command::subcommand() - pub fn args_conflicts_with_subcommands(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::ArgsNegateSubcommands) - } else { - self.unset_setting(AppSettings::ArgsNegateSubcommands) - } - } - - /// Prevent subcommands from being consumed as an arguments value. - /// - /// By default, if an option taking multiple values is followed by a subcommand, the - /// subcommand will be parsed as another value. - /// - /// ```text - /// cmd --foo val1 val2 subcommand - /// --------- ---------- - /// values another value - /// ``` - /// - /// This setting instructs the parser to stop when encountering a subcommand instead of - /// greedily consuming arguments. - /// - /// ```text - /// cmd --foo val1 val2 subcommand - /// --------- ---------- - /// values subcommand - /// ``` - /// - /// **Note:** Make sure you apply it as `global_setting` if you want this setting - /// to be propagated to subcommands and sub-subcommands! - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let cmd = Command::new("cmd").subcommand(Command::new("sub")).arg( - /// Arg::new("arg") - /// .long("arg") - /// .multiple_values(true) - /// .takes_value(true), - /// ); - /// - /// let matches = cmd - /// .clone() - /// .try_get_matches_from(&["cmd", "--arg", "1", "2", "3", "sub"]) - /// .unwrap(); - /// assert_eq!( - /// matches.values_of("arg").unwrap().collect::>(), - /// &["1", "2", "3", "sub"] - /// ); - /// assert!(matches.subcommand_matches("sub").is_none()); - /// - /// let matches = cmd - /// .subcommand_precedence_over_arg(true) - /// .try_get_matches_from(&["cmd", "--arg", "1", "2", "3", "sub"]) - /// .unwrap(); - /// assert_eq!( - /// matches.values_of("arg").unwrap().collect::>(), - /// &["1", "2", "3"] - /// ); - /// assert!(matches.subcommand_matches("sub").is_some()); - /// ``` - pub fn subcommand_precedence_over_arg(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::SubcommandPrecedenceOverArg) - } else { - self.unset_setting(AppSettings::SubcommandPrecedenceOverArg) - } - } - - /// Allows [`subcommands`] to override all requirements of the parent command. - /// - /// For example, if you had a subcommand or top level application with a required argument - /// that is only required as long as there is no subcommand present, - /// using this setting would allow you to set those arguments to [`Arg::required(true)`] - /// and yet receive no error so long as the user uses a valid subcommand instead. - /// - /// **NOTE:** This defaults to false (using subcommand does *not* negate requirements) - /// - /// # Examples - /// - /// This first example shows that it is an error to not use a required argument - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let err = Command::new("myprog") - /// .subcommand_negates_reqs(true) - /// .arg(Arg::new("opt").required(true)) - /// .subcommand(Command::new("test")) - /// .try_get_matches_from(vec![ - /// "myprog" - /// ]); - /// assert!(err.is_err()); - /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// # ; - /// ``` - /// - /// This next example shows that it is no longer error to not use a required argument if a - /// valid subcommand is used. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let noerr = Command::new("myprog") - /// .subcommand_negates_reqs(true) - /// .arg(Arg::new("opt").required(true)) - /// .subcommand(Command::new("test")) - /// .try_get_matches_from(vec![ - /// "myprog", "test" - /// ]); - /// assert!(noerr.is_ok()); - /// # ; - /// ``` - /// - /// [`Arg::required(true)`]: crate::Arg::required() - /// [`subcommands`]: crate::Command::subcommand() - pub fn subcommand_negates_reqs(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::SubcommandsNegateReqs) - } else { - self.unset_setting(AppSettings::SubcommandsNegateReqs) - } - } - - /// Multiple-personality program dispatched on the binary name (`argv[0]`) - /// - /// A "multicall" executable is a single executable - /// that contains a variety of applets, - /// and decides which applet to run based on the name of the file. - /// The executable can be called from different names by creating hard links - /// or symbolic links to it. - /// - /// This is desirable for: - /// - Easy distribution, a single binary that can install hardlinks to access the different - /// personalities. - /// - Minimal binary size by sharing common code (e.g. standard library, clap) - /// - Custom shells or REPLs where there isn't a single top-level command - /// - /// Setting `multicall` will cause - /// - `argv[0]` to be stripped to the base name and parsed as the first argument, as if - /// [`Command::no_binary_name`][App::no_binary_name] was set. - /// - Help and errors to report subcommands as if they were the top-level command - /// - /// When the subcommand is not present, there are several strategies you may employ, depending - /// on your needs: - /// - Let the error percolate up normally - /// - Print a specialized error message using the - /// [`Error::context`][crate::Error::context] - /// - Print the [help][App::write_help] but this might be ambiguous - /// - Disable `multicall` and re-parse it - /// - Disable `multicall` and re-parse it with a specific subcommand - /// - /// When detecting the error condition, the [`ErrorKind`] isn't sufficient as a sub-subcommand - /// might report the same error. Enable - /// [`allow_external_subcommands`][App::allow_external_subcommands] if you want to specifically - /// get the unrecognized binary name. - /// - /// **NOTE:** Multicall can't be used with [`no_binary_name`] since they interpret - /// the command name in incompatible ways. - /// - /// **NOTE:** The multicall command cannot have arguments. - /// - /// **NOTE:** Applets are slightly semantically different from subcommands, - /// so it's recommended to use [`Command::subcommand_help_heading`] and - /// [`Command::subcommand_value_name`] to change the descriptive text as above. - /// - /// # Examples - /// - /// `hostname` is an example of a multicall executable. - /// Both `hostname` and `dnsdomainname` are provided by the same executable - /// and which behaviour to use is based on the executable file name. - /// - /// This is desirable when the executable has a primary purpose - /// but there is related functionality that would be convenient to provide - /// and implement it to be in the same executable. - /// - /// The name of the cmd is essentially unused - /// and may be the same as the name of a subcommand. - /// - /// The names of the immediate subcommands of the Command - /// are matched against the basename of the first argument, - /// which is conventionally the path of the executable. - /// - /// This does not allow the subcommand to be passed as the first non-path argument. - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let mut cmd = Command::new("hostname") - /// .multicall(true) - /// .subcommand(Command::new("hostname")) - /// .subcommand(Command::new("dnsdomainname")); - /// let m = cmd.try_get_matches_from_mut(&["/usr/bin/hostname", "dnsdomainname"]); - /// assert!(m.is_err()); - /// assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// let m = cmd.get_matches_from(&["/usr/bin/dnsdomainname"]); - /// assert_eq!(m.subcommand_name(), Some("dnsdomainname")); - /// ``` - /// - /// Busybox is another common example of a multicall executable - /// with a subcommmand for each applet that can be run directly, - /// e.g. with the `cat` applet being run by running `busybox cat`, - /// or with `cat` as a link to the `busybox` binary. - /// - /// This is desirable when the launcher program has additional options - /// or it is useful to run the applet without installing a symlink - /// e.g. to test the applet without installing it - /// or there may already be a command of that name installed. - /// - /// To make an applet usable as both a multicall link and a subcommand - /// the subcommands must be defined both in the top-level Command - /// and as subcommands of the "main" applet. - /// - /// ```rust - /// # use clap::Command; - /// fn applet_commands() -> [Command<'static>; 2] { - /// [Command::new("true"), Command::new("false")] - /// } - /// let mut cmd = Command::new("busybox") - /// .multicall(true) - /// .subcommand( - /// Command::new("busybox") - /// .subcommand_value_name("APPLET") - /// .subcommand_help_heading("APPLETS") - /// .subcommands(applet_commands()), - /// ) - /// .subcommands(applet_commands()); - /// // When called from the executable's canonical name - /// // its applets can be matched as subcommands. - /// let m = cmd.try_get_matches_from_mut(&["/usr/bin/busybox", "true"]).unwrap(); - /// assert_eq!(m.subcommand_name(), Some("busybox")); - /// assert_eq!(m.subcommand().unwrap().1.subcommand_name(), Some("true")); - /// // When called from a link named after an applet that applet is matched. - /// let m = cmd.get_matches_from(&["/usr/bin/true"]); - /// assert_eq!(m.subcommand_name(), Some("true")); - /// ``` - /// - /// [`no_binary_name`]: crate::Command::no_binary_name - /// [`App::subcommand_value_name`]: crate::Command::subcommand_value_name - /// [`App::subcommand_help_heading`]: crate::Command::subcommand_help_heading - #[inline] - pub fn multicall(self, yes: bool) -> Self { - if yes { - self.setting(AppSettings::Multicall) - } else { - self.unset_setting(AppSettings::Multicall) - } - } - - /// Sets the value name used for subcommands when printing usage and help. - /// - /// By default, this is "SUBCOMMAND". - /// - /// See also [`Command::subcommand_help_heading`] - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .subcommand(Command::new("sub1")) - /// .print_help() - /// # ; - /// ``` - /// - /// will produce - /// - /// ```text - /// myprog - /// - /// USAGE: - /// myprog [SUBCOMMAND] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// - /// SUBCOMMANDS: - /// help Print this message or the help of the given subcommand(s) - /// sub1 - /// ``` - /// - /// but usage of `subcommand_value_name` - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .subcommand(Command::new("sub1")) - /// .subcommand_value_name("THING") - /// .print_help() - /// # ; - /// ``` - /// - /// will produce - /// - /// ```text - /// myprog - /// - /// USAGE: - /// myprog [THING] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// - /// SUBCOMMANDS: - /// help Print this message or the help of the given subcommand(s) - /// sub1 - /// ``` - #[must_use] - pub fn subcommand_value_name(mut self, value_name: S) -> Self - where - S: Into<&'help str>, - { - self.subcommand_value_name = Some(value_name.into()); - self - } - - /// Sets the help heading used for subcommands when printing usage and help. - /// - /// By default, this is "SUBCOMMANDS". - /// - /// See also [`Command::subcommand_value_name`] - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .subcommand(Command::new("sub1")) - /// .print_help() - /// # ; - /// ``` - /// - /// will produce - /// - /// ```text - /// myprog - /// - /// USAGE: - /// myprog [SUBCOMMAND] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// - /// SUBCOMMANDS: - /// help Print this message or the help of the given subcommand(s) - /// sub1 - /// ``` - /// - /// but usage of `subcommand_help_heading` - /// - /// ```no_run - /// # use clap::{Command, Arg}; - /// Command::new("myprog") - /// .subcommand(Command::new("sub1")) - /// .subcommand_help_heading("THINGS") - /// .print_help() - /// # ; - /// ``` - /// - /// will produce - /// - /// ```text - /// myprog - /// - /// USAGE: - /// myprog [SUBCOMMAND] - /// - /// OPTIONS: - /// -h, --help Print help information - /// -V, --version Print version information - /// - /// THINGS: - /// help Print this message or the help of the given subcommand(s) - /// sub1 - /// ``` - #[must_use] - pub fn subcommand_help_heading(mut self, heading: T) -> Self - where - T: Into<&'help str>, - { - self.subcommand_heading = Some(heading.into()); - self - } -} - -/// # Reflection -impl<'help> App<'help> { - #[inline] - pub(crate) fn get_usage_name(&self) -> Option<&str> { - self.usage_name.as_deref() - } - - /// Get the name of the binary. - #[inline] - pub fn get_display_name(&self) -> Option<&str> { - self.display_name.as_deref() - } - - /// Get the name of the binary. - #[inline] - pub fn get_bin_name(&self) -> Option<&str> { - self.bin_name.as_deref() - } - - /// Set binary name. Uses `&mut self` instead of `self`. - pub fn set_bin_name>(&mut self, name: S) { - self.bin_name = Some(name.into()); - } - - /// Get the name of the cmd. - #[inline] - pub fn get_name(&self) -> &str { - &self.name - } - - /// Get the version of the cmd. - #[inline] - pub fn get_version(&self) -> Option<&'help str> { - self.version - } - - /// Get the long version of the cmd. - #[inline] - pub fn get_long_version(&self) -> Option<&'help str> { - self.long_version - } - - /// Get the authors of the cmd. - #[inline] - pub fn get_author(&self) -> Option<&'help str> { - self.author - } - - /// Get the short flag of the subcommand. - #[inline] - pub fn get_short_flag(&self) -> Option { - self.short_flag - } - - /// Get the long flag of the subcommand. - #[inline] - pub fn get_long_flag(&self) -> Option<&'help str> { - self.long_flag - } - - /// Get the help message specified via [`Command::about`]. - /// - /// [`App::about`]: Command::about() - #[inline] - pub fn get_about(&self) -> Option<&'help str> { - self.about - } - - /// Get the help message specified via [`Command::long_about`]. - /// - /// [`App::long_about`]: Command::long_about() - #[inline] - pub fn get_long_about(&self) -> Option<&'help str> { - self.long_about - } - - /// Deprecated, replaced with [`Command::get_next_help_heading`] - #[inline] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `App::get_next_help_heading`") - )] - pub fn get_help_heading(&self) -> Option<&'help str> { - self.get_next_help_heading() - } - - /// Get the custom section heading specified via [`Command::help_heading`]. - /// - /// [`App::help_heading`]: Command::help_heading() - #[inline] - pub fn get_next_help_heading(&self) -> Option<&'help str> { - self.current_help_heading - } - - /// Iterate through the *visible* aliases for this subcommand. - #[inline] - pub fn get_visible_aliases(&self) -> impl Iterator + '_ { - self.aliases.iter().filter(|(_, vis)| *vis).map(|a| a.0) - } - - /// Iterate through the *visible* short aliases for this subcommand. - #[inline] - pub fn get_visible_short_flag_aliases(&self) -> impl Iterator + '_ { - self.short_flag_aliases - .iter() - .filter(|(_, vis)| *vis) - .map(|a| a.0) - } - - /// Iterate through the *visible* long aliases for this subcommand. - #[inline] - pub fn get_visible_long_flag_aliases(&self) -> impl Iterator + '_ { - self.long_flag_aliases - .iter() - .filter(|(_, vis)| *vis) - .map(|a| a.0) - } - - /// Iterate through the set of *all* the aliases for this subcommand, both visible and hidden. - #[inline] - pub fn get_all_aliases(&self) -> impl Iterator + '_ { - self.aliases.iter().map(|a| a.0) - } - - /// Iterate through the set of *all* the short aliases for this subcommand, both visible and hidden. - #[inline] - pub fn get_all_short_flag_aliases(&self) -> impl Iterator + '_ { - self.short_flag_aliases.iter().map(|a| a.0) - } - - /// Iterate through the set of *all* the long aliases for this subcommand, both visible and hidden. - #[inline] - pub fn get_all_long_flag_aliases(&self) -> impl Iterator + '_ { - self.long_flag_aliases.iter().map(|a| a.0) - } - - /// Check if the given [`AppSettings`] variant is currently set on the `Command`. - /// - /// This checks both [local] and [global settings]. - /// - /// [local]: Command::setting() - /// [global settings]: Command::global_setting() - #[inline] - pub fn is_set(&self, s: AppSettings) -> bool { - self.settings.is_set(s) || self.g_settings.is_set(s) - } - - /// Should we color the output? - #[inline(never)] - pub fn get_color(&self) -> ColorChoice { - debug!("Command::color: Color setting..."); - - if cfg!(feature = "color") { - #[allow(deprecated)] - if self.is_set(AppSettings::ColorNever) { - debug!("Never"); - ColorChoice::Never - } else if self.is_set(AppSettings::ColorAlways) { - debug!("Always"); - ColorChoice::Always - } else { - debug!("Auto"); - ColorChoice::Auto - } - } else { - ColorChoice::Never - } - } - - /// Iterate through the set of subcommands, getting a reference to each. - #[inline] - pub fn get_subcommands(&self) -> impl Iterator> { - self.subcommands.iter() - } - - /// Iterate through the set of subcommands, getting a mutable reference to each. - #[inline] - pub fn get_subcommands_mut(&mut self) -> impl Iterator> { - self.subcommands.iter_mut() - } - - /// Returns `true` if this `Command` has subcommands. - #[inline] - pub fn has_subcommands(&self) -> bool { - !self.subcommands.is_empty() - } - - /// Returns the help heading for listing subcommands. - #[inline] - pub fn get_subcommand_help_heading(&self) -> Option<&str> { - self.subcommand_heading - } - - /// Deprecated, replaced with [`App::get_subcommand_help_heading`] - #[inline] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `App::get_subcommand_help_heading`" - ) - )] - pub fn get_subommand_help_heading(&self) -> Option<&str> { - self.get_subcommand_help_heading() - } - - /// Returns the subcommand value name. - #[inline] - pub fn get_subcommand_value_name(&self) -> Option<&str> { - self.subcommand_value_name - } - - /// Returns the help heading for listing subcommands. - #[inline] - pub fn get_before_help(&self) -> Option<&str> { - self.before_help - } - - /// Returns the help heading for listing subcommands. - #[inline] - pub fn get_before_long_help(&self) -> Option<&str> { - self.before_long_help - } - - /// Returns the help heading for listing subcommands. - #[inline] - pub fn get_after_help(&self) -> Option<&str> { - self.after_help - } - - /// Returns the help heading for listing subcommands. - #[inline] - pub fn get_after_long_help(&self) -> Option<&str> { - self.after_long_help - } - - /// Find subcommand such that its name or one of aliases equals `name`. - /// - /// This does not recurse through subcommands of subcommands. - #[inline] - pub fn find_subcommand(&self, name: &T) -> Option<&App<'help>> - where - T: PartialEq + ?Sized, - { - self.get_subcommands().find(|s| s.aliases_to(name)) - } - - /// Find subcommand such that its name or one of aliases equals `name`, returning - /// a mutable reference to the subcommand. - /// - /// This does not recurse through subcommands of subcommands. - #[inline] - pub fn find_subcommand_mut(&mut self, name: &T) -> Option<&mut App<'help>> - where - T: PartialEq + ?Sized, - { - self.get_subcommands_mut().find(|s| s.aliases_to(name)) - } - - /// Iterate through the set of groups. - #[inline] - pub fn get_groups(&self) -> impl Iterator> { - self.groups.iter() - } - - /// Iterate through the set of arguments. - #[inline] - pub fn get_arguments(&self) -> impl Iterator> { - self.args.args() - } - - /// Iterate through the *positionals* arguments. - #[inline] - pub fn get_positionals(&self) -> impl Iterator> { - self.get_arguments().filter(|a| a.is_positional()) - } - - /// Iterate through the *options*. - pub fn get_opts(&self) -> impl Iterator> { - self.get_arguments() - .filter(|a| a.is_takes_value_set() && !a.is_positional()) - } - - /// Get a list of all arguments the given argument conflicts with. - /// - /// If the provided argument is declared as global, the conflicts will be determined - /// based on the propagation rules of global arguments. - /// - /// ### Panics - /// - /// If the given arg contains a conflict with an argument that is unknown to - /// this `Command`. - pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator - { - if arg.is_global_set() { - self.get_global_arg_conflicts_with(arg) - } else { - let mut result = Vec::new(); - for id in arg.blacklist.iter() { - if let Some(arg) = self.find(id) { - result.push(arg); - } else if let Some(group) = self.find_group(id) { - result.extend( - self.unroll_args_in_group(&group.id) - .iter() - .map(|id| self.find(id).expect(INTERNAL_ERROR_MSG)), - ); - } else { - panic!("Command::get_arg_conflicts_with: The passed arg conflicts with an arg unknown to the cmd"); - } - } - result - } - } - - // Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with. - // - // This behavior follows the propagation rules of global arguments. - // It is useful for finding conflicts for arguments declared as global. - // - // ### Panics - // - // If the given arg contains a conflict with an argument that is unknown to - // this `App`. - fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator - { - arg.blacklist - .iter() - .map(|id| { - self.args - .args() - .chain( - self.get_subcommands_containing(arg) - .iter() - .flat_map(|x| x.args.args()), - ) - .find(|arg| arg.id == *id) - .expect( - "Command::get_arg_conflicts_with: \ - The passed arg conflicts with an arg unknown to the cmd", - ) - }) - .collect() - } - - // Get a list of subcommands which contain the provided Argument - // - // This command will only include subcommands in its list for which the subcommands - // parent also contains the Argument. - // - // This search follows the propagation rules of global arguments. - // It is useful to finding subcommands, that have inherited a global argument. - // - // **NOTE:** In this case only Sucommand_1 will be included - // Subcommand_1 (contains Arg) - // Subcommand_1.1 (doesn't contain Arg) - // Subcommand_1.1.1 (contains Arg) - // - fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>> { - let mut vec = std::vec::Vec::new(); - for idx in 0..self.subcommands.len() { - if self.subcommands[idx].args.args().any(|ar| ar.id == arg.id) { - vec.push(&self.subcommands[idx]); - vec.append(&mut self.subcommands[idx].get_subcommands_containing(arg)); - } - } - vec - } - - /// Report whether [`Command::no_binary_name`] is set - pub fn is_no_binary_name_set(&self) -> bool { - self.is_set(AppSettings::NoBinaryName) - } - - /// Report whether [`Command::ignore_errors`] is set - pub(crate) fn is_ignore_errors_set(&self) -> bool { - self.is_set(AppSettings::IgnoreErrors) - } - - /// Report whether [`Command::dont_delimit_trailing_values`] is set - pub fn is_dont_delimit_trailing_values_set(&self) -> bool { - self.is_set(AppSettings::DontDelimitTrailingValues) - } - - /// Report whether [`Command::disable_version_flag`] is set - pub fn is_disable_version_flag_set(&self) -> bool { - self.is_set(AppSettings::DisableVersionFlag) - } - - /// Report whether [`Command::propagate_version`] is set - pub fn is_propagate_version_set(&self) -> bool { - self.is_set(AppSettings::PropagateVersion) - } - - /// Report whether [`Command::next_line_help`] is set - pub fn is_next_line_help_set(&self) -> bool { - self.is_set(AppSettings::NextLineHelp) - } - - /// Report whether [`Command::disable_help_flag`] is set - pub fn is_disable_help_flag_set(&self) -> bool { - self.is_set(AppSettings::DisableHelpFlag) - } - - /// Report whether [`Command::disable_help_subcommand`] is set - pub fn is_disable_help_subcommand_set(&self) -> bool { - self.is_set(AppSettings::DisableHelpSubcommand) - } - - /// Report whether [`Command::disable_colored_help`] is set - pub fn is_disable_colored_help_set(&self) -> bool { - self.is_set(AppSettings::DisableColoredHelp) - } - - /// Report whether [`Command::help_expected`] is set - #[cfg(debug_assertions)] - pub(crate) fn is_help_expected_set(&self) -> bool { - self.is_set(AppSettings::HelpExpected) - } - - /// Report whether [`Command::dont_collapse_args_in_usage`] is set - pub fn is_dont_collapse_args_in_usage_set(&self) -> bool { - self.is_set(AppSettings::DontCollapseArgsInUsage) - } - - /// Report whether [`Command::infer_long_args`] is set - pub(crate) fn is_infer_long_args_set(&self) -> bool { - self.is_set(AppSettings::InferLongArgs) - } - - /// Report whether [`Command::infer_subcommands`] is set - pub(crate) fn is_infer_subcommands_set(&self) -> bool { - self.is_set(AppSettings::InferSubcommands) - } - - /// Report whether [`Command::arg_required_else_help`] is set - pub fn is_arg_required_else_help_set(&self) -> bool { - self.is_set(AppSettings::ArgRequiredElseHelp) - } - - /// Report whether [`Command::allow_hyphen_values`] is set - pub(crate) fn is_allow_hyphen_values_set(&self) -> bool { - self.is_set(AppSettings::AllowHyphenValues) - } - - /// Report whether [`Command::allow_negative_numbers`] is set - pub fn is_allow_negative_numbers_set(&self) -> bool { - self.is_set(AppSettings::AllowNegativeNumbers) - } - - /// Report whether [`Command::trailing_var_arg`] is set - pub fn is_trailing_var_arg_set(&self) -> bool { - self.is_set(AppSettings::TrailingVarArg) - } - - /// Report whether [`Command::allow_missing_positional`] is set - pub fn is_allow_missing_positional_set(&self) -> bool { - self.is_set(AppSettings::AllowMissingPositional) - } - - /// Report whether [`Command::hide`] is set - pub fn is_hide_set(&self) -> bool { - self.is_set(AppSettings::Hidden) - } - - /// Report whether [`Command::subcommand_required`] is set - pub fn is_subcommand_required_set(&self) -> bool { - self.is_set(AppSettings::SubcommandRequired) - } - - /// Report whether [`Command::allow_external_subcommands`] is set - pub fn is_allow_external_subcommands_set(&self) -> bool { - self.is_set(AppSettings::AllowExternalSubcommands) - } - - /// Report whether [`Command::allow_invalid_utf8_for_external_subcommands`] is set - pub fn is_allow_invalid_utf8_for_external_subcommands_set(&self) -> bool { - self.is_set(AppSettings::AllowInvalidUtf8ForExternalSubcommands) - } - - /// Configured parser for values passed to an external subcommand - /// - /// # Example - /// - /// ```rust - /// let cmd = clap::Command::new("raw") - /// .allow_external_subcommands(true) - /// .allow_invalid_utf8_for_external_subcommands(true); - /// let value_parser = cmd.get_external_subcommand_value_parser(); - /// println!("{:?}", value_parser); - /// ``` - pub fn get_external_subcommand_value_parser(&self) -> Option<&super::ValueParser> { - if !self.is_allow_external_subcommands_set() { - None - } else if self.is_allow_invalid_utf8_for_external_subcommands_set() { - static DEFAULT: super::ValueParser = super::ValueParser::os_string(); - Some(&DEFAULT) - } else { - static DEFAULT: super::ValueParser = super::ValueParser::string(); - Some(&DEFAULT) - } - } - - /// Report whether [`Command::args_conflicts_with_subcommands`] is set - pub fn is_args_conflicts_with_subcommands_set(&self) -> bool { - self.is_set(AppSettings::ArgsNegateSubcommands) - } - - /// Report whether [`Command::subcommand_precedence_over_arg`] is set - pub fn is_subcommand_precedence_over_arg_set(&self) -> bool { - self.is_set(AppSettings::SubcommandPrecedenceOverArg) - } - - /// Report whether [`Command::subcommand_negates_reqs`] is set - pub fn is_subcommand_negates_reqs_set(&self) -> bool { - self.is_set(AppSettings::SubcommandsNegateReqs) - } - - /// Report whether [`Command::multicall`] is set - pub fn is_multicall_set(&self) -> bool { - self.is_set(AppSettings::Multicall) - } -} - -/// Deprecated -impl<'help> App<'help> { - /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? - #[cfg(feature = "yaml")] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" - ) - )] - #[doc(hidden)] - pub fn from_yaml(y: &'help Yaml) -> Self { - #![allow(deprecated)] - let yaml_file_hash = y.as_hash().expect("YAML file must be a hash"); - // We WANT this to panic on error...so expect() is good. - let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() { - (App::new(name), yaml_file_hash, "cmd".into()) - } else { - let (name_yaml, value_yaml) = yaml_file_hash - .iter() - .next() - .expect("There must be one subcommand in the YAML file"); - let name_str = name_yaml - .as_str() - .expect("Subcommand name must be a string"); - - ( - App::new(name_str), - value_yaml.as_hash().expect("Subcommand must be a hash"), - format!("subcommand '{}'", name_str), - ) - }; - - for (k, v) in yaml { - a = match k.as_str().expect("App fields must be strings") { - "version" => yaml_to_str!(a, v, version), - "long_version" => yaml_to_str!(a, v, long_version), - "author" => yaml_to_str!(a, v, author), - "bin_name" => yaml_to_str!(a, v, bin_name), - "about" => yaml_to_str!(a, v, about), - "long_about" => yaml_to_str!(a, v, long_about), - "before_help" => yaml_to_str!(a, v, before_help), - "after_help" => yaml_to_str!(a, v, after_help), - "template" => yaml_to_str!(a, v, help_template), - "usage" => yaml_to_str!(a, v, override_usage), - "help" => yaml_to_str!(a, v, override_help), - "help_message" => yaml_to_str!(a, v, help_message), - "version_message" => yaml_to_str!(a, v, version_message), - "alias" => yaml_to_str!(a, v, alias), - "aliases" => yaml_vec_or_str!(a, v, alias), - "visible_alias" => yaml_to_str!(a, v, visible_alias), - "visible_aliases" => yaml_vec_or_str!(a, v, visible_alias), - "display_order" => yaml_to_usize!(a, v, display_order), - "args" => { - if let Some(vec) = v.as_vec() { - for arg_yaml in vec { - a = a.arg(Arg::from_yaml(arg_yaml)); - } - } else { - panic!("Failed to convert YAML value {:?} to a vec", v); - } - a - } - "subcommands" => { - if let Some(vec) = v.as_vec() { - for sc_yaml in vec { - a = a.subcommand(App::from_yaml(sc_yaml)); - } - } else { - panic!("Failed to convert YAML value {:?} to a vec", v); - } - a - } - "groups" => { - if let Some(vec) = v.as_vec() { - for ag_yaml in vec { - a = a.group(ArgGroup::from(ag_yaml)); - } - } else { - panic!("Failed to convert YAML value {:?} to a vec", v); - } - a - } - "setting" | "settings" => { - yaml_to_setting!(a, v, setting, AppSettings, "AppSetting", err) - } - "global_setting" | "global_settings" => { - yaml_to_setting!(a, v, global_setting, AppSettings, "AppSetting", err) - } - _ => a, - } - } - - a - } - - /// Deprecated, replaced with [`Command::override_usage`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::override_usage`") - )] - #[doc(hidden)] - #[must_use] - pub fn usage>(self, usage: S) -> Self { - self.override_usage(usage) - } - - /// Deprecated, replaced with [`Command::override_help`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::override_help`") - )] - #[doc(hidden)] - #[must_use] - pub fn help>(self, help: S) -> Self { - self.override_help(help) - } - - /// Deprecated, replaced with [`Command::mut_arg`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") - )] - #[doc(hidden)] - #[must_use] - pub fn help_short(self, c: char) -> Self { - self.mut_arg("help", |a| a.short(c)) - } - - /// Deprecated, replaced with [`Command::mut_arg`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") - )] - #[doc(hidden)] - #[must_use] - pub fn version_short(self, c: char) -> Self { - self.mut_arg("version", |a| a.short(c)) - } - - /// Deprecated, replaced with [`Command::mut_arg`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") - )] - #[doc(hidden)] - #[must_use] - pub fn help_message(self, s: impl Into<&'help str>) -> Self { - self.mut_arg("help", |a| a.help(s.into())) - } - - /// Deprecated, replaced with [`Command::mut_arg`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::mut_arg`") - )] - #[doc(hidden)] - #[must_use] - pub fn version_message(self, s: impl Into<&'help str>) -> Self { - self.mut_arg("version", |a| a.help(s.into())) - } - - /// Deprecated, replaced with [`Command::help_template`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::help_template`") - )] - #[doc(hidden)] - #[must_use] - pub fn template>(self, s: S) -> Self { - self.help_template(s) - } - - /// Deprecated, replaced with [`Command::setting(a| b)`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::setting(a | b)`") - )] - #[doc(hidden)] - #[must_use] - pub fn settings(mut self, settings: &[AppSettings]) -> Self { - for s in settings { - self.settings.insert((*s).into()); - } - self - } - - /// Deprecated, replaced with [`Command::unset_setting(a| b)`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::unset_setting(a | b)`") - )] - #[doc(hidden)] - #[must_use] - pub fn unset_settings(mut self, settings: &[AppSettings]) -> Self { - for s in settings { - self.settings.remove((*s).into()); - } - self - } - - /// Deprecated, replaced with [`Command::global_setting(a| b)`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::global_setting(a | b)`") - )] - #[doc(hidden)] - #[must_use] - pub fn global_settings(mut self, settings: &[AppSettings]) -> Self { - for s in settings { - self.settings.insert((*s).into()); - self.g_settings.insert((*s).into()); - } - self - } - - /// Deprecated, replaced with [`Command::term_width`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::term_width`") - )] - #[doc(hidden)] - #[must_use] - pub fn set_term_width(self, width: usize) -> Self { - self.term_width(width) - } - - /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!]. - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!") - )] - #[doc(hidden)] - #[must_use] - pub fn arg_from_usage(self, usage: &'help str) -> Self { - #![allow(deprecated)] - self.arg(Arg::from_usage(usage)) - } - - /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!]. - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!") - )] - #[doc(hidden)] - #[must_use] - pub fn args_from_usage(mut self, usage: &'help str) -> Self { - #![allow(deprecated)] - for line in usage.lines() { - let l = line.trim(); - if l.is_empty() { - continue; - } - self = self.arg(Arg::from_usage(l)); - } - self - } - - /// Deprecated, replaced with [`Command::render_version`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::render_version`") - )] - #[doc(hidden)] - pub fn write_version(&self, w: &mut W) -> ClapResult<()> { - write!(w, "{}", self.render_version()).map_err(From::from) - } - - /// Deprecated, replaced with [`Command::render_long_version`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::render_long_version`") - )] - #[doc(hidden)] - pub fn write_long_version(&self, w: &mut W) -> ClapResult<()> { - write!(w, "{}", self.render_long_version()).map_err(From::from) - } - - /// Deprecated, replaced with [`Command::try_get_matches`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches`") - )] - #[doc(hidden)] - pub fn get_matches_safe(self) -> ClapResult { - self.try_get_matches() - } - - /// Deprecated, replaced with [`Command::try_get_matches_from`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches_from`") - )] - #[doc(hidden)] - pub fn get_matches_from_safe(self, itr: I) -> ClapResult - where - I: IntoIterator, - T: Into + Clone, - { - self.try_get_matches_from(itr) - } - - /// Deprecated, replaced with [`Command::try_get_matches_from_mut`] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `App::try_get_matches_from_mut`" - ) - )] - #[doc(hidden)] - pub fn get_matches_from_safe_borrow(&mut self, itr: I) -> ClapResult - where - I: IntoIterator, - T: Into + Clone, - { - self.try_get_matches_from_mut(itr) - } -} - -// Internally used only -impl<'help> App<'help> { - pub(crate) fn get_id(&self) -> Id { - self.id.clone() - } - - pub(crate) fn get_override_usage(&self) -> Option<&str> { - self.usage_str - } - - pub(crate) fn get_override_help(&self) -> Option<&str> { - self.help_str - } - - pub(crate) fn get_help_template(&self) -> Option<&str> { - self.template - } - - pub(crate) fn get_term_width(&self) -> Option { - self.term_w - } - - pub(crate) fn get_max_term_width(&self) -> Option { - self.max_w - } - - pub(crate) fn get_replacement(&self, key: &str) -> Option<&[&str]> { - self.replacers.get(key).copied() - } - - pub(crate) fn get_keymap(&self) -> &MKeyMap<'help> { - &self.args - } - - fn get_used_global_args(&self, matches: &ArgMatches, global_arg_vec: &mut Vec) { - global_arg_vec.extend( - self.args - .args() - .filter(|a| a.is_global_set()) - .map(|ga| ga.id.clone()), - ); - if let Some((id, matches)) = matches.subcommand() { - if let Some(used_sub) = self.find_subcommand(id) { - used_sub.get_used_global_args(matches, global_arg_vec); - } - } - } - - fn _do_parse( - &mut self, - raw_args: &mut clap_lex::RawArgs, - args_cursor: clap_lex::ArgCursor, - ) -> ClapResult { - debug!("Command::_do_parse"); - - // If there are global arguments, or settings we need to propagate them down to subcommands - // before parsing in case we run into a subcommand - self._build_self(); - - let mut matcher = ArgMatcher::new(self); - - // do the real parsing - let mut parser = Parser::new(self); - if let Err(error) = parser.get_matches_with(&mut matcher, raw_args, args_cursor) { - if self.is_set(AppSettings::IgnoreErrors) { - debug!("Command::_do_parse: ignoring error: {}", error); - } else { - return Err(error); - } - } - - let mut global_arg_vec = Default::default(); - self.get_used_global_args(&matcher, &mut global_arg_vec); - - matcher.propagate_globals(&global_arg_vec); - - Ok(matcher.into_inner()) - } - - #[doc(hidden)] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.10", note = "Replaced with `Command::build`") - )] - pub fn _build_all(&mut self) { - self.build(); - } - - #[doc(hidden)] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.10", note = "Replaced with `Command::build`") - )] - pub fn _build(&mut self) { - self._build_self() - } - - #[doc(hidden)] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.13", note = "Replaced with `Command::build`") - )] - pub fn _build_bin_names(&mut self) { - self._build_bin_names_internal(); - } - - /// Prepare for introspecting on all included [`Command`]s - /// - /// Call this on the top-level [`Command`] when done building and before reading state for - /// cases like completions, custom help output, etc. - pub fn build(&mut self) { - self._build_recursive(); - self._build_bin_names_internal(); - } - - pub(crate) fn _build_recursive(&mut self) { - self._build_self(); - for subcmd in self.get_subcommands_mut() { - subcmd._build_recursive(); - } - } - - pub(crate) fn _build_self(&mut self) { - debug!("Command::_build: name={:?}", self.get_name()); - if !self.settings.is_set(AppSettings::Built) { - // Make sure all the globally set flags apply to us as well - self.settings = self.settings | self.g_settings; - - if self.is_multicall_set() { - self.settings.insert(AppSettings::SubcommandRequired.into()); - self.settings.insert(AppSettings::DisableHelpFlag.into()); - self.settings.insert(AppSettings::DisableVersionFlag.into()); - } - - self._propagate(); - self._check_help_and_version(); - self._propagate_global_args(); - self._derive_display_order(); - - let mut pos_counter = 1; - let self_override = self.is_set(AppSettings::AllArgsOverrideSelf); - let hide_pv = self.is_set(AppSettings::HidePossibleValues); - let auto_help = - !self.is_set(AppSettings::NoAutoHelp) && !self.is_disable_help_flag_set(); - let auto_version = - !self.is_set(AppSettings::NoAutoVersion) && !self.is_disable_version_flag_set(); - for a in self.args.args_mut() { - // Fill in the groups - for g in &a.groups { - if let Some(ag) = self.groups.iter_mut().find(|grp| grp.id == *g) { - ag.args.push(a.id.clone()); - } else { - let mut ag = ArgGroup::with_id(g.clone()); - ag.args.push(a.id.clone()); - self.groups.push(ag); - } - } - - // Figure out implied settings - if a.is_last_set() { - // if an arg has `Last` set, we need to imply DontCollapseArgsInUsage so that args - // in the usage string don't get confused or left out. - self.settings.set(AppSettings::DontCollapseArgsInUsage); - } - if hide_pv && a.is_takes_value_set() { - a.settings.set(ArgSettings::HidePossibleValues); - } - if self_override { - let self_id = a.id.clone(); - a.overrides.push(self_id); - } - a._build(); - // HACK: Setting up action at this level while auto-help / disable help flag is - // required. Otherwise, most of this won't be needed because when we can break - // compat, actions will reign supreme (default to `Store`) - if a.action.is_none() { - if a.get_id() == "help" && auto_help && !a.is_takes_value_set() { - let action = super::ArgAction::Help; - a.action = Some(action); - } else if a.get_id() == "version" && auto_version && !a.is_takes_value_set() { - let action = super::ArgAction::Version; - a.action = Some(action); - } else if a.is_takes_value_set() { - let action = super::ArgAction::StoreValue; - a.action = Some(action); - } else { - let action = super::ArgAction::IncOccurrence; - a.action = Some(action); - } - } - if a.is_positional() && a.index.is_none() { - a.index = Some(pos_counter); - pos_counter += 1; - } - } - - self.args._build(); - - #[cfg(debug_assertions)] - assert_app(self); - self.settings.set(AppSettings::Built); - } else { - debug!("Command::_build: already built"); - } - } - - pub(crate) fn _build_subcommand(&mut self, name: &str) -> Option<&mut Self> { - use std::fmt::Write; - - let mut mid_string = String::from(" "); - if !self.is_subcommand_negates_reqs_set() && !self.is_args_conflicts_with_subcommands_set() - { - let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m) - - for s in &reqs { - mid_string.push_str(s); - mid_string.push(' '); - } - } - let is_multicall_set = self.is_multicall_set(); - - let sc = self.subcommands.iter_mut().find(|s| s.name == name)?; - - // Display subcommand name, short and long in usage - let mut sc_names = sc.name.clone(); - let mut flag_subcmd = false; - if let Some(l) = sc.long_flag { - write!(sc_names, "|--{}", l).unwrap(); - flag_subcmd = true; - } - if let Some(s) = sc.short_flag { - write!(sc_names, "|-{}", s).unwrap(); - flag_subcmd = true; - } - - if flag_subcmd { - sc_names = format!("{{{}}}", sc_names); - } - - let usage_name = self - .bin_name - .as_ref() - .map(|bin_name| format!("{}{}{}", bin_name, mid_string, sc_names)) - .unwrap_or(sc_names); - sc.usage_name = Some(usage_name); - - // bin_name should be parent's bin_name + [] + the sc's name separated by - // a space - let bin_name = format!( - "{}{}{}", - self.bin_name.as_ref().unwrap_or(&String::new()), - if self.bin_name.is_some() { " " } else { "" }, - &*sc.name - ); - debug!( - "Command::_build_subcommand Setting bin_name of {} to {:?}", - sc.name, bin_name - ); - sc.bin_name = Some(bin_name); - - if sc.display_name.is_none() { - let self_display_name = if is_multicall_set { - self.display_name.as_deref().unwrap_or("") - } else { - self.display_name.as_deref().unwrap_or(&self.name) - }; - let display_name = format!( - "{}{}{}", - self_display_name, - if !self_display_name.is_empty() { - "-" - } else { - "" - }, - &*sc.name - ); - debug!( - "Command::_build_subcommand Setting display_name of {} to {:?}", - sc.name, display_name - ); - sc.display_name = Some(display_name); - } - - // Ensure all args are built and ready to parse - sc._build_self(); - - Some(sc) - } - - fn _build_bin_names_internal(&mut self) { - debug!("Command::_build_bin_names"); - - if !self.is_set(AppSettings::BinNameBuilt) { - let mut mid_string = String::from(" "); - if !self.is_subcommand_negates_reqs_set() - && !self.is_args_conflicts_with_subcommands_set() - { - let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m) - - for s in &reqs { - mid_string.push_str(s); - mid_string.push(' '); - } - } - let is_multicall_set = self.is_multicall_set(); - - let self_bin_name = if is_multicall_set { - self.bin_name.as_deref().unwrap_or("") - } else { - self.bin_name.as_deref().unwrap_or(&self.name) - } - .to_owned(); - - for mut sc in &mut self.subcommands { - debug!("Command::_build_bin_names:iter: bin_name set..."); - - if sc.usage_name.is_none() { - use std::fmt::Write; - // Display subcommand name, short and long in usage - let mut sc_names = sc.name.clone(); - let mut flag_subcmd = false; - if let Some(l) = sc.long_flag { - write!(sc_names, "|--{}", l).unwrap(); - flag_subcmd = true; - } - if let Some(s) = sc.short_flag { - write!(sc_names, "|-{}", s).unwrap(); - flag_subcmd = true; - } - - if flag_subcmd { - sc_names = format!("{{{}}}", sc_names); - } - - let usage_name = format!("{}{}{}", self_bin_name, mid_string, sc_names); - debug!( - "Command::_build_bin_names:iter: Setting usage_name of {} to {:?}", - sc.name, usage_name - ); - sc.usage_name = Some(usage_name); - } else { - debug!( - "Command::_build_bin_names::iter: Using existing usage_name of {} ({:?})", - sc.name, sc.usage_name - ); - } - - if sc.bin_name.is_none() { - let bin_name = format!( - "{}{}{}", - self_bin_name, - if !self_bin_name.is_empty() { " " } else { "" }, - &*sc.name - ); - debug!( - "Command::_build_bin_names:iter: Setting bin_name of {} to {:?}", - sc.name, bin_name - ); - sc.bin_name = Some(bin_name); - } else { - debug!( - "Command::_build_bin_names::iter: Using existing bin_name of {} ({:?})", - sc.name, sc.bin_name - ); - } - - if sc.display_name.is_none() { - let self_display_name = if is_multicall_set { - self.display_name.as_deref().unwrap_or("") - } else { - self.display_name.as_deref().unwrap_or(&self.name) - }; - let display_name = format!( - "{}{}{}", - self_display_name, - if !self_display_name.is_empty() { - "-" - } else { - "" - }, - &*sc.name - ); - debug!( - "Command::_build_bin_names:iter: Setting display_name of {} to {:?}", - sc.name, display_name - ); - sc.display_name = Some(display_name); - } else { - debug!( - "Command::_build_bin_names::iter: Using existing display_name of {} ({:?})", - sc.name, sc.display_name - ); - } - - sc._build_bin_names_internal(); - } - self.set(AppSettings::BinNameBuilt); - } else { - debug!("Command::_build_bin_names: already built"); - } - } - - pub(crate) fn _panic_on_missing_help(&self, help_required_globally: bool) { - if self.is_set(AppSettings::HelpExpected) || help_required_globally { - let args_missing_help: Vec = self - .args - .args() - .filter(|arg| arg.help.is_none() && arg.long_help.is_none()) - .map(|arg| String::from(arg.name)) - .collect(); - - assert!(args_missing_help.is_empty(), - "Command::help_expected is enabled for the Command {}, but at least one of its arguments does not have either `help` or `long_help` set. List of such arguments: {}", - self.name, - args_missing_help.join(", ") - ); - } - - for sub_app in &self.subcommands { - sub_app._panic_on_missing_help(help_required_globally); - } - } - - #[cfg(debug_assertions)] - pub(crate) fn two_args_of(&self, condition: F) -> Option<(&Arg<'help>, &Arg<'help>)> - where - F: Fn(&Arg) -> bool, - { - two_elements_of(self.args.args().filter(|a: &&Arg| condition(a))) - } - - // just in case - #[allow(unused)] - fn two_groups_of(&self, condition: F) -> Option<(&ArgGroup, &ArgGroup)> - where - F: Fn(&ArgGroup) -> bool, - { - two_elements_of(self.groups.iter().filter(|a| condition(a))) - } - - /// Propagate global args - pub(crate) fn _propagate_global_args(&mut self) { - debug!("Command::_propagate_global_args:{}", self.name); - - for sc in &mut self.subcommands { - for a in self.args.args().filter(|a| a.is_global_set()) { - let mut propagate = false; - let is_generated = matches!( - a.provider, - ArgProvider::Generated | ArgProvider::GeneratedMutated - ); - - // Remove generated help and version args in the subcommand - // - // Don't remove if those args are further mutated - if is_generated { - let generated_pos = sc - .args - .args() - .position(|x| x.id == a.id && x.provider == ArgProvider::Generated); - - if let Some(index) = generated_pos { - debug!( - "Command::_propagate removing {}'s {:?}", - sc.get_name(), - a.id - ); - sc.args.remove(index); - propagate = true; - } - } - - if propagate || sc.find(&a.id).is_none() { - debug!( - "Command::_propagate pushing {:?} to {}", - a.id, - sc.get_name(), - ); - sc.args.push(a.clone()); - } - } - } - } - - /// Propagate settings - pub(crate) fn _propagate(&mut self) { - debug!("Command::_propagate:{}", self.name); - let mut subcommands = std::mem::take(&mut self.subcommands); - for sc in &mut subcommands { - self._propagate_subcommand(sc); - } - self.subcommands = subcommands; - } - - fn _propagate_subcommand(&self, sc: &mut Self) { - // We have to create a new scope in order to tell rustc the borrow of `sc` is - // done and to recursively call this method - { - if self.settings.is_set(AppSettings::PropagateVersion) { - if sc.version.is_none() && self.version.is_some() { - sc.version = Some(self.version.unwrap()); - } - if sc.long_version.is_none() && self.long_version.is_some() { - sc.long_version = Some(self.long_version.unwrap()); - } - } - - sc.settings = sc.settings | self.g_settings; - sc.g_settings = sc.g_settings | self.g_settings; - sc.term_w = self.term_w; - sc.max_w = self.max_w; - } - } - - #[allow(clippy::blocks_in_if_conditions)] - pub(crate) fn _check_help_and_version(&mut self) { - debug!("Command::_check_help_and_version: {}", self.name); - - if self.is_set(AppSettings::DisableHelpFlag) - || self.args.args().any(|x| { - x.provider == ArgProvider::User - && (x.long == Some("help") || x.id == Id::help_hash()) - }) - || self - .subcommands - .iter() - .any(|sc| sc.long_flag == Some("help")) - { - debug!("Command::_check_help_and_version: Removing generated help"); - - let generated_help_pos = self - .args - .args() - .position(|x| x.id == Id::help_hash() && x.provider == ArgProvider::Generated); - - if let Some(index) = generated_help_pos { - self.args.remove(index); - } - } else { - let help = self - .args - .args() - .find(|x| x.id == Id::help_hash()) - .expect(INTERNAL_ERROR_MSG); - assert_ne!(help.provider, ArgProvider::User); - - if help.short.is_some() { - if help.short == Some('h') { - if let Some(other_arg) = self - .args - .args() - .find(|x| x.id != Id::help_hash() && x.short == Some('h')) - { - panic!( - "`help`s `-h` conflicts with `{}`. - -To change `help`s short, call `cmd.arg(Arg::new(\"help\")...)`.", - other_arg.name - ); - } - } - } else if !(self.args.args().any(|x| x.short == Some('h')) - || self.subcommands.iter().any(|sc| sc.short_flag == Some('h'))) - { - let help = self - .args - .args_mut() - .find(|x| x.id == Id::help_hash()) - .expect(INTERNAL_ERROR_MSG); - help.short = Some('h'); - } else { - debug!("Command::_check_help_and_version: Removing `-h` from help"); - } - } - - // Determine if we should remove the generated --version flag - // - // Note that if only mut_arg() was used, the first expression will evaluate to `true` - // however inside the condition block, we only check for Generated args, not - // GeneratedMutated args, so the `mut_arg("version", ..) will be skipped and fall through - // to the following condition below (Adding the short `-V`) - if self.settings.is_set(AppSettings::DisableVersionFlag) - || (self.version.is_none() && self.long_version.is_none()) - || self.args.args().any(|x| { - x.provider == ArgProvider::User - && (x.long == Some("version") || x.id == Id::version_hash()) - }) - || self - .subcommands - .iter() - .any(|sc| sc.long_flag == Some("version")) - { - debug!("Command::_check_help_and_version: Removing generated version"); - - // This is the check mentioned above that only checks for Generated, not - // GeneratedMutated args by design. - let generated_version_pos = self - .args - .args() - .position(|x| x.id == Id::version_hash() && x.provider == ArgProvider::Generated); - - if let Some(index) = generated_version_pos { - self.args.remove(index); - } - } - - // If we still have a generated --version flag, determine if we can apply the short `-V` - if self.args.args().any(|x| { - x.id == Id::version_hash() - && matches!( - x.provider, - ArgProvider::Generated | ArgProvider::GeneratedMutated - ) - }) { - let other_arg_has_short = self.args.args().any(|x| x.short == Some('V')); - let version = self - .args - .args_mut() - .find(|x| x.id == Id::version_hash()) - .expect(INTERNAL_ERROR_MSG); - - if !(version.short.is_some() - || other_arg_has_short - || self.subcommands.iter().any(|sc| sc.short_flag == Some('V'))) - { - version.short = Some('V'); - } - } - - if !self.is_set(AppSettings::DisableHelpSubcommand) - && self.has_subcommands() - && !self.subcommands.iter().any(|s| s.id == Id::help_hash()) - { - debug!("Command::_check_help_and_version: Building help subcommand"); - let mut help_subcmd = App::new("help") - .about("Print this message or the help of the given subcommand(s)") - .arg( - Arg::new("subcommand") - .index(1) - .takes_value(true) - .multiple_occurrences(true) - .value_name("SUBCOMMAND") - .help("The subcommand whose help message to display"), - ); - self._propagate_subcommand(&mut help_subcmd); - - // The parser acts like this is set, so let's set it so we don't falsely - // advertise it to the user - help_subcmd.version = None; - help_subcmd.long_version = None; - help_subcmd = help_subcmd - .setting(AppSettings::DisableHelpFlag) - .unset_global_setting(AppSettings::PropagateVersion); - - self.subcommands.push(help_subcmd); - } - } - - pub(crate) fn _derive_display_order(&mut self) { - debug!("Command::_derive_display_order:{}", self.name); - - if self.settings.is_set(AppSettings::DeriveDisplayOrder) { - for a in self - .args - .args_mut() - .filter(|a| !a.is_positional()) - .filter(|a| a.provider != ArgProvider::Generated) - { - a.disp_ord.make_explicit(); - } - for (i, sc) in &mut self.subcommands.iter_mut().enumerate() { - sc.disp_ord.get_or_insert(i); - } - } - for sc in &mut self.subcommands { - sc._derive_display_order(); - } - } - - pub(crate) fn _render_version(&self, use_long: bool) -> String { - debug!("Command::_render_version"); - - let ver = if use_long { - self.long_version.or(self.version).unwrap_or("") - } else { - self.version.or(self.long_version).unwrap_or("") - }; - if let Some(bn) = self.bin_name.as_ref() { - if bn.contains(' ') { - // In case we're dealing with subcommands i.e. git mv is translated to git-mv - format!("{} {}\n", bn.replace(' ', "-"), ver) - } else { - format!("{} {}\n", &self.name[..], ver) - } - } else { - format!("{} {}\n", &self.name[..], ver) - } - } - - pub(crate) fn format_group(&self, g: &Id) -> String { - let g_string = self - .unroll_args_in_group(g) - .iter() - .filter_map(|x| self.find(x)) - .map(|x| { - if x.is_positional() { - // Print val_name for positional arguments. e.g. - x.name_no_brackets().to_string() - } else { - // Print usage string for flags arguments, e.g. <--help> - x.to_string() - } - }) - .collect::>() - .join("|"); - format!("<{}>", &*g_string) - } -} - -/// A workaround: -/// -pub(crate) trait Captures<'a> {} -impl<'a, T> Captures<'a> for T {} - -// Internal Query Methods -impl<'help> App<'help> { - /// Iterate through the *flags* & *options* arguments. - pub(crate) fn get_non_positionals(&self) -> impl Iterator> { - self.get_arguments().filter(|a| !a.is_positional()) - } - - /// Iterate through the *positionals* that don't have custom heading. - pub(crate) fn get_positionals_with_no_heading(&self) -> impl Iterator> { - self.get_positionals() - .filter(|a| a.get_help_heading().is_none()) - } - - /// Iterate through the *flags* & *options* that don't have custom heading. - pub(crate) fn get_non_positionals_with_no_heading(&self) -> impl Iterator> { - self.get_non_positionals() - .filter(|a| a.get_help_heading().is_none()) - } - - pub(crate) fn find(&self, arg_id: &Id) -> Option<&Arg<'help>> { - self.args.args().find(|a| a.id == *arg_id) - } - - #[inline] - pub(crate) fn contains_short(&self, s: char) -> bool { - assert!( - self.is_set(AppSettings::Built), - "If App::_build hasn't been called, manually search through Arg shorts" - ); - - self.args.contains(s) - } - - #[inline] - pub(crate) fn set(&mut self, s: AppSettings) { - self.settings.set(s) - } - - #[inline] - pub(crate) fn has_args(&self) -> bool { - !self.args.is_empty() - } - - pub(crate) fn has_positionals(&self) -> bool { - self.args.keys().any(|x| x.is_position()) - } - - pub(crate) fn has_visible_subcommands(&self) -> bool { - self.subcommands - .iter() - .any(|sc| sc.name != "help" && !sc.is_set(AppSettings::Hidden)) - } - - /// Check if this subcommand can be referred to as `name`. In other words, - /// check if `name` is the name of this subcommand or is one of its aliases. - #[inline] - pub(crate) fn aliases_to(&self, name: &T) -> bool - where - T: PartialEq + ?Sized, - { - *name == *self.get_name() || self.get_all_aliases().any(|alias| *name == *alias) - } - - /// Check if this subcommand can be referred to as `name`. In other words, - /// check if `name` is the name of this short flag subcommand or is one of its short flag aliases. - #[inline] - pub(crate) fn short_flag_aliases_to(&self, flag: char) -> bool { - Some(flag) == self.short_flag - || self.get_all_short_flag_aliases().any(|alias| flag == alias) - } - - /// Check if this subcommand can be referred to as `name`. In other words, - /// check if `name` is the name of this long flag subcommand or is one of its long flag aliases. - #[inline] - pub(crate) fn long_flag_aliases_to(&self, flag: &T) -> bool - where - T: PartialEq + ?Sized, - { - match self.long_flag { - Some(long_flag) => { - flag == long_flag || self.get_all_long_flag_aliases().any(|alias| flag == alias) - } - None => self.get_all_long_flag_aliases().any(|alias| flag == alias), - } - } - - #[cfg(debug_assertions)] - pub(crate) fn id_exists(&self, id: &Id) -> bool { - self.args.args().any(|x| x.id == *id) || self.groups.iter().any(|x| x.id == *id) - } - - /// Iterate through the groups this arg is member of. - pub(crate) fn groups_for_arg<'a>(&'a self, arg: &Id) -> impl Iterator + 'a { - debug!("Command::groups_for_arg: id={:?}", arg); - let arg = arg.clone(); - self.groups - .iter() - .filter(move |grp| grp.args.iter().any(|a| a == &arg)) - .map(|grp| grp.id.clone()) - } - - pub(crate) fn find_group(&self, group_id: &Id) -> Option<&ArgGroup<'help>> { - self.groups.iter().find(|g| g.id == *group_id) - } - - /// Iterate through all the names of all subcommands (not recursively), including aliases. - /// Used for suggestions. - pub(crate) fn all_subcommand_names(&self) -> impl Iterator + Captures<'help> { - self.get_subcommands().flat_map(|sc| { - let name = sc.get_name(); - let aliases = sc.get_all_aliases(); - std::iter::once(name).chain(aliases) - }) - } - - pub(crate) fn required_graph(&self) -> ChildGraph { - let mut reqs = ChildGraph::with_capacity(5); - for a in self.args.args().filter(|a| a.is_required_set()) { - reqs.insert(a.id.clone()); - } - for group in &self.groups { - if group.required { - let idx = reqs.insert(group.id.clone()); - for a in &group.requires { - reqs.insert_child(idx, a.clone()); - } - } - } - - reqs - } - - pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec { - debug!("Command::unroll_args_in_group: group={:?}", group); - let mut g_vec = vec![group]; - let mut args = vec![]; - - while let Some(g) = g_vec.pop() { - for n in self - .groups - .iter() - .find(|grp| grp.id == *g) - .expect(INTERNAL_ERROR_MSG) - .args - .iter() - { - debug!("Command::unroll_args_in_group:iter: entity={:?}", n); - if !args.contains(n) { - if self.find(n).is_some() { - debug!("Command::unroll_args_in_group:iter: this is an arg"); - args.push(n.clone()) - } else { - debug!("Command::unroll_args_in_group:iter: this is a group"); - g_vec.push(n); - } - } - } - } - - args - } - - pub(crate) fn unroll_arg_requires(&self, func: F, arg: &Id) -> Vec - where - F: Fn(&(ArgPredicate<'_>, Id)) -> Option, - { - let mut processed = vec![]; - let mut r_vec = vec![arg]; - let mut args = vec![]; - - while let Some(a) = r_vec.pop() { - if processed.contains(&a) { - continue; - } - - processed.push(a); - - if let Some(arg) = self.find(a) { - for r in arg.requires.iter().filter_map(&func) { - if let Some(req) = self.find(&r) { - if !req.requires.is_empty() { - r_vec.push(&req.id) - } - } - args.push(r); - } - } - } - - args - } - - /// Find a flag subcommand name by short flag or an alias - pub(crate) fn find_short_subcmd(&self, c: char) -> Option<&str> { - self.get_subcommands() - .find(|sc| sc.short_flag_aliases_to(c)) - .map(|sc| sc.get_name()) - } - - /// Find a flag subcommand name by long flag or an alias - pub(crate) fn find_long_subcmd(&self, long: &str) -> Option<&str> { - self.get_subcommands() - .find(|sc| sc.long_flag_aliases_to(long)) - .map(|sc| sc.get_name()) - } - - pub(crate) fn get_display_order(&self) -> usize { - self.disp_ord.unwrap_or(999) - } - - pub(crate) fn write_help_err( - &self, - mut use_long: bool, - stream: Stream, - ) -> ClapResult { - debug!( - "Parser::write_help_err: use_long={:?}, stream={:?}", - use_long && self.use_long_help(), - stream - ); - - use_long = use_long && self.use_long_help(); - let usage = Usage::new(self); - - let mut c = Colorizer::new(stream, self.color_help()); - Help::new(HelpWriter::Buffer(&mut c), self, &usage, use_long).write_help()?; - Ok(c) - } - - pub(crate) fn use_long_help(&self) -> bool { - debug!("Command::use_long_help"); - // In this case, both must be checked. This allows the retention of - // original formatting, but also ensures that the actual -h or --help - // specified by the user is sent through. If hide_short_help is not included, - // then items specified with hidden_short_help will also be hidden. - let should_long = |v: &Arg| { - v.long_help.is_some() - || v.is_hide_long_help_set() - || v.is_hide_short_help_set() - || cfg!(feature = "unstable-v4") - && v.get_possible_values2() - .iter() - .any(PossibleValue::should_show_help) - }; - - // Subcommands aren't checked because we prefer short help for them, deferring to - // `cmd subcmd --help` for more. - self.get_long_about().is_some() - || self.get_before_long_help().is_some() - || self.get_after_long_help().is_some() - || self.get_arguments().any(should_long) - } - - // Should we color the help? - pub(crate) fn color_help(&self) -> ColorChoice { - #[cfg(feature = "color")] - if self.is_disable_colored_help_set() { - return ColorChoice::Never; - } - - self.get_color() - } -} - -impl<'help> Default for App<'help> { - fn default() -> Self { - Self { - id: Default::default(), - name: Default::default(), - long_flag: Default::default(), - short_flag: Default::default(), - display_name: Default::default(), - bin_name: Default::default(), - author: Default::default(), - version: Default::default(), - long_version: Default::default(), - about: Default::default(), - long_about: Default::default(), - before_help: Default::default(), - before_long_help: Default::default(), - after_help: Default::default(), - after_long_help: Default::default(), - aliases: Default::default(), - short_flag_aliases: Default::default(), - long_flag_aliases: Default::default(), - usage_str: Default::default(), - usage_name: Default::default(), - help_str: Default::default(), - disp_ord: Default::default(), - term_w: Default::default(), - max_w: Default::default(), - template: Default::default(), - settings: Default::default(), - g_settings: Default::default(), - args: Default::default(), - subcommands: Default::default(), - replacers: Default::default(), - groups: Default::default(), - current_help_heading: Default::default(), - current_disp_ord: Some(0), - subcommand_value_name: Default::default(), - subcommand_heading: Default::default(), - } - } -} - -impl<'help> Index<&'_ Id> for App<'help> { - type Output = Arg<'help>; - - fn index(&self, key: &Id) -> &Self::Output { - self.find(key).expect(INTERNAL_ERROR_MSG) - } -} - -impl fmt::Display for App<'_> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name) - } -} - -fn two_elements_of(mut iter: I) -> Option<(T, T)> -where - I: Iterator, -{ - let first = iter.next(); - let second = iter.next(); - - match (first, second) { - (Some(first), Some(second)) => Some((first, second)), - _ => None, - } -} - -#[test] -fn check_auto_traits() { - static_assertions::assert_impl_all!(Command: Send, Sync, Unpin); -} diff --git a/vendor/clap/src/builder/debug_asserts.rs b/vendor/clap/src/builder/debug_asserts.rs deleted file mode 100644 index 864b8b479..000000000 --- a/vendor/clap/src/builder/debug_asserts.rs +++ /dev/null @@ -1,851 +0,0 @@ -use std::cmp::Ordering; - -use clap_lex::RawOsStr; - -use crate::builder::arg::ArgProvider; -use crate::mkeymap::KeyType; -use crate::ArgAction; -use crate::{Arg, Command, ValueHint}; - -pub(crate) fn assert_app(cmd: &Command) { - debug!("Command::_debug_asserts"); - - let mut short_flags = vec![]; - let mut long_flags = vec![]; - - // Invalid version flag settings - if cmd.get_version().is_none() && cmd.get_long_version().is_none() { - // PropagateVersion is meaningless if there is no version - assert!( - !cmd.is_propagate_version_set(), - "Command {}: No version information via Command::version or Command::long_version to propagate", - cmd.get_name(), - ); - - // Used `Command::mut_arg("version", ..) but did not provide any version information to display - let version_needed = cmd - .get_arguments() - .filter(|x| { - let action_set = matches!(x.get_action(), ArgAction::Version); - #[cfg(not(feature = "unstable-v4"))] - let provider_set = matches!(x.provider, ArgProvider::GeneratedMutated); - #[cfg(feature = "unstable-v4")] - let provider_set = matches!( - x.provider, - ArgProvider::User | ArgProvider::GeneratedMutated - ); - action_set && provider_set - }) - .map(|x| x.get_id()) - .collect::>(); - - assert_eq!(version_needed, Vec::<&str>::new(), "Command {}: `ArgAction::Version` used without providing Command::version or Command::long_version" - ,cmd.get_name() - ); - } - - for sc in cmd.get_subcommands() { - if let Some(s) = sc.get_short_flag().as_ref() { - short_flags.push(Flag::Command(format!("-{}", s), sc.get_name())); - } - - for short_alias in sc.get_all_short_flag_aliases() { - short_flags.push(Flag::Command(format!("-{}", short_alias), sc.get_name())); - } - - if let Some(l) = sc.get_long_flag().as_ref() { - #[cfg(feature = "unstable-v4")] - { - assert!(!l.starts_with('-'), "Command {}: long_flag {:?} must not start with a `-`, that will be handled by the parser", sc.get_name(), l); - } - long_flags.push(Flag::Command(format!("--{}", l), sc.get_name())); - } - - for long_alias in sc.get_all_long_flag_aliases() { - long_flags.push(Flag::Command(format!("--{}", long_alias), sc.get_name())); - } - } - - for arg in cmd.get_arguments() { - assert_arg(arg); - - assert!( - !cmd.is_multicall_set(), - "Command {}: Arguments like {} cannot be set on a multicall command", - cmd.get_name(), - arg.name - ); - - if let Some(s) = arg.short.as_ref() { - short_flags.push(Flag::Arg(format!("-{}", s), &*arg.name)); - } - - for (short_alias, _) in &arg.short_aliases { - short_flags.push(Flag::Arg(format!("-{}", short_alias), arg.name)); - } - - if let Some(l) = arg.long.as_ref() { - #[cfg(feature = "unstable-v4")] - { - assert!(!l.starts_with('-'), "Argument {}: long {:?} must not start with a `-`, that will be handled by the parser", arg.name, l); - } - long_flags.push(Flag::Arg(format!("--{}", l), &*arg.name)); - } - - for (long_alias, _) in &arg.aliases { - long_flags.push(Flag::Arg(format!("--{}", long_alias), arg.name)); - } - - // Name conflicts - assert!( - cmd.two_args_of(|x| x.id == arg.id).is_none(), - "Command {}: Argument names must be unique, but '{}' is in use by more than one argument or group", - cmd.get_name(), - arg.name, - ); - - // Long conflicts - if let Some(l) = arg.long { - if let Some((first, second)) = cmd.two_args_of(|x| x.long == Some(l)) { - panic!( - "Command {}: Long option names must be unique for each argument, \ - but '--{}' is in use by both '{}' and '{}'", - cmd.get_name(), - l, - first.name, - second.name - ) - } - } - - // Short conflicts - if let Some(s) = arg.short { - if let Some((first, second)) = cmd.two_args_of(|x| x.short == Some(s)) { - panic!( - "Command {}: Short option names must be unique for each argument, \ - but '-{}' is in use by both '{}' and '{}'", - cmd.get_name(), - s, - first.name, - second.name - ) - } - } - - // Index conflicts - if let Some(idx) = arg.index { - if let Some((first, second)) = - cmd.two_args_of(|x| x.is_positional() && x.index == Some(idx)) - { - panic!( - "Command {}: Argument '{}' has the same index as '{}' \ - and they are both positional arguments\n\n\t \ - Use Arg::multiple_values(true) to allow one \ - positional argument to take multiple values", - cmd.get_name(), - first.name, - second.name - ) - } - } - - // requires, r_if, r_unless - for req in &arg.requires { - assert!( - cmd.id_exists(&req.1), - "Command {}: Argument or group '{:?}' specified in 'requires*' for '{}' does not exist", - cmd.get_name(), - req.1, - arg.name, - ); - } - - for req in &arg.r_ifs { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_if_eq*`", - arg.name - ); - } - assert!( - cmd.id_exists(&req.0), - "Command {}: Argument or group '{:?}' specified in 'required_if_eq*' for '{}' does not exist", - cmd.get_name(), - req.0, - arg.name - ); - } - - for req in &arg.r_ifs_all { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_if_eq_all`", - arg.name - ); - } - assert!( - cmd.id_exists(&req.0), - "Command {}: Argument or group '{:?}' specified in 'required_if_eq_all' for '{}' does not exist", - cmd.get_name(), - req.0, - arg.name - ); - } - - for req in &arg.r_unless { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_unless*`", - arg.name - ); - } - assert!( - cmd.id_exists(req), - "Command {}: Argument or group '{:?}' specified in 'required_unless*' for '{}' does not exist", - cmd.get_name(), - req, - arg.name, - ); - } - - for req in &arg.r_unless_all { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_unless*`", - arg.name - ); - } - assert!( - cmd.id_exists(req), - "Command {}: Argument or group '{:?}' specified in 'required_unless*' for '{}' does not exist", - cmd.get_name(), - req, - arg.name, - ); - } - - // blacklist - for req in &arg.blacklist { - assert!( - cmd.id_exists(req), - "Command {}: Argument or group '{:?}' specified in 'conflicts_with*' for '{}' does not exist", - cmd.get_name(), - req, - arg.name, - ); - } - - if arg.is_last_set() { - assert!( - arg.long.is_none(), - "Command {}: Flags or Options cannot have last(true) set. '{}' has both a long and last(true) set.", - cmd.get_name(), - arg.name - ); - assert!( - arg.short.is_none(), - "Command {}: Flags or Options cannot have last(true) set. '{}' has both a short and last(true) set.", - cmd.get_name(), - arg.name - ); - } - - assert!( - !(arg.is_required_set() && arg.is_global_set()), - "Command {}: Global arguments cannot be required.\n\n\t'{}' is marked as both global and required", - cmd.get_name(), - arg.name - ); - - // validators - assert!( - arg.validator.is_none() || arg.validator_os.is_none(), - "Command {}: Argument '{}' has both `validator` and `validator_os` set which is not allowed", - cmd.get_name(), - arg.name - ); - - if arg.get_value_hint() == ValueHint::CommandWithArguments { - assert!( - arg.is_positional(), - "Command {}: Argument '{}' has hint CommandWithArguments and must be positional.", - cmd.get_name(), - arg.name - ); - - assert!( - cmd.is_trailing_var_arg_set(), - "Command {}: Positional argument '{}' has hint CommandWithArguments, so Command must have TrailingVarArg set.", - cmd.get_name(), - arg.name - ); - } - } - - for group in cmd.get_groups() { - // Name conflicts - assert!( - cmd.get_groups().filter(|x| x.id == group.id).count() < 2, - "Command {}: Argument group name must be unique\n\n\t'{}' is already in use", - cmd.get_name(), - group.name, - ); - - // Groups should not have naming conflicts with Args - assert!( - !cmd.get_arguments().any(|x| x.id == group.id), - "Command {}: Argument group name '{}' must not conflict with argument name", - cmd.get_name(), - group.name, - ); - - for arg in &group.args { - // Args listed inside groups should exist - assert!( - cmd.get_arguments().any(|x| x.id == *arg), - "Command {}: Argument group '{}' contains non-existent argument '{:?}'", - cmd.get_name(), - group.name, - arg - ); - } - } - - // Conflicts between flags and subcommands - - long_flags.sort_unstable(); - short_flags.sort_unstable(); - - detect_duplicate_flags(&long_flags, "long"); - detect_duplicate_flags(&short_flags, "short"); - - _verify_positionals(cmd); - - if let Some(help_template) = cmd.get_help_template() { - assert!( - !help_template.contains("{flags}"), - "Command {}: {}", - cmd.get_name(), - "`{flags}` template variable was removed in clap3, they are now included in `{options}`", - ); - assert!( - !help_template.contains("{unified}"), - "Command {}: {}", - cmd.get_name(), - "`{unified}` template variable was removed in clap3, use `{options}` instead" - ); - } - - cmd._panic_on_missing_help(cmd.is_help_expected_set()); - assert_app_flags(cmd); -} - -#[derive(Eq)] -enum Flag<'a> { - Command(String, &'a str), - Arg(String, &'a str), -} - -impl PartialEq for Flag<'_> { - fn eq(&self, other: &Flag) -> bool { - self.cmp(other) == Ordering::Equal - } -} - -impl PartialOrd for Flag<'_> { - fn partial_cmp(&self, other: &Flag) -> Option { - use Flag::*; - - match (self, other) { - (Command(s1, _), Command(s2, _)) - | (Arg(s1, _), Arg(s2, _)) - | (Command(s1, _), Arg(s2, _)) - | (Arg(s1, _), Command(s2, _)) => { - if s1 == s2 { - Some(Ordering::Equal) - } else { - s1.partial_cmp(s2) - } - } - } - } -} - -impl Ord for Flag<'_> { - fn cmp(&self, other: &Self) -> Ordering { - self.partial_cmp(other).unwrap() - } -} - -fn detect_duplicate_flags(flags: &[Flag], short_or_long: &str) { - use Flag::*; - - for (one, two) in find_duplicates(flags) { - match (one, two) { - (Command(flag, one), Command(_, another)) if one != another => panic!( - "the '{}' {} flag is specified for both '{}' and '{}' subcommands", - flag, short_or_long, one, another - ), - - (Arg(flag, one), Arg(_, another)) if one != another => panic!( - "{} option names must be unique, but '{}' is in use by both '{}' and '{}'", - short_or_long, flag, one, another - ), - - (Arg(flag, arg), Command(_, sub)) | (Command(flag, sub), Arg(_, arg)) => panic!( - "the '{}' {} flag for the '{}' argument conflicts with the short flag \ - for '{}' subcommand", - flag, short_or_long, arg, sub - ), - - _ => {} - } - } -} - -/// Find duplicates in a sorted array. -/// -/// The algorithm is simple: the array is sorted, duplicates -/// must be placed next to each other, we can check only adjacent elements. -fn find_duplicates(slice: &[T]) -> impl Iterator { - slice.windows(2).filter_map(|w| { - if w[0] == w[1] { - Some((&w[0], &w[1])) - } else { - None - } - }) -} - -fn assert_app_flags(cmd: &Command) { - macro_rules! checker { - ($a:ident requires $($b:ident)|+) => { - if cmd.$a() { - let mut s = String::new(); - - $( - if !cmd.$b() { - s.push_str(&format!(" AppSettings::{} is required when AppSettings::{} is set.\n", std::stringify!($b), std::stringify!($a))); - } - )+ - - if !s.is_empty() { - panic!("{}", s) - } - } - }; - ($a:ident conflicts $($b:ident)|+) => { - if cmd.$a() { - let mut s = String::new(); - - $( - if cmd.$b() { - s.push_str(&format!(" AppSettings::{} conflicts with AppSettings::{}.\n", std::stringify!($b), std::stringify!($a))); - } - )+ - - if !s.is_empty() { - panic!("{}\n{}", cmd.get_name(), s) - } - } - }; - } - - checker!(is_allow_invalid_utf8_for_external_subcommands_set requires is_allow_external_subcommands_set); - checker!(is_multicall_set conflicts is_no_binary_name_set); -} - -#[cfg(debug_assertions)] -fn _verify_positionals(cmd: &Command) -> bool { - debug!("Command::_verify_positionals"); - // Because you must wait until all arguments have been supplied, this is the first chance - // to make assertions on positional argument indexes - // - // First we verify that the index highest supplied index, is equal to the number of - // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3 - // but no 2) - - let highest_idx = cmd - .get_keymap() - .keys() - .filter_map(|x| { - if let KeyType::Position(n) = x { - Some(*n) - } else { - None - } - }) - .max() - .unwrap_or(0); - - let num_p = cmd.get_keymap().keys().filter(|x| x.is_position()).count(); - - assert!( - highest_idx == num_p, - "Found positional argument whose index is {} but there \ - are only {} positional arguments defined", - highest_idx, - num_p - ); - - // Next we verify that only the highest index has takes multiple arguments (if any) - let only_highest = |a: &Arg| a.is_multiple() && (a.index.unwrap_or(0) != highest_idx); - if cmd.get_positionals().any(only_highest) { - // First we make sure if there is a positional that allows multiple values - // the one before it (second to last) has one of these: - // * a value terminator - // * ArgSettings::Last - // * The last arg is Required - - // We can't pass the closure (it.next()) to the macro directly because each call to - // find() (iterator, not macro) gets called repeatedly. - let last = &cmd.get_keymap()[&KeyType::Position(highest_idx)]; - let second_to_last = &cmd.get_keymap()[&KeyType::Position(highest_idx - 1)]; - - // Either the final positional is required - // Or the second to last has a terminator or .last(true) set - let ok = last.is_required_set() - || (second_to_last.terminator.is_some() || second_to_last.is_last_set()) - || last.is_last_set(); - assert!( - ok, - "When using a positional argument with .multiple_values(true) that is *not the \ - last* positional argument, the last positional argument (i.e. the one \ - with the highest index) *must* have .required(true) or .last(true) set." - ); - - // We make sure if the second to last is Multiple the last is ArgSettings::Last - let ok = second_to_last.is_multiple() || last.is_last_set(); - assert!( - ok, - "Only the last positional argument, or second to last positional \ - argument may be set to .multiple_values(true)" - ); - - // Next we check how many have both Multiple and not a specific number of values set - let count = cmd - .get_positionals() - .filter(|p| { - #[allow(deprecated)] - { - p.is_multiple_occurrences_set() - || (p.is_multiple_values_set() && p.num_vals.is_none()) - } - }) - .count(); - let ok = count <= 1 - || (last.is_last_set() - && last.is_multiple() - && second_to_last.is_multiple() - && count == 2); - assert!( - ok, - "Only one positional argument with .multiple_values(true) set is allowed per \ - command, unless the second one also has .last(true) set" - ); - } - - let mut found = false; - - if cmd.is_allow_missing_positional_set() { - // Check that if a required positional argument is found, all positions with a lower - // index are also required. - let mut foundx2 = false; - - for p in cmd.get_positionals() { - if foundx2 && !p.is_required_set() { - assert!( - p.is_required_set(), - "Found non-required positional argument with a lower \ - index than a required positional argument by two or more: {:?} \ - index {:?}", - p.name, - p.index - ); - } else if p.is_required_set() && !p.is_last_set() { - // Args that .last(true) don't count since they can be required and have - // positionals with a lower index that aren't required - // Imagine: prog [opt1] -- - // Both of these are valid invocations: - // $ prog r1 -- r2 - // $ prog r1 o1 -- r2 - if found { - foundx2 = true; - continue; - } - found = true; - continue; - } else { - found = false; - } - } - } else { - // Check that if a required positional argument is found, all positions with a lower - // index are also required - for p in (1..=num_p).rev().filter_map(|n| cmd.get_keymap().get(&n)) { - if found { - assert!( - p.is_required_set(), - "Found non-required positional argument with a lower \ - index than a required positional argument: {:?} index {:?}", - p.name, - p.index - ); - } else if p.is_required_set() && !p.is_last_set() { - // Args that .last(true) don't count since they can be required and have - // positionals with a lower index that aren't required - // Imagine: prog [opt1] -- - // Both of these are valid invocations: - // $ prog r1 -- r2 - // $ prog r1 o1 -- r2 - found = true; - continue; - } - } - } - assert!( - cmd.get_positionals().filter(|p| p.is_last_set()).count() < 2, - "Only one positional argument may have last(true) set. Found two." - ); - if cmd - .get_positionals() - .any(|p| p.is_last_set() && p.is_required_set()) - && cmd.has_subcommands() - && !cmd.is_subcommand_negates_reqs_set() - { - panic!( - "Having a required positional argument with .last(true) set *and* child \ - subcommands without setting SubcommandsNegateReqs isn't compatible." - ); - } - - true -} - -fn assert_arg(arg: &Arg) { - debug!("Arg::_debug_asserts:{}", arg.name); - - // Self conflict - // TODO: this check should be recursive - assert!( - !arg.blacklist.iter().any(|x| *x == arg.id), - "Argument '{}' cannot conflict with itself", - arg.name, - ); - - assert_eq!( - arg.get_action().takes_values(), - arg.is_takes_value_set(), - "Argument `{}`'s selected action {:?} contradicts `takes_value`", - arg.name, - arg.get_action() - ); - if let Some(action_type_id) = arg.get_action().value_type_id() { - assert_eq!( - action_type_id, - arg.get_value_parser().type_id(), - "Argument `{}`'s selected action {:?} contradicts `value_parser` ({:?})", - arg.name, - arg.get_action(), - arg.get_value_parser() - ); - } - - if arg.get_value_hint() != ValueHint::Unknown { - assert!( - arg.is_takes_value_set(), - "Argument '{}' has value hint but takes no value", - arg.name - ); - - if arg.get_value_hint() == ValueHint::CommandWithArguments { - assert!( - arg.is_multiple_values_set(), - "Argument '{}' uses hint CommandWithArguments and must accept multiple values", - arg.name - ) - } - } - - if arg.index.is_some() { - assert!( - arg.is_positional(), - "Argument '{}' is a positional argument and can't have short or long name versions", - arg.name - ); - assert!( - arg.is_takes_value_set(), - "Argument '{}` is positional, it must take a value", - arg.name - ); - } - - #[cfg(feature = "unstable-v4")] - { - let num_vals = arg.get_num_vals().unwrap_or(usize::MAX); - let num_val_names = arg.get_value_names().unwrap_or(&[]).len(); - if num_vals < num_val_names { - panic!( - "Argument {}: Too many value names ({}) compared to number_of_values ({})", - arg.name, num_val_names, num_vals - ); - } - } - - assert_arg_flags(arg); - - assert_defaults(arg, "default_value", arg.default_vals.iter().copied()); - assert_defaults( - arg, - "default_missing_value", - arg.default_missing_vals.iter().copied(), - ); - assert_defaults( - arg, - "default_value_if", - arg.default_vals_ifs - .iter() - .filter_map(|(_, _, default)| *default), - ); -} - -fn assert_arg_flags(arg: &Arg) { - macro_rules! checker { - ($a:ident requires $($b:ident)|+) => { - if arg.$a() { - let mut s = String::new(); - - $( - if !arg.$b() { - s.push_str(&format!(" Arg::{} is required when Arg::{} is set.\n", std::stringify!($b), std::stringify!($a))); - } - )+ - - if !s.is_empty() { - panic!("Argument {:?}\n{}", arg.get_id(), s) - } - } - } - } - - checker!(is_require_value_delimiter_set requires is_takes_value_set); - checker!(is_require_value_delimiter_set requires is_use_value_delimiter_set); - checker!(is_hide_possible_values_set requires is_takes_value_set); - checker!(is_allow_hyphen_values_set requires is_takes_value_set); - checker!(is_require_equals_set requires is_takes_value_set); - checker!(is_last_set requires is_takes_value_set); - checker!(is_hide_default_value_set requires is_takes_value_set); - checker!(is_multiple_values_set requires is_takes_value_set); - checker!(is_ignore_case_set requires is_takes_value_set); - { - #![allow(deprecated)] - checker!(is_forbid_empty_values_set requires is_takes_value_set); - checker!(is_allow_invalid_utf8_set requires is_takes_value_set); - } -} - -fn assert_defaults<'d>( - arg: &Arg, - field: &'static str, - defaults: impl IntoIterator, -) { - for default_os in defaults { - if let Some(default_s) = default_os.to_str() { - if !arg.possible_vals.is_empty() { - if let Some(delim) = arg.get_value_delimiter() { - for part in default_s.split(delim) { - assert!( - arg.possible_vals.iter().any(|possible_val| { - possible_val.matches(part, arg.is_ignore_case_set()) - }), - "Argument `{}`'s {}={} doesn't match possible values", - arg.name, - field, - part - ) - } - } else { - assert!( - arg.possible_vals.iter().any(|possible_val| { - possible_val.matches(default_s, arg.is_ignore_case_set()) - }), - "Argument `{}`'s {}={} doesn't match possible values", - arg.name, - field, - default_s - ); - } - } - - if let Some(validator) = arg.validator.as_ref() { - let mut validator = validator.lock().unwrap(); - if let Some(delim) = arg.get_value_delimiter() { - for part in default_s.split(delim) { - if let Err(err) = validator(part) { - panic!( - "Argument `{}`'s {}={} failed validation: {}", - arg.name, field, part, err - ); - } - } - } else if let Err(err) = validator(default_s) { - panic!( - "Argument `{}`'s {}={} failed validation: {}", - arg.name, field, default_s, err - ); - } - } - } - - if let Some(validator) = arg.validator_os.as_ref() { - let mut validator = validator.lock().unwrap(); - if let Some(delim) = arg.get_value_delimiter() { - let default_os = RawOsStr::new(default_os); - for part in default_os.split(delim) { - if let Err(err) = validator(&part.to_os_str()) { - panic!( - "Argument `{}`'s {}={:?} failed validation: {}", - arg.name, field, part, err - ); - } - } - } else if let Err(err) = validator(default_os) { - panic!( - "Argument `{}`'s {}={:?} failed validation: {}", - arg.name, field, default_os, err - ); - } - } - - let value_parser = arg.get_value_parser(); - let assert_cmd = Command::new("assert"); - if let Some(delim) = arg.get_value_delimiter() { - let default_os = RawOsStr::new(default_os); - for part in default_os.split(delim) { - if let Err(err) = value_parser.parse_ref(&assert_cmd, Some(arg), &part.to_os_str()) - { - panic!( - "Argument `{}`'s {}={:?} failed validation: {}", - arg.name, - field, - part.to_str_lossy(), - err - ); - } - } - } else if let Err(err) = value_parser.parse_ref(&assert_cmd, Some(arg), default_os) { - panic!( - "Argument `{}`'s {}={:?} failed validation: {}", - arg.name, field, default_os, err - ); - } - } -} diff --git a/vendor/clap/src/builder/macros.rs b/vendor/clap/src/builder/macros.rs deleted file mode 100644 index 5be4d205e..000000000 --- a/vendor/clap/src/builder/macros.rs +++ /dev/null @@ -1,180 +0,0 @@ -#[cfg(feature = "yaml")] -macro_rules! yaml_tuple2 { - ($a:ident, $v:ident, $c:ident) => {{ - if let Some(vec) = $v.as_vec() { - for ys in vec { - if let Some(tup) = ys.as_vec() { - debug_assert_eq!(2, tup.len()); - $a = $a.$c(yaml_str!(tup[0]), yaml_str!(tup[1])); - } else { - panic!("Failed to convert YAML value to vec"); - } - } - } else { - panic!("Failed to convert YAML value to vec"); - } - $a - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_tuple3 { - ($a:ident, $v:ident, $c:ident) => {{ - if let Some(vec) = $v.as_vec() { - for ys in vec { - if let Some(tup) = ys.as_vec() { - debug_assert_eq!(3, tup.len()); - $a = $a.$c( - yaml_str!(tup[0]), - yaml_opt_str!(tup[1]), - yaml_opt_str!(tup[2]), - ); - } else { - panic!("Failed to convert YAML value to vec"); - } - } - } else { - panic!("Failed to convert YAML value to vec"); - } - $a - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_vec_or_str { - ($a:ident, $v:ident, $c:ident) => {{ - let maybe_vec = $v.as_vec(); - if let Some(vec) = maybe_vec { - for ys in vec { - if let Some(s) = ys.as_str() { - $a = $a.$c(s); - } else { - panic!("Failed to convert YAML value {:?} to a string", ys); - } - } - } else { - if let Some(s) = $v.as_str() { - $a = $a.$c(s); - } else { - panic!( - "Failed to convert YAML value {:?} to either a vec or string", - $v - ); - } - } - $a - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_vec { - ($a:ident, $v:ident, $c:ident) => {{ - let maybe_vec = $v.as_vec(); - if let Some(vec) = maybe_vec { - let content = vec.into_iter().map(|ys| { - if let Some(s) = ys.as_str() { - s - } else { - panic!("Failed to convert YAML value {:?} to a string", ys); - } - }); - $a = $a.$c(content) - } else { - panic!("Failed to convert YAML value {:?} to a vec", $v); - } - $a - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_opt_str { - ($v:expr) => {{ - if !$v.is_null() { - Some( - $v.as_str() - .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)), - ) - } else { - None - } - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_char { - ($v:expr) => {{ - $v.as_str() - .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)) - .chars() - .next() - .unwrap_or_else(|| panic!("Expected char")) - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_str { - ($v:expr) => {{ - $v.as_str() - .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)) - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_to_char { - ($a:ident, $v:ident, $c:ident) => {{ - $a.$c(yaml_char!($v)) - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_to_str { - ($a:ident, $v:ident, $c:ident) => {{ - $a.$c(yaml_str!($v)) - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_to_bool { - ($a:ident, $v:ident, $c:ident) => {{ - $a.$c($v - .as_bool() - .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))) - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_to_usize { - ($a:ident, $v:ident, $c:ident) => {{ - $a.$c($v - .as_i64() - .unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)) - as usize) - }}; -} - -#[cfg(feature = "yaml")] -macro_rules! yaml_to_setting { - ($a:ident, $v:ident, $c:ident, $s:ident, $t:literal, $n:expr) => {{ - if let Some(v) = $v.as_vec() { - for ys in v { - if let Some(s) = ys.as_str() { - $a = $a.$c(s.parse::<$s>().unwrap_or_else(|_| { - panic!("Unknown {} '{}' found in YAML file for {}", $t, s, $n) - })); - } else { - panic!( - "Failed to convert YAML {:?} value to an array of strings", - $v - ); - } - } - } else if let Some(v) = $v.as_str() { - $a = $a.$c(v - .parse::<$s>() - .unwrap_or_else(|_| panic!("Unknown {} '{}' found in YAML file for {}", $t, v, $n))) - } else { - panic!("Failed to convert YAML {:?} value to a string", $v); - } - $a - }}; -} diff --git a/vendor/clap/src/builder/mod.rs b/vendor/clap/src/builder/mod.rs deleted file mode 100644 index 4f24c74d3..000000000 --- a/vendor/clap/src/builder/mod.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Define [`Command`] line [arguments][`Arg`] - -#[macro_use] -mod macros; - -mod action; -mod app_settings; -mod arg; -mod arg_group; -mod arg_predicate; -mod arg_settings; -mod command; -mod possible_value; -mod usage_parser; -mod value_hint; -mod value_parser; - -#[cfg(feature = "regex")] -mod regex; - -#[cfg(debug_assertions)] -mod debug_asserts; - -#[cfg(test)] -mod tests; - -pub use action::ArgAction; -pub use app_settings::{AppFlags, AppSettings}; -pub use arg::Arg; -pub use arg_group::ArgGroup; -pub use arg_settings::{ArgFlags, ArgSettings}; -pub use command::Command; -pub use possible_value::PossibleValue; -pub use value_hint::ValueHint; -pub use value_parser::PossibleValuesParser; -pub use value_parser::RangedI64ValueParser; -pub use value_parser::RangedU64ValueParser; -pub use value_parser::StringValueParser; -pub use value_parser::TypedValueParser; -pub use value_parser::ValueParser; -pub use value_parser::ValueParserFactory; -pub use value_parser::_AnonymousValueParser; -pub use value_parser::_AutoValueParser; -pub use value_parser::via_prelude; -pub use value_parser::BoolValueParser; -pub use value_parser::BoolishValueParser; -pub use value_parser::EnumValueParser; -pub use value_parser::FalseyValueParser; -pub use value_parser::NonEmptyStringValueParser; -pub use value_parser::OsStringValueParser; -pub use value_parser::PathBufValueParser; - -#[allow(deprecated)] -pub use command::App; - -#[cfg(feature = "regex")] -pub use self::regex::RegexRef; - -pub(crate) use action::CountType; -pub(crate) use arg::display_arg_val; -pub(crate) use arg_predicate::ArgPredicate; diff --git a/vendor/clap/src/builder/possible_value.rs b/vendor/clap/src/builder/possible_value.rs deleted file mode 100644 index 1c14217a6..000000000 --- a/vendor/clap/src/builder/possible_value.rs +++ /dev/null @@ -1,259 +0,0 @@ -use std::{borrow::Cow, iter}; - -use crate::util::eq_ignore_case; - -/// A possible value of an argument. -/// -/// This is used for specifying [possible values] of [Args]. -/// -/// **NOTE:** This struct is likely not needed for most usecases as it is only required to -/// [hide] single values from help messages and shell completions or to attach [help] to possible values. -/// -/// # Examples -/// -/// ```rust -/// # use clap::{Arg, PossibleValue}; -/// let cfg = Arg::new("config") -/// .takes_value(true) -/// .value_name("FILE") -/// .value_parser([ -/// PossibleValue::new("fast"), -/// PossibleValue::new("slow").help("slower than fast"), -/// PossibleValue::new("secret speed").hide(true) -/// ]); -/// ``` -/// [Args]: crate::Arg -/// [possible values]: crate::builder::ValueParser::possible_values -/// [hide]: PossibleValue::hide() -/// [help]: PossibleValue::help() -#[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct PossibleValue<'help> { - name: &'help str, - help: Option<&'help str>, - aliases: Vec<&'help str>, // (name, visible) - hide: bool, -} - -impl<'help> PossibleValue<'help> { - /// Create a [`PossibleValue`] with its name. - /// - /// The name will be used to decide whether this value was provided by the user to an argument. - /// - /// **NOTE:** In case it is not [hidden] it will also be shown in help messages for arguments - /// that use it as a [possible value] and have not hidden them through [`Arg::hide_possible_values(true)`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::PossibleValue; - /// PossibleValue::new("fast") - /// # ; - /// ``` - /// [hidden]: PossibleValue::hide - /// [possible value]: crate::Arg::possible_values - /// [`Arg::hide_possible_values(true)`]: crate::Arg::hide_possible_values() - pub fn new(name: &'help str) -> Self { - PossibleValue { - name, - ..Default::default() - } - } - - /// Sets the help description of the value. - /// - /// This is typically displayed in completions (where supported) and should be a short, one-line - /// description. - /// - /// # Examples - /// - /// ```rust - /// # use clap::PossibleValue; - /// PossibleValue::new("slow") - /// .help("not fast") - /// # ; - /// ``` - #[inline] - #[must_use] - pub fn help(mut self, help: &'help str) -> Self { - self.help = Some(help); - self - } - - /// Hides this value from help and shell completions. - /// - /// This is an alternative to hiding through [`Arg::hide_possible_values(true)`], if you only - /// want to hide some values. - /// - /// # Examples - /// - /// ```rust - /// # use clap::PossibleValue; - /// PossibleValue::new("secret") - /// .hide(true) - /// # ; - /// ``` - /// [`Arg::hide_possible_values(true)`]: crate::Arg::hide_possible_values() - #[inline] - #[must_use] - pub fn hide(mut self, yes: bool) -> Self { - self.hide = yes; - self - } - - /// Sets a *hidden* alias for this argument value. - /// - /// # Examples - /// - /// ```rust - /// # use clap::PossibleValue; - /// PossibleValue::new("slow") - /// .alias("not-fast") - /// # ; - /// ``` - #[must_use] - pub fn alias(mut self, name: &'help str) -> Self { - self.aliases.push(name); - self - } - - /// Sets multiple *hidden* aliases for this argument value. - /// - /// # Examples - /// - /// ```rust - /// # use clap::PossibleValue; - /// PossibleValue::new("slow") - /// .aliases(["not-fast", "snake-like"]) - /// # ; - /// ``` - #[must_use] - pub fn aliases(mut self, names: I) -> Self - where - I: IntoIterator, - { - self.aliases.extend(names.into_iter()); - self - } -} - -/// Reflection -impl<'help> PossibleValue<'help> { - /// Get the name of the argument value - #[inline] - pub fn get_name(&self) -> &'help str { - self.name - } - - /// Get the help specified for this argument, if any - #[inline] - pub fn get_help(&self) -> Option<&'help str> { - self.help - } - - /// Get the help specified for this argument, if any and the argument - /// value is not hidden - #[inline] - #[cfg(feature = "unstable-v4")] - pub(crate) fn get_visible_help(&self) -> Option<&'help str> { - if !self.hide { - self.help - } else { - None - } - } - - /// Deprecated, replaced with [`PossibleValue::is_hide_set`] - #[inline] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `PossibleValue::is_hide_set`") - )] - pub fn is_hidden(&self) -> bool { - self.is_hide_set() - } - - /// Report if [`PossibleValue::hide`] is set - #[inline] - pub fn is_hide_set(&self) -> bool { - self.hide - } - - /// Report if PossibleValue is not hidden and has a help message - pub(crate) fn should_show_help(&self) -> bool { - !self.hide && self.help.is_some() - } - - /// Get the name if argument value is not hidden, `None` otherwise - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.4", - note = "Use `PossibleValue::is_hide_set` and `PossibleValue::get_name`" - ) - )] - pub fn get_visible_name(&self) -> Option<&'help str> { - if self.hide { - None - } else { - Some(self.name) - } - } - - /// Get the name if argument value is not hidden, `None` otherwise, - /// but wrapped in quotes if it contains whitespace - pub(crate) fn get_visible_quoted_name(&self) -> Option> { - if !self.hide { - Some(if self.name.contains(char::is_whitespace) { - format!("{:?}", self.name).into() - } else { - self.name.into() - }) - } else { - None - } - } - - /// Returns all valid values of the argument value. - /// - /// Namely the name and all aliases. - pub fn get_name_and_aliases(&self) -> impl Iterator + '_ { - iter::once(&self.name).chain(&self.aliases).copied() - } - - /// Tests if the value is valid for this argument value - /// - /// The value is valid if it is either the name or one of the aliases. - /// - /// # Examples - /// - /// ```rust - /// # use clap::PossibleValue; - /// let arg_value = PossibleValue::new("fast").alias("not-slow"); - /// - /// assert!(arg_value.matches("fast", false)); - /// assert!(arg_value.matches("not-slow", false)); - /// - /// assert!(arg_value.matches("FAST", true)); - /// assert!(!arg_value.matches("FAST", false)); - /// ``` - pub fn matches(&self, value: &str, ignore_case: bool) -> bool { - if ignore_case { - self.get_name_and_aliases() - .any(|name| eq_ignore_case(name, value)) - } else { - self.get_name_and_aliases().any(|name| name == value) - } - } -} - -impl<'help> From<&'help str> for PossibleValue<'help> { - fn from(s: &'help str) -> Self { - Self::new(s) - } -} - -impl<'help> From<&'help &'help str> for PossibleValue<'help> { - fn from(s: &'help &'help str) -> Self { - Self::new(s) - } -} diff --git a/vendor/clap/src/builder/regex.rs b/vendor/clap/src/builder/regex.rs deleted file mode 100644 index bf3a78e0c..000000000 --- a/vendor/clap/src/builder/regex.rs +++ /dev/null @@ -1,88 +0,0 @@ -use ::regex::{Error, Regex, RegexSet}; - -use core::{convert::TryFrom, ops::Deref, str::FromStr}; -use std::borrow::Cow; - -/// Contains either a regular expression or a set of them or a reference to one. -/// -/// See [Arg::validator_regex(][crate::Arg::validator_regex] to set this on an argument. -#[derive(Debug, Clone)] -pub enum RegexRef<'a> { - /// Used if the underlying is a regex set - RegexSet(Cow<'a, RegexSet>), - /// Used if the underlying is a regex - Regex(Cow<'a, Regex>), -} - -impl<'a> RegexRef<'a> { - pub(crate) fn is_match(&self, text: &str) -> bool { - match self { - Self::Regex(r) => r.deref().is_match(text), - Self::RegexSet(r) => r.deref().is_match(text), - } - } -} - -impl<'a> From<&'a Regex> for RegexRef<'a> { - fn from(r: &'a Regex) -> Self { - Self::Regex(Cow::Borrowed(r)) - } -} - -impl<'a> From for RegexRef<'a> { - fn from(r: Regex) -> Self { - Self::Regex(Cow::Owned(r)) - } -} - -impl<'a> From<&'a RegexSet> for RegexRef<'a> { - fn from(r: &'a RegexSet) -> Self { - Self::RegexSet(Cow::Borrowed(r)) - } -} - -impl<'a> From for RegexRef<'a> { - fn from(r: RegexSet) -> Self { - Self::RegexSet(Cow::Owned(r)) - } -} - -impl<'a> TryFrom<&'a str> for RegexRef<'a> { - type Error = ::Err; - - fn try_from(r: &'a str) -> Result { - Self::from_str(r) - } -} - -impl<'a> FromStr for RegexRef<'a> { - type Err = Error; - - fn from_str(s: &str) -> Result { - Regex::from_str(s).map(|v| Self::Regex(Cow::Owned(v))) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use core::convert::TryInto; - - #[test] - fn test_try_from_with_valid_string() { - let t: Result = "^Hello, World$".try_into(); - assert!(t.is_ok()) - } - - #[test] - fn test_try_from_with_invalid_string() { - let t: Result = "^Hello, World)$".try_into(); - assert!(t.is_err()); - } - - #[test] - fn from_str() { - let t: Result = RegexRef::from_str("^Hello, World"); - assert!(t.is_ok()); - } -} diff --git a/vendor/clap/src/builder/tests.rs b/vendor/clap/src/builder/tests.rs deleted file mode 100644 index 76c8b8785..000000000 --- a/vendor/clap/src/builder/tests.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::Arg; -use crate::Command; - -#[test] -fn propagate_version() { - let mut cmd = Command::new("test") - .propagate_version(true) - .version("1.1") - .subcommand(Command::new("sub1")); - cmd._propagate(); - assert_eq!( - cmd.get_subcommands().next().unwrap().get_version(), - Some("1.1") - ); -} - -#[test] -fn global_setting() { - let mut cmd = Command::new("test") - .disable_version_flag(true) - .subcommand(Command::new("subcmd")); - cmd._propagate(); - assert!(cmd - .get_subcommands() - .find(|s| s.get_name() == "subcmd") - .unwrap() - .is_disable_version_flag_set()); -} - -// This test will *fail to compile* if Command is not Send + Sync -#[test] -fn app_send_sync() { - fn foo(_: T) {} - foo(Command::new("test")) -} - -#[test] -fn issue_2090() { - let mut cmd = Command::new("cmd") - .disable_version_flag(true) - .subcommand(Command::new("sub")); - cmd._build_self(); - - assert!(cmd - .get_subcommands() - .next() - .unwrap() - .is_disable_version_flag_set()); -} - -// This test will *fail to compile* if Arg is not Send + Sync -#[test] -fn arg_send_sync() { - fn foo(_: T) {} - foo(Arg::new("test")) -} diff --git a/vendor/clap/src/builder/usage_parser.rs b/vendor/clap/src/builder/usage_parser.rs deleted file mode 100644 index 85d0d304e..000000000 --- a/vendor/clap/src/builder/usage_parser.rs +++ /dev/null @@ -1,1277 +0,0 @@ -#![allow(deprecated)] - -// Internal -use crate::builder::Arg; -use crate::builder::ArgSettings; -use crate::INTERNAL_ERROR_MSG; - -#[derive(PartialEq, Debug)] -enum UsageToken { - Name, - ValName, - Short, - Long, - Help, - Multiple, - Unknown, - Default, -} - -#[derive(Debug)] -pub(crate) struct UsageParser<'help> { - usage: &'help str, - pos: usize, - start: usize, - prev: UsageToken, - explicit_name_set: bool, -} - -impl<'help> UsageParser<'help> { - fn new(usage: &'help str) -> Self { - debug!("new: usage={:?}", usage); - UsageParser { - usage, - pos: 0, - start: 0, - prev: UsageToken::Unknown, - explicit_name_set: false, - } - } - - pub(crate) fn from_usage(usage: &'help str) -> Self { - debug!("UsageParser::from_usage"); - UsageParser::new(usage) - } - - pub(crate) fn parse(mut self) -> Arg<'help> { - debug!("UsageParser::parse"); - let mut arg = Arg::default(); - loop { - debug!("UsageParser::parse:iter: pos={}", self.pos); - self.stop_at(token); - if let Some(&c) = self.usage.as_bytes().get(self.pos) { - match c { - b'-' => self.short_or_long(&mut arg), - b'.' => self.multiple(&mut arg), - b'@' => self.default(&mut arg), - b'\'' => self.help(&mut arg), - _ => self.name(&mut arg), - } - } else { - break; - } - } - - debug!("UsageParser::parse: vals...{:?}", arg.val_names); - arg - } - - fn name(&mut self, arg: &mut Arg<'help>) { - debug!("UsageParser::name"); - if *self - .usage - .as_bytes() - .get(self.pos) - .expect(INTERNAL_ERROR_MSG) - == b'<' - && !self.explicit_name_set - { - arg.settings.set(ArgSettings::Required); - } - self.pos += 1; - self.stop_at(name_end); - let name = &self.usage[self.start..self.pos]; - if self.prev == UsageToken::Unknown { - debug!("UsageParser::name: setting name...{}", name); - arg.id = name.into(); - arg.name = name; - if arg.long.is_none() && arg.short.is_none() { - debug!("name: explicit name set..."); - self.explicit_name_set = true; - self.prev = UsageToken::Name; - } - } else { - debug!("UsageParser::name: setting val name...{}", name); - if arg.val_names.is_empty() { - arg.settings.set(ArgSettings::TakesValue); - } - let len = arg.val_names.len(); - arg.val_names.insert(len, name); - self.prev = UsageToken::ValName; - } - } - - fn stop_at(&mut self, f: F) - where - F: Fn(u8) -> bool, - { - debug!("UsageParser::stop_at"); - self.start = self.pos; - self.pos += self.usage[self.start..] - .bytes() - .take_while(|&b| f(b)) - .count(); - } - - fn short_or_long(&mut self, arg: &mut Arg<'help>) { - debug!("UsageParser::short_or_long"); - self.pos += 1; - if *self - .usage - .as_bytes() - .get(self.pos) - .expect(INTERNAL_ERROR_MSG) - == b'-' - { - self.pos += 1; - self.long(arg); - return; - } - self.short(arg) - } - - fn long(&mut self, arg: &mut Arg<'help>) { - debug!("UsageParser::long"); - self.stop_at(long_end); - let name = &self.usage[self.start..self.pos]; - if !self.explicit_name_set { - debug!("UsageParser::long: setting name...{}", name); - arg.id = name.into(); - arg.name = name; - } - debug!("UsageParser::long: setting long...{}", name); - arg.long = Some(name); - self.prev = UsageToken::Long; - } - - fn short(&mut self, arg: &mut Arg<'help>) { - debug!("UsageParser::short"); - let start = &self.usage[self.pos..]; - let short = start.chars().next().expect(INTERNAL_ERROR_MSG); - debug!("UsageParser::short: setting short...{}", short); - arg.short = Some(short); - if arg.name.is_empty() { - // --long takes precedence but doesn't set self.explicit_name_set - let name = &start[..short.len_utf8()]; - debug!("UsageParser::short: setting name...{}", name); - arg.id = name.into(); - arg.name = name; - } - self.prev = UsageToken::Short; - } - - // "something..." - fn multiple(&mut self, arg: &mut Arg) { - debug!("UsageParser::multiple"); - let mut dot_counter = 1; - let start = self.pos; - let mut bytes = self.usage[start..].bytes(); - while bytes.next() == Some(b'.') { - dot_counter += 1; - self.pos += 1; - if dot_counter == 3 { - debug!("UsageParser::multiple: setting multiple"); - arg.settings.set(ArgSettings::MultipleOccurrences); - if arg.is_takes_value_set() { - arg.settings.set(ArgSettings::MultipleValues); - arg.settings.set(ArgSettings::UseValueDelimiter); - arg.val_delim.get_or_insert(','); - } - self.prev = UsageToken::Multiple; - self.pos += 1; - break; - } - } - } - - fn help(&mut self, arg: &mut Arg<'help>) { - debug!("UsageParser::help"); - self.stop_at(help_start); - self.start = self.pos + 1; - self.pos = self.usage.len() - 1; - debug!( - "UsageParser::help: setting help...{}", - &self.usage[self.start..self.pos] - ); - arg.help = Some(&self.usage[self.start..self.pos]); - self.pos += 1; // Move to next byte to keep from thinking ending ' is a start - self.prev = UsageToken::Help; - } - - fn default(&mut self, arg: &mut Arg<'help>) { - debug!( - "UsageParser::default: from=\"{}\"", - &self.usage[self.pos..self.usage.len()] - ); - self.pos += 1; // Skip @ - self.stop_at(default_value_end); // Find first space after value - debug!( - "UsageParser::default: setting default...\"{}\"", - &self.usage[self.start..self.pos] - ); - arg.settings.set(ArgSettings::TakesValue); - arg.default_vals = vec![std::ffi::OsStr::new(&self.usage[self.start..self.pos])]; - self.prev = UsageToken::Default; - } -} - -#[inline] -fn name_end(b: u8) -> bool { - b != b']' && b != b'>' -} - -#[inline] -fn token(b: u8) -> bool { - b != b'\'' && b != b'.' && b != b'<' && b != b'[' && b != b'-' && b != b'@' -} - -#[inline] -fn long_end(b: u8) -> bool { - b != b'\'' && b != b'.' && b != b'<' && b != b'[' && b != b'=' && b != b' ' -} - -#[inline] -fn help_start(b: u8) -> bool { - b != b'\'' -} - -#[inline] -fn default_value_end(b: u8) -> bool { - b != b' ' -} - -#[cfg(test)] -mod test { - #![allow(deprecated)] - - use crate::builder::{Arg, ArgSettings}; - - #[allow(clippy::cognitive_complexity)] - #[test] - fn create_flag_usage() { - let a = Arg::from_usage("[flag] -f 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.long.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("[flag] --flag 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.long.unwrap(), "flag"); - assert!(a.short.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("--flag 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.long.unwrap(), "flag"); - assert!(a.short.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("[flag] -f --flag 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.short.unwrap(), 'f'); - assert_eq!(a.long.unwrap(), "flag"); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("[flag] -f... 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.long.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("[flag] -f --flag... 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.long.unwrap(), "flag"); - assert_eq!(a.short.unwrap(), 'f'); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("-f --flag... 'some help info'"); - assert_eq!(a.name, "flag"); - assert_eq!(a.long.unwrap(), "flag"); - assert_eq!(a.short.unwrap(), 'f'); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("--flags"); - assert_eq!(a.name, "flags"); - assert_eq!(a.long.unwrap(), "flags"); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("--flags..."); - assert_eq!(a.name, "flags"); - assert_eq!(a.long.unwrap(), "flags"); - assert!(a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("[flags] -f"); - assert_eq!(a.name, "flags"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("[flags] -f..."); - assert_eq!(a.name, "flags"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("-f 'some help info'"); - assert_eq!(a.name, "f"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.long.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("-f"); - assert_eq!(a.name, "f"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.val_names.is_empty()); - - let a = Arg::from_usage("-f..."); - assert_eq!(a.name, "f"); - assert_eq!(a.short.unwrap(), 'f'); - assert!(a.is_multiple_occurrences_set()); - assert!(a.val_names.is_empty()); - } - - #[test] - fn create_option_usage0() { - // Short only - let a = Arg::from_usage("[option] -o [opt] 'some help info'"); - assert_eq!(a.name, "option"); - assert_eq!(a.short.unwrap(), 'o'); - assert!(a.long.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(!a.is_multiple_values_set()); - assert!(a.is_takes_value_set()); - assert!(!a.is_required_set()); - assert_eq!(a.val_names.iter().collect::>(), [&"opt"]); - } - - #[test] - fn create_option_usage1() { - let a = Arg::from_usage("-o [opt] 'some help info'"); - assert_eq!(a.name, "o"); - assert_eq!(a.short.unwrap(), 'o'); - assert!(a.long.is_none()); - assert_eq!(a.help.unwrap(), "some help info"); - assert!(!a.is_multiple_occurrences_set()); - assert!(!a.is_multiple_values_set()); - assert!(a.is_takes_value_set()); - assert!(!a.is_required_set()); - assert_eq!(a.val_names.iter().collect::>(), [&"opt"]); - } - - #[test] - fn create_option_usage2() { - let a = Arg::from_usage("

(&mut self, mut pred: P) -> Option<(usize, Self::Item)> where P: FnMut(&Self::Item) -> bool { - let mut index = 0usize; - for elt in self { + for (index, elt) in self.enumerate() { if pred(&elt) { return Some((index, elt)); } - index += 1; } None } @@ -1795,7 +1795,7 @@ pub trait Itertools : Iterator { Some(if predicate(&first) { first } else { - self.find(|x| predicate(&x)).unwrap_or(first) + self.find(|x| predicate(x)).unwrap_or(first) }) } /// Returns `true` if the given item is present in this iterator. @@ -1953,7 +1953,7 @@ pub trait Itertools : Iterator { where F: FnMut(Self::Item), Self: Sized, { - self.for_each(f) + self.for_each(f); } /// Combine all an iterator's elements into one element by using [`Extend`]. @@ -2271,7 +2271,7 @@ pub trait Itertools : Iterator { /// ``` /// /// Which, for non-associative functions, will typically produce a different - /// result than the linear call tree used by `fold1`: + /// result than the linear call tree used by [`Iterator::reduce`]: /// /// ```text /// 1 2 3 4 5 6 7 @@ -2279,7 +2279,7 @@ pub trait Itertools : Iterator { /// └─f─f─f─f─f─f /// ``` /// - /// If `f` is associative, prefer the normal `fold1` instead. + /// If `f` is associative, prefer the normal [`Iterator::reduce`] instead. /// /// ``` /// use itertools::Itertools; @@ -2692,7 +2692,6 @@ pub trait Itertools : Iterator { /// itertools::assert_equal(oldest_people_first, /// vec!["Jill", "Jack", "Jane", "John"]); /// ``` - /// ``` #[cfg(feature = "use_alloc")] fn sorted_by_cached_key(self, f: F) -> VecIntoIter where @@ -2902,6 +2901,194 @@ pub trait Itertools : Iterator { grouping_map::new(grouping_map::MapForGrouping::new(self, key_mapper)) } + /// Return all minimum elements of an iterator. + /// + /// # Examples + /// + /// ``` + /// use itertools::Itertools; + /// + /// let a: [i32; 0] = []; + /// assert_eq!(a.iter().min_set(), Vec::<&i32>::new()); + /// + /// let a = [1]; + /// assert_eq!(a.iter().min_set(), vec![&1]); + /// + /// let a = [1, 2, 3, 4, 5]; + /// assert_eq!(a.iter().min_set(), vec![&1]); + /// + /// let a = [1, 1, 1, 1]; + /// assert_eq!(a.iter().min_set(), vec![&1, &1, &1, &1]); + /// ``` + /// + /// The elements can be floats but no particular result is guaranteed + /// if an element is NaN. + #[cfg(feature = "use_std")] + fn min_set(self) -> Vec + where Self: Sized, Self::Item: Ord + { + extrema_set::min_set_impl(self, |_| (), |x, y, _, _| x.cmp(y)) + } + + /// Return all minimum elements of an iterator, as determined by + /// the specified function. + /// + /// # Examples + /// + /// ``` + /// # use std::cmp::Ordering; + /// use itertools::Itertools; + /// + /// let a: [(i32, i32); 0] = []; + /// assert_eq!(a.iter().min_set_by(|_, _| Ordering::Equal), Vec::<&(i32, i32)>::new()); + /// + /// let a = [(1, 2)]; + /// assert_eq!(a.iter().min_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2)]); + /// + /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)]; + /// assert_eq!(a.iter().min_set_by(|&&(_,k1), &&(_,k2)| k1.cmp(&k2)), vec![&(1, 2), &(2, 2)]); + /// + /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)]; + /// assert_eq!(a.iter().min_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]); + /// ``` + /// + /// The elements can be floats but no particular result is guaranteed + /// if an element is NaN. + #[cfg(feature = "use_std")] + fn min_set_by(self, mut compare: F) -> Vec + where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering + { + extrema_set::min_set_impl( + self, + |_| (), + |x, y, _, _| compare(x, y) + ) + } + + /// Return all minimum elements of an iterator, as determined by + /// the specified function. + /// + /// # Examples + /// + /// ``` + /// use itertools::Itertools; + /// + /// let a: [(i32, i32); 0] = []; + /// assert_eq!(a.iter().min_set_by_key(|_| ()), Vec::<&(i32, i32)>::new()); + /// + /// let a = [(1, 2)]; + /// assert_eq!(a.iter().min_set_by_key(|&&(k,_)| k), vec![&(1, 2)]); + /// + /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)]; + /// assert_eq!(a.iter().min_set_by_key(|&&(_, k)| k), vec![&(1, 2), &(2, 2)]); + /// + /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)]; + /// assert_eq!(a.iter().min_set_by_key(|&&(k, _)| k), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]); + /// ``` + /// + /// The elements can be floats but no particular result is guaranteed + /// if an element is NaN. + #[cfg(feature = "use_std")] + fn min_set_by_key(self, key: F) -> Vec + where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K + { + extrema_set::min_set_impl(self, key, |_, _, kx, ky| kx.cmp(ky)) + } + + /// Return all maximum elements of an iterator. + /// + /// # Examples + /// + /// ``` + /// use itertools::Itertools; + /// + /// let a: [i32; 0] = []; + /// assert_eq!(a.iter().max_set(), Vec::<&i32>::new()); + /// + /// let a = [1]; + /// assert_eq!(a.iter().max_set(), vec![&1]); + /// + /// let a = [1, 2, 3, 4, 5]; + /// assert_eq!(a.iter().max_set(), vec![&5]); + /// + /// let a = [1, 1, 1, 1]; + /// assert_eq!(a.iter().max_set(), vec![&1, &1, &1, &1]); + /// ``` + /// + /// The elements can be floats but no particular result is guaranteed + /// if an element is NaN. + #[cfg(feature = "use_std")] + fn max_set(self) -> Vec + where Self: Sized, Self::Item: Ord + { + extrema_set::max_set_impl(self, |_| (), |x, y, _, _| x.cmp(y)) + } + + /// Return all maximum elements of an iterator, as determined by + /// the specified function. + /// + /// # Examples + /// + /// ``` + /// # use std::cmp::Ordering; + /// use itertools::Itertools; + /// + /// let a: [(i32, i32); 0] = []; + /// assert_eq!(a.iter().max_set_by(|_, _| Ordering::Equal), Vec::<&(i32, i32)>::new()); + /// + /// let a = [(1, 2)]; + /// assert_eq!(a.iter().max_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2)]); + /// + /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)]; + /// assert_eq!(a.iter().max_set_by(|&&(_,k1), &&(_,k2)| k1.cmp(&k2)), vec![&(3, 9), &(5, 9)]); + /// + /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)]; + /// assert_eq!(a.iter().max_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]); + /// ``` + /// + /// The elements can be floats but no particular result is guaranteed + /// if an element is NaN. + #[cfg(feature = "use_std")] + fn max_set_by(self, mut compare: F) -> Vec + where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering + { + extrema_set::max_set_impl( + self, + |_| (), + |x, y, _, _| compare(x, y) + ) + } + + /// Return all minimum elements of an iterator, as determined by + /// the specified function. + /// + /// # Examples + /// + /// ``` + /// use itertools::Itertools; + /// + /// let a: [(i32, i32); 0] = []; + /// assert_eq!(a.iter().max_set_by_key(|_| ()), Vec::<&(i32, i32)>::new()); + /// + /// let a = [(1, 2)]; + /// assert_eq!(a.iter().max_set_by_key(|&&(k,_)| k), vec![&(1, 2)]); + /// + /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)]; + /// assert_eq!(a.iter().max_set_by_key(|&&(_, k)| k), vec![&(3, 9), &(5, 9)]); + /// + /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)]; + /// assert_eq!(a.iter().max_set_by_key(|&&(k, _)| k), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]); + /// ``` + /// + /// The elements can be floats but no particular result is guaranteed + /// if an element is NaN. + #[cfg(feature = "use_std")] + fn max_set_by_key(self, key: F) -> Vec + where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K + { + extrema_set::max_set_impl(self, key, |_, _, kx, ky| kx.cmp(ky)) + } + /// Return the minimum and maximum elements in the iterator. /// /// The return type `MinMaxResult` is an enum of three variants: @@ -3157,7 +3344,7 @@ pub trait Itertools : Iterator { /// be equal to `ypos`. /// /// On an iterator of length `n`, `position_minmax` does `1.5 * n` - /// comparisons, and so is faster than calling `positon_min` and + /// comparisons, and so is faster than calling `position_min` and /// `position_max` separately which does `2 * n` comparisons. /// /// For the minimum, if several elements are equally minimum, the @@ -3478,8 +3665,7 @@ impl Itertools for T where T: Iterator { } /// (elements pairwise equal and sequences of the same length), /// `false` otherwise. /// -/// This is an [`IntoIterator`] enabled function that is similar to the standard -/// library method [`Iterator::eq`]. +/// [`IntoIterator`] enabled version of [`Iterator::eq`]. /// /// ``` /// assert!(itertools::equal(vec![1, 2, 3], 1..4)); @@ -3490,17 +3676,7 @@ pub fn equal(a: I, b: J) -> bool J: IntoIterator, I::Item: PartialEq { - let mut ia = a.into_iter(); - let mut ib = b.into_iter(); - loop { - match ia.next() { - Some(x) => match ib.next() { - Some(y) => if x != y { return false; }, - None => return false, - }, - None => return ib.next().is_none() - } - } + a.into_iter().eq(b) } /// Assert that two iterables produce equal sequences, with the same diff --git a/vendor/itertools/src/merge_join.rs b/vendor/itertools/src/merge_join.rs index 4c0048f68..f2fbdea2c 100644 --- a/vendor/itertools/src/merge_join.rs +++ b/vendor/itertools/src/merge_join.rs @@ -4,10 +4,12 @@ use std::fmt; use super::adaptors::{PutBack, put_back}; use crate::either_or_both::EitherOrBoth; +#[cfg(doc)] +use crate::Itertools; /// Return an iterator adaptor that merge-joins items from the two base iterators in ascending order. /// -/// See [`.merge_join_by()`](crate::Itertools::merge_join_by) for more information. +/// [`IntoIterator`] enabled version of [`Itertools::merge_join_by`]. pub fn merge_join_by(left: I, right: J, cmp_fn: F) -> MergeJoinBy where I: IntoIterator, diff --git a/vendor/itertools/src/multipeek_impl.rs b/vendor/itertools/src/multipeek_impl.rs index 5917681fc..8b49c695e 100644 --- a/vendor/itertools/src/multipeek_impl.rs +++ b/vendor/itertools/src/multipeek_impl.rs @@ -2,6 +2,8 @@ use std::iter::Fuse; use alloc::collections::VecDeque; use crate::size_hint; use crate::PeekingNext; +#[cfg(doc)] +use crate::Itertools; /// See [`multipeek()`] for more information. #[derive(Clone, Debug)] @@ -15,6 +17,8 @@ pub struct MultiPeek /// An iterator adaptor that allows the user to peek at multiple `.next()` /// values without advancing the base iterator. +/// +/// [`IntoIterator`] enabled version of [`Itertools::multipeek`]. pub fn multipeek(iterable: I) -> MultiPeek where I: IntoIterator { @@ -67,10 +71,8 @@ impl PeekingNext for MultiPeek if let Some(r) = self.peek() { if !accept(r) { return None } } - } else { - if let Some(r) = self.buf.get(0) { - if !accept(r) { return None } - } + } else if let Some(r) = self.buf.get(0) { + if !accept(r) { return None } } self.next() } diff --git a/vendor/itertools/src/pad_tail.rs b/vendor/itertools/src/pad_tail.rs index de57ee416..248a43243 100644 --- a/vendor/itertools/src/pad_tail.rs +++ b/vendor/itertools/src/pad_tail.rs @@ -23,7 +23,7 @@ where debug_fmt_fields!(PadUsing, iter, min, pos); } -/// Create a new **PadUsing** iterator. +/// Create a new `PadUsing` iterator. pub fn pad_using(iter: I, min: usize, filler: F) -> PadUsing where I: Iterator, F: FnMut(usize) -> I::Item diff --git a/vendor/itertools/src/peeking_take_while.rs b/vendor/itertools/src/peeking_take_while.rs index cd0945a52..b3a9c5ccb 100644 --- a/vendor/itertools/src/peeking_take_while.rs +++ b/vendor/itertools/src/peeking_take_while.rs @@ -90,7 +90,7 @@ where debug_fmt_fields!(PeekingTakeWhile, iter); } -/// Create a PeekingTakeWhile +/// Create a `PeekingTakeWhile` pub fn peeking_take_while(iter: &mut I, f: F) -> PeekingTakeWhile where I: Iterator, { diff --git a/vendor/itertools/src/permutations.rs b/vendor/itertools/src/permutations.rs index 3080f9d5c..d03b85262 100644 --- a/vendor/itertools/src/permutations.rs +++ b/vendor/itertools/src/permutations.rs @@ -113,19 +113,15 @@ where Some(indices.map(|i| vals[i].clone()).collect()) } - PermutationState::Complete(CompleteState::Start { .. }) => None, PermutationState::Complete(CompleteState::Ongoing { ref indices, ref cycles }) => { let k = cycles.len(); - Some(indices[0..k].iter().map(|&i| vals[i].clone()).collect()) }, - PermutationState::Empty => None + PermutationState::Complete(CompleteState::Start { .. }) | PermutationState::Empty => None } } fn count(self) -> usize { - let Permutations { vals, state } = self; - fn from_complete(complete_state: CompleteState) -> usize { match complete_state.remaining() { CompleteStateRemaining::Known(count) => count, @@ -135,6 +131,7 @@ where } } + let Permutations { vals, state } = self; match state { PermutationState::StartUnknownLen { k } => { let n = vals.len() + vals.it.count(); diff --git a/vendor/itertools/src/rciter_impl.rs b/vendor/itertools/src/rciter_impl.rs index 782908e28..7298350a8 100644 --- a/vendor/itertools/src/rciter_impl.rs +++ b/vendor/itertools/src/rciter_impl.rs @@ -51,7 +51,6 @@ pub fn rciter(iterable: I) -> RcIter } impl Clone for RcIter { - #[inline] clone_fields!(rciter); } diff --git a/vendor/itertools/src/size_hint.rs b/vendor/itertools/src/size_hint.rs index 1168ecaa3..71ea1412b 100644 --- a/vendor/itertools/src/size_hint.rs +++ b/vendor/itertools/src/size_hint.rs @@ -1,14 +1,14 @@ -//! Arithmetic on **Iterator** *.size_hint()* values. +//! Arithmetic on `Iterator.size_hint()` values. //! use std::usize; use std::cmp; use std::u32; -/// **SizeHint** is the return type of **Iterator::size_hint()**. +/// `SizeHint` is the return type of `Iterator::size_hint()`. pub type SizeHint = (usize, Option); -/// Add **SizeHint** correctly. +/// Add `SizeHint` correctly. #[inline] pub fn add(a: SizeHint, b: SizeHint) -> SizeHint { let min = a.0.saturating_add(b.0); @@ -20,7 +20,7 @@ pub fn add(a: SizeHint, b: SizeHint) -> SizeHint { (min, max) } -/// Add **x** correctly to a **SizeHint**. +/// Add `x` correctly to a `SizeHint`. #[inline] pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint { let (mut low, mut hi) = sh; @@ -29,7 +29,7 @@ pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint { (low, hi) } -/// Sbb **x** correctly to a **SizeHint**. +/// Subtract `x` correctly from a `SizeHint`. #[inline] #[allow(dead_code)] pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint { @@ -40,7 +40,7 @@ pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint { } -/// Multiply **SizeHint** correctly +/// Multiply `SizeHint` correctly /// /// ```ignore /// use std::usize; @@ -66,7 +66,7 @@ pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint { (low, hi) } -/// Multiply **x** correctly with a **SizeHint**. +/// Multiply `x` correctly with a `SizeHint`. #[inline] pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint { let (mut low, mut hi) = sh; @@ -75,7 +75,7 @@ pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint { (low, hi) } -/// Raise `base` correctly by a **`SizeHint`** exponent. +/// Raise `base` correctly by a `SizeHint` exponent. #[inline] pub fn pow_scalar_base(base: usize, exp: SizeHint) -> SizeHint { let exp_low = cmp::min(exp.0, u32::MAX as usize) as u32; diff --git a/vendor/itertools/src/tuple_impl.rs b/vendor/itertools/src/tuple_impl.rs index d914e0323..06b5c13cb 100644 --- a/vendor/itertools/src/tuple_impl.rs +++ b/vendor/itertools/src/tuple_impl.rs @@ -162,8 +162,8 @@ pub fn tuple_windows(mut iter: I) -> TupleWindows } TupleWindows { - last, iter, + last, } } diff --git a/vendor/itertools/src/unique_impl.rs b/vendor/itertools/src/unique_impl.rs index 2240f36ed..4e81e78ec 100644 --- a/vendor/itertools/src/unique_impl.rs +++ b/vendor/itertools/src/unique_impl.rs @@ -1,6 +1,5 @@ - use std::collections::HashMap; -use std::collections::hash_map::{Entry}; +use std::collections::hash_map::Entry; use std::hash::Hash; use std::fmt; use std::iter::FusedIterator; @@ -12,7 +11,9 @@ use std::iter::FusedIterator; #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct UniqueBy { iter: I, - // Use a hashmap for the entry API + // Use a Hashmap for the Entry API in order to prevent hashing twice. + // This can maybe be replaced with a HashSet once `get_or_insert_with` + // or a proper Entry API for Hashset is stable and meets this msrv used: HashMap, f: F, } diff --git a/vendor/itertools/src/unziptuple.rs b/vendor/itertools/src/unziptuple.rs index f468f05e0..7af29ec4a 100644 --- a/vendor/itertools/src/unziptuple.rs +++ b/vendor/itertools/src/unziptuple.rs @@ -39,11 +39,11 @@ macro_rules! impl_unzip_iter { #[allow(non_snake_case)] impl, $($T, $FromT: Default + Extend<$T>),* > MultiUnzip<($($FromT,)*)> for IT { fn multiunzip(self) -> ($($FromT,)*) { - // This implementation mirrors the logic of Iterator::unzip as close as possible. - // Unfortunately a lot of the used api there is still unstable represented by - // the commented out parts that follow. + // This implementation mirrors the logic of Iterator::unzip resp. Extend for (A, B) as close as possible. + // Unfortunately a lot of the used api there is still unstable (https://github.com/rust-lang/rust/issues/72631). // - // https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.html#2816-2844 + // Iterator::unzip: https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.html#2825-2865 + // Extend for (A, B): https://doc.rust-lang.org/src/core/iter/traits/collect.rs.html#370-411 let mut res = ($($FromT::default(),)*); let ($($FromT,)*) = &mut res; diff --git a/vendor/itertools/src/ziptuple.rs b/vendor/itertools/src/ziptuple.rs index b7902ae53..6d3a584c4 100644 --- a/vendor/itertools/src/ziptuple.rs +++ b/vendor/itertools/src/ziptuple.rs @@ -36,6 +36,7 @@ pub struct Zip { /// /// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]); /// ``` +/// [`izip!()`]: crate::izip pub fn multizip(t: U) -> Zip where Zip: From, Zip: Iterator, diff --git a/vendor/itertools/tests/adaptors_no_collect.rs b/vendor/itertools/tests/adaptors_no_collect.rs index a47f906f9..103db23f1 100644 --- a/vendor/itertools/tests/adaptors_no_collect.rs +++ b/vendor/itertools/tests/adaptors_no_collect.rs @@ -11,12 +11,11 @@ impl Iterator for PanickingCounter { fn next(&mut self) -> Option { self.curr += 1; - if self.curr == self.max { - panic!( - "Input iterator reached maximum of {} suggesting collection by adaptor", - self.max - ); - } + assert_ne!( + self.curr, self.max, + "Input iterator reached maximum of {} suggesting collection by adaptor", + self.max + ); Some(()) } diff --git a/vendor/itertools/tests/quick.rs b/vendor/itertools/tests/quick.rs index 7e222a641..0adcf1ad7 100644 --- a/vendor/itertools/tests/quick.rs +++ b/vendor/itertools/tests/quick.rs @@ -258,12 +258,13 @@ where let mut it = get_it(); for _ in 0..(counts.len() - 1) { - if let None = it.next() { + #[allow(clippy::manual_assert)] + if it.next().is_none() { panic!("Iterator shouldn't be finished, may not be deterministic"); } } - if let None = it.next() { + if it.next().is_none() { break 'outer; } @@ -438,7 +439,7 @@ quickcheck! { } assert_eq!(answer, actual); - assert_eq!(answer.into_iter().last(), a.clone().multi_cartesian_product().last()); + assert_eq!(answer.into_iter().last(), a.multi_cartesian_product().last()); } #[allow(deprecated)] @@ -498,15 +499,13 @@ quickcheck! { exact_size(it) } - fn equal_merge(a: Vec, b: Vec) -> bool { - let mut sa = a.clone(); - let mut sb = b.clone(); - sa.sort(); - sb.sort(); - let mut merged = sa.clone(); - merged.extend(sb.iter().cloned()); + fn equal_merge(mut a: Vec, mut b: Vec) -> bool { + a.sort(); + b.sort(); + let mut merged = a.clone(); + merged.extend(b.iter().cloned()); merged.sort(); - itertools::equal(&merged, sa.iter().merge(&sb)) + itertools::equal(&merged, a.iter().merge(&b)) } fn size_merge(a: Iter, b: Iter) -> bool { correct_size_hint(a.merge(b)) @@ -517,7 +516,7 @@ quickcheck! { exact_size(multizip((a, b, c))) } fn size_zip_rc(a: Iter, b: Iter) -> bool { - let rc = rciter(a.clone()); + let rc = rciter(a); correct_size_hint(multizip((&rc, &rc, b))) } @@ -526,19 +525,16 @@ quickcheck! { correct_size_hint(izip!(filt, b.clone(), c.clone())) && exact_size(izip!(a, b, c)) } - fn equal_kmerge(a: Vec, b: Vec, c: Vec) -> bool { + fn equal_kmerge(mut a: Vec, mut b: Vec, mut c: Vec) -> bool { use itertools::free::kmerge; - let mut sa = a.clone(); - let mut sb = b.clone(); - let mut sc = c.clone(); - sa.sort(); - sb.sort(); - sc.sort(); - let mut merged = sa.clone(); - merged.extend(sb.iter().cloned()); - merged.extend(sc.iter().cloned()); + a.sort(); + b.sort(); + c.sort(); + let mut merged = a.clone(); + merged.extend(b.iter().cloned()); + merged.extend(c.iter().cloned()); merged.sort(); - itertools::equal(merged.into_iter(), kmerge(vec![sa, sb, sc])) + itertools::equal(merged.into_iter(), kmerge(vec![a, b, c])) } // Any number of input iterators @@ -610,7 +606,7 @@ quickcheck! { fn size_2_zip_longest(a: Iter, b: Iter) -> bool { let it = a.clone().zip_longest(b.clone()); let jt = a.clone().zip_longest(b.clone()); - itertools::equal(a.clone(), + itertools::equal(a, it.filter_map(|elt| match elt { EitherOrBoth::Both(x, _) => Some(x), EitherOrBoth::Left(x) => Some(x), @@ -618,7 +614,7 @@ quickcheck! { } )) && - itertools::equal(b.clone(), + itertools::equal(b, jt.filter_map(|elt| match elt { EitherOrBoth::Both(_, y) => Some(y), EitherOrBoth::Right(y) => Some(y), @@ -721,7 +717,7 @@ quickcheck! { assert_eq!(expected_first, curr_perm); - while let Some(next_perm) = perms.next() { + for next_perm in perms { assert!( next_perm > curr_perm, "next perm isn't greater-than current; next_perm={:?} curr_perm={:?} n={}", @@ -943,8 +939,7 @@ quickcheck! { fn fuzz_group_by_lazy_1(it: Iter) -> bool { let jt = it.clone(); let groups = it.group_by(|k| *k); - let res = itertools::equal(jt, groups.into_iter().flat_map(|(_, x)| x)); - res + itertools::equal(jt, groups.into_iter().flat_map(|(_, x)| x)) } } @@ -1286,7 +1281,7 @@ quickcheck! { .map(|i| (i % modulo, i)) .into_group_map() .into_iter() - .map(|(key, vals)| (key, vals.into_iter().fold(0u64, |acc, val| acc + val))) + .map(|(key, vals)| (key, vals.into_iter().sum())) .collect::>(); assert_eq!(lookup, group_map_lookup); @@ -1551,10 +1546,10 @@ quickcheck! { } quickcheck! { - #[test] fn counts(nums: Vec) -> TestResult { let counts = nums.iter().counts(); for (&item, &count) in counts.iter() { + #[allow(clippy::absurd_extreme_comparisons)] if count <= 0 { return TestResult::failed(); } @@ -1602,7 +1597,7 @@ quickcheck! { fn is_fused(mut it: I) -> bool { - while let Some(_) = it.next() {} + for _ in it.by_ref() {} for _ in 0..10{ if it.next().is_some(){ return false; @@ -1693,3 +1688,62 @@ quickcheck! { } } +quickcheck! { + fn min_set_contains_min(a: Vec<(usize, char)>) -> bool { + let result_set = a.iter().min_set(); + if let Some(result_element) = a.iter().min() { + result_set.contains(&result_element) + } else { + result_set.is_empty() + } + } + + fn min_set_by_contains_min(a: Vec<(usize, char)>) -> bool { + let compare = |x: &&(usize, char), y: &&(usize, char)| x.1.cmp(&y.1); + let result_set = a.iter().min_set_by(compare); + if let Some(result_element) = a.iter().min_by(compare) { + result_set.contains(&result_element) + } else { + result_set.is_empty() + } + } + + fn min_set_by_key_contains_min(a: Vec<(usize, char)>) -> bool { + let key = |x: &&(usize, char)| x.1; + let result_set = a.iter().min_set_by_key(&key); + if let Some(result_element) = a.iter().min_by_key(&key) { + result_set.contains(&result_element) + } else { + result_set.is_empty() + } + } + + fn max_set_contains_max(a: Vec<(usize, char)>) -> bool { + let result_set = a.iter().max_set(); + if let Some(result_element) = a.iter().max() { + result_set.contains(&result_element) + } else { + result_set.is_empty() + } + } + + fn max_set_by_contains_max(a: Vec<(usize, char)>) -> bool { + let compare = |x: &&(usize, char), y: &&(usize, char)| x.1.cmp(&y.1); + let result_set = a.iter().max_set_by(compare); + if let Some(result_element) = a.iter().max_by(compare) { + result_set.contains(&result_element) + } else { + result_set.is_empty() + } + } + + fn max_set_by_key_contains_max(a: Vec<(usize, char)>) -> bool { + let key = |x: &&(usize, char)| x.1; + let result_set = a.iter().max_set_by_key(&key); + if let Some(result_element) = a.iter().max_by_key(&key) { + result_set.contains(&result_element) + } else { + result_set.is_empty() + } + } +} diff --git a/vendor/itertools/tests/specializations.rs b/vendor/itertools/tests/specializations.rs index 199cf562a..057e11c9f 100644 --- a/vendor/itertools/tests/specializations.rs +++ b/vendor/itertools/tests/specializations.rs @@ -129,7 +129,7 @@ quickcheck! { check_results_specialized!(it, |i| { let mut parameters_from_fold = vec![]; let fold_result = i.fold(vec![], |mut acc, v| { - parameters_from_fold.push((acc.clone(), v.clone())); + parameters_from_fold.push((acc.clone(), v)); acc.push(v); acc }); @@ -139,7 +139,7 @@ quickcheck! { let mut parameters_from_all = vec![]; let first = i.next(); let all_result = i.all(|x| { - parameters_from_all.push(x.clone()); + parameters_from_all.push(x); Some(x)==first }); (parameters_from_all, all_result) diff --git a/vendor/itertools/tests/test_core.rs b/vendor/itertools/tests/test_core.rs index a7b7449d3..df94eb665 100644 --- a/vendor/itertools/tests/test_core.rs +++ b/vendor/itertools/tests/test_core.rs @@ -116,7 +116,7 @@ fn chain2() { fn write_to() { let xs = [7, 9, 8]; let mut ys = [0; 5]; - let cnt = ys.iter_mut().set_from(xs.iter().map(|x| *x)); + let cnt = ys.iter_mut().set_from(xs.iter().copied()); assert!(cnt == xs.len()); assert!(ys == [7, 9, 8, 0, 0]); @@ -180,15 +180,10 @@ fn batching() { let ys = [(0, 1), (2, 1)]; // An iterator that gathers elements up in pairs - let pit = xs.iter().cloned().batching(|it| { - match it.next() { - None => None, - Some(x) => match it.next() { - None => None, - Some(y) => Some((x, y)), - } - } - }); + let pit = xs + .iter() + .cloned() + .batching(|it| it.next().and_then(|x| it.next().map(|y| (x, y)))); it::assert_equal(pit, ys.iter().cloned()); } diff --git a/vendor/itertools/tests/test_std.rs b/vendor/itertools/tests/test_std.rs index 2049d1597..f59034234 100644 --- a/vendor/itertools/tests/test_std.rs +++ b/vendor/itertools/tests/test_std.rs @@ -1,5 +1,3 @@ -use paste; -use permutohedron; use quickcheck as qc; use rand::{distributions::{Distribution, Standard}, Rng, SeedableRng, rngs::StdRng}; use rand::{seq::SliceRandom, thread_rng}; @@ -123,12 +121,12 @@ fn unique() { #[test] fn intersperse() { let xs = ["a", "", "b", "c"]; - let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect(); + let v: Vec<&str> = xs.iter().cloned().intersperse(", ").collect(); let text: String = v.concat(); assert_eq!(text, "a, , b, c".to_string()); let ys = [0, 1, 2, 3]; - let mut it = ys[..0].iter().map(|x| *x).intersperse(1); + let mut it = ys[..0].iter().copied().intersperse(1); assert!(it.next() == None); } @@ -474,7 +472,7 @@ impl qc::Arbitrary for Ran // Check that taking the k smallest is the same as // sorting then taking the k first elements -fn k_smallest_sort(i: I, k: u16) -> () +fn k_smallest_sort(i: I, k: u16) where I: Iterator + Clone, I::Item: Ord + Debug, @@ -538,10 +536,10 @@ fn sorted_by_cached_key() { fn test_multipeek() { let nums = vec![1u8,2,3,4,5]; - let mp = multipeek(nums.iter().map(|&x| x)); + let mp = multipeek(nums.iter().copied()); assert_eq!(nums, mp.collect::>()); - let mut mp = multipeek(nums.iter().map(|&x| x)); + let mut mp = multipeek(nums.iter().copied()); assert_eq!(mp.peek(), Some(&1)); assert_eq!(mp.next(), Some(1)); assert_eq!(mp.peek(), Some(&2)); @@ -579,7 +577,7 @@ fn test_multipeek_peeking_next() { use crate::it::PeekingNext; let nums = vec![1u8,2,3,4,5,6,7]; - let mut mp = multipeek(nums.iter().map(|&x| x)); + let mut mp = multipeek(nums.iter().copied()); assert_eq!(mp.peeking_next(|&x| x != 0), Some(1)); assert_eq!(mp.next(), Some(2)); assert_eq!(mp.peek(), Some(&3)); @@ -604,10 +602,10 @@ fn test_multipeek_peeking_next() { fn test_peek_nth() { let nums = vec![1u8,2,3,4,5]; - let iter = peek_nth(nums.iter().map(|&x| x)); + let iter = peek_nth(nums.iter().copied()); assert_eq!(nums, iter.collect::>()); - let mut iter = peek_nth(nums.iter().map(|&x| x)); + let mut iter = peek_nth(nums.iter().copied()); assert_eq!(iter.peek_nth(0), Some(&1)); assert_eq!(iter.peek_nth(0), Some(&1)); @@ -638,7 +636,7 @@ fn test_peek_nth() { fn test_peek_nth_peeking_next() { use it::PeekingNext; let nums = vec![1u8,2,3,4,5,6,7]; - let mut iter = peek_nth(nums.iter().map(|&x| x)); + let mut iter = peek_nth(nums.iter().copied()); assert_eq!(iter.peeking_next(|&x| x != 0), Some(1)); assert_eq!(iter.next(), Some(2)); @@ -694,7 +692,7 @@ fn group_by() { } } - let toupper = |ch: &char| ch.to_uppercase().nth(0).unwrap(); + let toupper = |ch: &char| ch.to_uppercase().next().unwrap(); // try all possible orderings for indices in permutohedron::Heap::new(&mut [0, 1, 2, 3]) { @@ -992,6 +990,54 @@ fn diff_shorter() { }); } +#[test] +fn extrema_set() { + use std::cmp::Ordering; + + // A peculiar type: Equality compares both tuple items, but ordering only the + // first item. Used to distinguish equal elements. + #[derive(Clone, Debug, PartialEq, Eq)] + struct Val(u32, u32); + + impl PartialOrd for Val { + fn partial_cmp(&self, other: &Val) -> Option { + self.0.partial_cmp(&other.0) + } + } + + impl Ord for Val { + fn cmp(&self, other: &Val) -> Ordering { + self.0.cmp(&other.0) + } + } + + assert_eq!(None::.iter().min_set(), Vec::<&u32>::new()); + assert_eq!(None::.iter().max_set(), Vec::<&u32>::new()); + + assert_eq!(Some(1u32).iter().min_set(), vec![&1]); + assert_eq!(Some(1u32).iter().max_set(), vec![&1]); + + let data = vec![Val(0, 1), Val(2, 0), Val(0, 2), Val(1, 0), Val(2, 1)]; + + let min_set = data.iter().min_set(); + assert_eq!(min_set, vec![&Val(0, 1), &Val(0, 2)]); + + let min_set_by_key = data.iter().min_set_by_key(|v| v.1); + assert_eq!(min_set_by_key, vec![&Val(2, 0), &Val(1, 0)]); + + let min_set_by = data.iter().min_set_by(|x, y| x.1.cmp(&y.1)); + assert_eq!(min_set_by, vec![&Val(2, 0), &Val(1, 0)]); + + let max_set = data.iter().max_set(); + assert_eq!(max_set, vec![&Val(2, 0), &Val(2, 1)]); + + let max_set_by_key = data.iter().max_set_by_key(|v| v.1); + assert_eq!(max_set_by_key, vec![&Val(0, 2)]); + + let max_set_by = data.iter().max_set_by(|x, y| x.1.cmp(&y.1)); + assert_eq!(max_set_by, vec![&Val(0, 2)]); +} + #[test] fn minmax() { use std::cmp::Ordering; @@ -1043,9 +1089,9 @@ fn format() { let t2 = format!("{:?}", data.iter().format("--")); assert_eq!(t2, ans2); - let dataf = [1.1, 2.71828, -22.]; + let dataf = [1.1, 5.71828, -22.]; let t3 = format!("{:.2e}", dataf.iter().format(", ")); - assert_eq!(t3, "1.10e0, 2.72e0, -2.20e1"); + assert_eq!(t3, "1.10e0, 5.72e0, -2.20e1"); } #[test] @@ -1062,7 +1108,7 @@ fn fold_while() { let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let sum = vec.into_iter().fold_while(0, |acc, item| { iterations += 1; - let new_sum = acc.clone() + item; + let new_sum = acc + item; if new_sum <= 20 { FoldWhile::Continue(new_sum) } else { @@ -1095,7 +1141,7 @@ fn tree_fold1() { "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 15 x x x x", ]; for (i, &s) in x.iter().enumerate() { - let expected = if s == "" { None } else { Some(s.to_string()) }; + let expected = if s.is_empty() { None } else { Some(s.to_string()) }; let num_strings = (0..i).map(|x| x.to_string()); let actual = num_strings.tree_fold1(|a, b| format!("{} {} x", a, b)); assert_eq!(actual, expected); @@ -1119,4 +1165,4 @@ fn multiunzip() { let (): () = [(), (), ()].iter().cloned().multiunzip(); let t: (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)].iter().cloned().multiunzip(); assert_eq!(t, (vec![0], vec![1], vec![2], vec![3], vec![4], vec![5], vec![6], vec![7], vec![8], vec![9], vec![10], vec![11])); -} \ No newline at end of file +} diff --git a/vendor/itertools/tests/zip.rs b/vendor/itertools/tests/zip.rs index 5801b4232..75157d34f 100644 --- a/vendor/itertools/tests/zip.rs +++ b/vendor/itertools/tests/zip.rs @@ -29,8 +29,8 @@ fn test_zip_longest_size_hint() { fn test_double_ended_zip_longest() { let xs = [1, 2, 3, 4, 5, 6]; let ys = [1, 2, 3, 7]; - let a = xs.iter().map(|&x| x); - let b = ys.iter().map(|&x| x); + let a = xs.iter().copied(); + let b = ys.iter().copied(); let mut it = a.zip_longest(b); assert_eq!(it.next(), Some(Both(1, 1))); assert_eq!(it.next(), Some(Both(2, 2))); @@ -45,8 +45,8 @@ fn test_double_ended_zip_longest() { fn test_double_ended_zip() { let xs = [1, 2, 3, 4, 5, 6]; let ys = [1, 2, 3, 7]; - let a = xs.iter().map(|&x| x); - let b = ys.iter().map(|&x| x); + let a = xs.iter().copied(); + let b = ys.iter().copied(); let mut it = multizip((a, b)); assert_eq!(it.next_back(), Some((4, 7))); assert_eq!(it.next_back(), Some((3, 3))); diff --git a/vendor/itoa/.cargo-checksum.json b/vendor/itoa/.cargo-checksum.json index 4af98bbb4..5c464a6c5 100644 --- a/vendor/itoa/.cargo-checksum.json +++ b/vendor/itoa/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"2e653183f335114876acd61d9e4eeb893b202e6842d4f128bbae40c121439432","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4bc11375d5c1c2c7cf4988b94d44c0f1fe8cdf2d68755fef127cd5ba0d70b939","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"55c938bd2421bf2adc505504ecfe44dd8f537f234b3f3555bbaf6df87d35b54b","src/udiv128.rs":"16394f767854452756372d74f8025f7329fd8b61a676d81edf489681a6332ee9","tests/test.rs":"f7404fc5f7cd1bdaf74a3b64a70d5b30586241ddc1ce2c82bd1b564999fcce0e"},"package":"6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"} \ No newline at end of file +{"files":{"Cargo.toml":"895c75445c305a4d56486a2ca7312a85a486469492286e277f41601be418bcd4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4bc11375d5c1c2c7cf4988b94d44c0f1fe8cdf2d68755fef127cd5ba0d70b939","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"9438cd2cfcf95e4a6719816580e209c3873beb75074ca756118f8723d336141b","src/udiv128.rs":"d28c1872c37ee2185931babcb20a221b8706a5aa8abc4963419763888023ff17","tests/test.rs":"f7404fc5f7cd1bdaf74a3b64a70d5b30586241ddc1ce2c82bd1b564999fcce0e"},"package":"4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"} \ No newline at end of file diff --git a/vendor/itoa/Cargo.toml b/vendor/itoa/Cargo.toml index c3a1bd601..bab03ecf7 100644 --- a/vendor/itoa/Cargo.toml +++ b/vendor/itoa/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.36" name = "itoa" -version = "1.0.3" +version = "1.0.4" authors = ["David Tolnay "] exclude = [ "performance.png", @@ -32,3 +32,7 @@ repository = "https://github.com/dtolnay/itoa" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies.no-panic] +version = "0.1" +optional = true diff --git a/vendor/itoa/src/lib.rs b/vendor/itoa/src/lib.rs index 002156cb8..7c3616e51 100644 --- a/vendor/itoa/src/lib.rs +++ b/vendor/itoa/src/lib.rs @@ -30,7 +30,7 @@ //! //! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png) -#![doc(html_root_url = "https://docs.rs/itoa/1.0.3")] +#![doc(html_root_url = "https://docs.rs/itoa/1.0.4")] #![no_std] #![allow( clippy::cast_lossless, @@ -43,6 +43,8 @@ mod udiv128; use core::mem::{self, MaybeUninit}; use core::{ptr, slice, str}; +#[cfg(feature = "no-panic")] +use no_panic::no_panic; /// A correctly sized stack allocation for the formatted integer to be written /// into. @@ -76,6 +78,7 @@ impl Buffer { /// This is a cheap operation; you don't need to worry about reusing buffers /// for efficiency. #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] pub fn new() -> Buffer { let bytes = [MaybeUninit::::uninit(); I128_MAX_LEN]; Buffer { bytes } @@ -83,6 +86,7 @@ impl Buffer { /// Print an integer into this buffer and return a reference to its string /// representation within the buffer. + #[cfg_attr(feature = "no-panic", no_panic)] pub fn format(&mut self, i: I) -> &str { i.write(unsafe { &mut *(&mut self.bytes as *mut [MaybeUninit; I128_MAX_LEN] @@ -122,6 +126,7 @@ macro_rules! impl_Integer { #[allow(unused_comparisons)] #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] fn write(self, buf: &mut [MaybeUninit; $max_len]) -> &str { let is_nonnegative = self >= 0; let mut n = if is_nonnegative { @@ -223,6 +228,7 @@ macro_rules! impl_Integer128 { #[allow(unused_comparisons)] #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] fn write(self, buf: &mut [MaybeUninit; $max_len]) -> &str { let is_nonnegative = self >= 0; let n = if is_nonnegative { diff --git a/vendor/itoa/src/udiv128.rs b/vendor/itoa/src/udiv128.rs index df53eb526..0587047a7 100644 --- a/vendor/itoa/src/udiv128.rs +++ b/vendor/itoa/src/udiv128.rs @@ -1,5 +1,9 @@ +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + /// Multiply unsigned 128 bit integers, return upper 128 bits of the result #[inline] +#[cfg_attr(feature = "no-panic", no_panic)] fn u128_mulhi(x: u128, y: u128) -> u128 { let x_lo = x as u64; let x_hi = (x >> 64) as u64; @@ -26,6 +30,7 @@ fn u128_mulhi(x: u128, y: u128) -> u128 { /// Implementation, 1994, pp. 61–72 /// #[inline] +#[cfg_attr(feature = "no-panic", no_panic)] pub fn udivmod_1e19(n: u128) -> (u128, u64) { let d = 10_000_000_000_000_000_000_u64; // 10^19 diff --git a/vendor/libc/.cargo-checksum.json b/vendor/libc/.cargo-checksum.json index f16c56427..631af7226 100644 --- a/vendor/libc/.cargo-checksum.json +++ b/vendor/libc/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"1549dc2db0ecd74316f52b2d14b15144ae970a848bf3d54c048844ed7a35df2a","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"94cbaad15021e287a1b9546a697b04c1e560f1204b52204ffaaea5975c5d03b9","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"ce753ef318b300bbd441feabdd77d00322dfb6ce9eee8c78a38afe02b57aa4c0","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"56dc7604509f49b274770cade97a1874c8955c3b0a445fb857707ae0ca6df41b","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"d0e8246063cae113806524a63a47c6c0628cc54a3ef03e938e89964f8b4f08b4","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"ec229cc7af2511cb510c078e87e90ee2625090bfe94f40eb35f73d79143533aa","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"1e35b4773384ea143810cdce4b96f47108b37446430da30c96a0d1651656d73d","src/unix/bsd/mod.rs":"817ca5719c36a74c84e52c6a56a5998b60d7f02351a405e034f08ebab079b63a","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"8f9613e50c2771b33d7cf817a735d536b389ec57f861b9486d870373c768276e","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"228505fa48292e74b06acbed96196801595a4b822da2126a6d6c7fa773cff8bc","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"df7b6b7d8dd3441665bfe87f2abc942bddc65b8b10dfa9c83dd0422f68107891","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"80e9f93fed838a48b4e2e8d77b95c72cfd7c0647bcce63851555c5ad16dad143","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"962741303dc24a5b9653f2e9b0b4ad9eb42fc54daa0a70ca70a7ce175e75094b","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"c69c90606d4362f8de89b8816df0ded724ed64b53bf55d15681fde171b7bb361","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c72a08011c32f82919e930e0d89044d8feb65fd41bf80647436756c290344eb8","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"f0db9914315d5a3d51bf5ec04a0ae6584f2e1688b9258ce132b617e67d9bd7a9","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"fd62b48974dd2f97f6e8fa2a30624e8d69fdedc5d3b0ab2f3f09516e88a8769a","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"af94b1a6d844bed87bb4c93de0a12f160ca1f918f5234d7fe17511d4e424dedc","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"1fa4974fe412b22c3555d3e240dbf00cc04a5287c751035ddf08a0470d4a7c9a","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"c7ebabc4e1bdbbd97e5065faa3a57f41f473570920582d979f9e9d4f77448546","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"c3365480375bc258ffe267e7a299d7b3bb542a908bef8881f503ddc25ba8fc1f","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"09fa012e027bfcdaabee221c1b676804a9c7e0e04a4b64fdd98a50c9b5c2f674","src/unix/mod.rs":"fbd5520d160a32a127608cd408905febe387773bbf05bfe199ef385fb5562e9c","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"816f235f4aa4baabba7f2606b31d0fdb03988c52194c966728de8690bf17299d","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"8914a68865af026c1f4fb1d5f02ba0053362ef34b813ad60cc4aa3a88aa4999e","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"090dd8fcd951d18f1905bca96188783c2e3f1433484926ecdcda144237ecec0f","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"} \ No newline at end of file +{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"04fa9ce26b0efcfe3dd51e3f1bbb81bb36f5d61982a11947283c7616d390549e","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"cf7e0df0e655337d1c0852880817b6b514ef9599e2125232fc79cdf8eddd01ba","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"ce753ef318b300bbd441feabdd77d00322dfb6ce9eee8c78a38afe02b57aa4c0","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"bb61eec399428faee753b3df509410c51ed2ac51406d40559fcec290bb50e293","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"e4f33050d52d3e5c932da8d10e1f377e1ff609fb178ea986bfc458d31e37dc19","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"23f189f188651762b38f40b4e9aba785625f6f9a52558a4a490510c3b1d08b53","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"57fee9dd251ac615ec7d32d293e0f0b6fa3bf28efbddd6d569765765aafb8b9b","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"7df84dd6dee8b73fd4d72dd1638584d788e2a1a85f95746f7c5b330b8dc23655","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"236ef119410d566ef94064bf13d734635eaeecb3635a5d21e8e9f91e7e3152ac","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"6a8eb9a1e35eec893de9c76a5be3ce29e4c3ca26db45fbcfa925bdd757f6352d","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"a61d41f6fe01c06c6de5db2ed970522601eada133e6bac4ed2d1dfaceb576db2","src/unix/bsd/mod.rs":"817ca5719c36a74c84e52c6a56a5998b60d7f02351a405e034f08ebab079b63a","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"fa260decf53280d4fdf714af60f42d4774f8d6f2da71b0a55a6c2a85e422eb57","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"079b11c99c6ca3cc5942c0e6d854541f8765c5058c2f024b84656697840e198b","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"df7b6b7d8dd3441665bfe87f2abc942bddc65b8b10dfa9c83dd0422f68107891","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"80e9f93fed838a48b4e2e8d77b95c72cfd7c0647bcce63851555c5ad16dad143","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"41b9d0f405cd474385acce06df0649f4eeaab3fe8fb4655f97806fa40bdf84d8","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"6ef4652dfb94e3c58aed5133ece982ad30569d46b6b1054552cd61905fa61690","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e2b46404e44f7d63c26af9dbd79b4e166ef7bced2bc9c6746a26ca86e508e0d4","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"5bd3f6b3484e049ddaac95f411b0d82cbf1cd28e6a5defbc927bd917f5f7d299","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"6b9a5dac6f937ddc1453e808e3c43502c87143332df9e43ac64fb8b1eda6c116","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"5c5d90326b54b57b98eff4745fe7a3fb02f053b2dc782241a73e807b491936a3","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"5e7c1e29aeb82fc422f45b73fb0cf3d13d0902300f9150d2755a9074f8d96999","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"80894eece66e9348f45d1b07ad37c757ea694bbd10ed49d3f920b34e9f51a9a3","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"c703cc5e9de2dc31d9e5831bfb6f354d6e3518b2ae02263f68a9a70f1c0167e2","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c91813ee5e1bc817996c46be86d1f46802e73df2952cab576ea015490929afc5","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"80b4b97a41564290c510e68a1fb20cfd8424206f010e71a596f12877de886a71","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"a595e37c2325ceb40ef66c634bd3c255ad184a1d70ff8025e98a075f0ec67704","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"ef4b13477ffd8532fb6705ca3fa63a1f13e8d19ee39b083c5355dfce430c1a5b","src/unix/linux_like/linux/gnu/b64/s390x.rs":"788fde4fa1919859cc028b59da31de00449edd2b2c1530ae76134beac418b73c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"c4fa0ede3f78b21a9982667922cccd0681bee3cb6d42208ea9958f65e93d6308","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"e37e0421290b152fe508883181c41225e09dd5452a6b085e8d807b3b54823028","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"c1b6345ce14f67d1b2e2f7f2c0ff9a074c07acbd348df69cb4558bda8c8fb9ae","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"3f4d2aeadb7d2620cad09564abdbfc5cf02eeb5a27f2bab8a4e9b4bdbdb258a5","src/unix/linux_like/linux/gnu/mod.rs":"06abaca7fc85e805650ec807c4d06c888ff99e146e1ba2685f20840a86e35a2f","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"1d84f37fdfa4dfab1b758345af75e02485e2a18746830413c2afe5069a1e39ce","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"f5b217a93f99c2852f7fd1459f529798372fa7df84ee0cfd3d8cdd5b2021b8cf","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"16a7a03d998a5db11be9ee81525c7faec4623383260e8bc125b1c53a050fde75","src/unix/linux_like/linux/musl/b32/mod.rs":"580e27c5ce3344df686f1ffc08fdfa2c282d1ceb623d778c50d210d4bd65ec7e","src/unix/linux_like/linux/musl/b32/powerpc.rs":"dc52adc264c34bce80753d6bd064e8fc4b8237fa1e5c5315ccb6c72df74c2813","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"e57dc5562553aab6d0765e0ec266254aa52975f8757bfe97e0c6028fa7d5d37c","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"7a1586f77bb693f0b319ec720c35963da056287fc42f8e2ccf1d5b2bcccf4fd6","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"31e75179cbb4e26425b3f5b052e358f593153da662884655e60801d852e55dc2","src/unix/linux_like/linux/musl/b64/mips64.rs":"9a5d29f666332bb056d0e2951e9de989aa1dc016075f009db3f2f628e0cdda8c","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"455dc0ffa55afc1db6ffaf461f6f2a7b49d31658bfebe0bb4efac5967a6f956c","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"42d4b6d36807f37759094a732a321080cccdf498b174d632cebba147051de294","src/unix/linux_like/linux/musl/b64/s390x.rs":"d8a4fdfea0960ec284cae4facb8b0fb342e8aa41544cffacdcaf08c5a92a43f8","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"7a877cd23b64be66d28e6b8dddae32d59a88d69115637539daf19381f4e39330","src/unix/linux_like/linux/musl/mod.rs":"0514b337aaa6e62be9e01e00702ef996c60319b7050ece155530147c20de9995","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"7d8dfbd26ce958d9da17468b3c9d0b119ce7dbd59b3384551cd4423ce25db44a","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"420dbea99e99091f333641e202960fa4bed0733de2a834e610708555be6bab4c","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"3d03bd583aaf04f285f95ff8b53c9b5a891d3b64bfcda37a42648ec51c4c51e5","src/unix/mod.rs":"fbd5520d160a32a127608cd408905febe387773bbf05bfe199ef385fb5562e9c","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"816f235f4aa4baabba7f2606b31d0fdb03988c52194c966728de8690bf17299d","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"494e56628d4408bf66ad30ff71fbd21bc33d9037935c411dff7bf73dd3f1070b","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"1369fb55325914654ba3ad02410b75a40c8c0008feed9704c28520be1ee49641","src/unix/solarish/mod.rs":"52a31038984e68582347f4b28fd64c01e6308ff4293628818bb279605e7b28c6","src/unix/solarish/solaris.rs":"36abcfb46fab6e7151a0c1f555b419e1267b82893f6e84d5d260308ba8eeb0c5","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"ec2b01f194eb8a6a27133c57681da195a949e03098f3ea1e847227a9c09ef5fc","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"090dd8fcd951d18f1905bca96188783c2e3f1433484926ecdcda144237ecec0f","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"} \ No newline at end of file diff --git a/vendor/libc/Cargo.toml b/vendor/libc/Cargo.toml index 5b54eced6..cb7c0047e 100644 --- a/vendor/libc/Cargo.toml +++ b/vendor/libc/Cargo.toml @@ -11,7 +11,7 @@ [package] name = "libc" -version = "0.2.132" +version = "0.2.135" authors = ["The Rust Project Developers"] build = "build.rs" exclude = [ diff --git a/vendor/libc/src/fuchsia/mod.rs b/vendor/libc/src/fuchsia/mod.rs index 4a18a8daa..eee82d0d8 100644 --- a/vendor/libc/src/fuchsia/mod.rs +++ b/vendor/libc/src/fuchsia/mod.rs @@ -3235,17 +3235,6 @@ f! { minor as ::c_uint } - pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { - let major = major as ::dev_t; - let minor = minor as ::dev_t; - let mut dev = 0; - dev |= (major & 0x00000fff) << 8; - dev |= (major & 0xfffff000) << 32; - dev |= (minor & 0x000000ff) << 0; - dev |= (minor & 0xffffff00) << 12; - dev - } - pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { cmsg.offset(1) as *mut c_uchar } @@ -3322,6 +3311,17 @@ safe_f! { pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { (cmd << 8) | (type_ & 0x00ff) } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0x00000fff) << 8; + dev |= (major & 0xfffff000) << 32; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } } fn __CMSG_LEN(cmsg: *const cmsghdr) -> ::ssize_t { @@ -4212,6 +4212,11 @@ extern "C" { child: ::Option, ) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn getgrouplist( user: *const ::c_char, group: ::gid_t, diff --git a/vendor/libc/src/unix/bsd/apple/mod.rs b/vendor/libc/src/unix/bsd/apple/mod.rs index a831ca850..ed3028695 100644 --- a/vendor/libc/src/unix/bsd/apple/mod.rs +++ b/vendor/libc/src/unix/bsd/apple/mod.rs @@ -119,6 +119,15 @@ pub type thread_throughput_qos_policy_t = *mut thread_throughput_qos_policy; pub type pthread_introspection_hook_t = extern "C" fn(event: ::c_uint, thread: ::pthread_t, addr: *mut ::c_void, size: ::size_t); +pub type pthread_jit_write_callback_t = ::Option ::c_int>; + +pub type os_unfair_lock = os_unfair_lock_s; +pub type os_unfair_lock_t = *mut os_unfair_lock; + +pub type os_log_t = *mut ::c_void; +pub type os_log_type_t = u8; +pub type os_signpost_id_t = u64; +pub type os_signpost_type_t = u8; pub type vm_statistics_t = *mut vm_statistics; pub type vm_statistics_data_t = vm_statistics; @@ -137,6 +146,9 @@ pub type CCRNGStatus = ::CCCryptorStatus; pub type copyfile_state_t = *mut ::c_void; pub type copyfile_flags_t = u32; +pub type attrgroup_t = u32; +pub type vol_capabilities_set_t = [u32; 4]; + deprecated_mach! { pub type mach_timebase_info_data_t = mach_timebase_info; } @@ -981,6 +993,39 @@ s! { pub uuid: ::uuid_t, pub offset: u32, } + + pub struct attrlist { + pub bitmapcount: ::c_ushort, + pub reserved: u16, + pub commonattr: attrgroup_t, + pub volattr: attrgroup_t, + pub dirattr: attrgroup_t, + pub fileattr: attrgroup_t, + pub forkattr: attrgroup_t, + } + + pub struct attrreference_t { + pub attr_dataoffset: i32, + pub attr_length: u32, + } + + pub struct vol_capabilities_attr_t { + pub capabilities: vol_capabilities_set_t, + pub valid: vol_capabilities_set_t, + } + + pub struct attribute_set_t { + pub commonattr: attrgroup_t, + pub volattr: attrgroup_t, + pub dirattr: attrgroup_t, + pub fileattr: attrgroup_t, + pub forkattr: attrgroup_t, + } + + pub struct vol_attributes_attr_t { + pub validattr: attribute_set_t, + pub nativeattr: attribute_set_t, + } } s_no_extra_traits! { @@ -1258,6 +1303,10 @@ s_no_extra_traits! { pub l2p_contigbytes: ::off_t, pub l2p_devoffset: ::off_t, } + + pub struct os_unfair_lock_s { + _os_unfair_lock_opaque: u32, + } } impl siginfo_t { @@ -2539,6 +2588,27 @@ cfg_if! { l2p_devoffset.hash(state); } } + impl PartialEq for os_unfair_lock { + fn eq(&self, other: &os_unfair_lock) -> bool { + self._os_unfair_lock_opaque == other._os_unfair_lock_opaque + } + } + + impl Eq for os_unfair_lock {} + + impl ::fmt::Debug for os_unfair_lock { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("os_unfair_lock") + .field("_os_unfair_lock_opaque", &self._os_unfair_lock_opaque) + .finish() + } + } + + impl ::hash::Hash for os_unfair_lock { + fn hash(&self, state: &mut H) { + self._os_unfair_lock_opaque.hash(state); + } + } } } @@ -2654,6 +2724,8 @@ pub const EOF: ::c_int = -1; pub const SEEK_SET: ::c_int = 0; pub const SEEK_CUR: ::c_int = 1; pub const SEEK_END: ::c_int = 2; +pub const SEEK_HOLE: ::c_int = 3; +pub const SEEK_DATA: ::c_int = 4; pub const _IOFBF: ::c_int = 0; pub const _IONBF: ::c_int = 2; pub const _IOLBF: ::c_int = 1; @@ -2671,11 +2743,13 @@ pub const _PC_PIPE_BUF: ::c_int = 6; pub const _PC_CHOWN_RESTRICTED: ::c_int = 7; pub const _PC_NO_TRUNC: ::c_int = 8; pub const _PC_VDISABLE: ::c_int = 9; -pub const O_DSYNC: ::c_int = 0x400000; -pub const O_NOCTTY: ::c_int = 0x20000; -pub const O_CLOEXEC: ::c_int = 0x1000000; -pub const O_DIRECTORY: ::c_int = 0x100000; -pub const O_SYMLINK: ::c_int = 0x200000; +pub const O_EVTONLY: ::c_int = 0x00008000; +pub const O_NOCTTY: ::c_int = 0x00020000; +pub const O_DIRECTORY: ::c_int = 0x00100000; +pub const O_SYMLINK: ::c_int = 0x00200000; +pub const O_DSYNC: ::c_int = 0x00400000; +pub const O_CLOEXEC: ::c_int = 0x01000000; +pub const O_NOFOLLOW_ANY: ::c_int = 0x20000000; pub const S_IFIFO: mode_t = 4096; pub const S_IFCHR: mode_t = 8192; pub const S_IFBLK: mode_t = 24576; @@ -3796,6 +3870,11 @@ pub const _SC_TRACE_NAME_MAX: ::c_int = 128; pub const _SC_TRACE_SYS_MAX: ::c_int = 129; pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 130; pub const _SC_PASS_MAX: ::c_int = 131; +// `confstr` keys (only the values guaranteed by `man confstr`). +pub const _CS_PATH: ::c_int = 1; +pub const _CS_DARWIN_USER_DIR: ::c_int = 65536; +pub const _CS_DARWIN_USER_TEMP_DIR: ::c_int = 65537; +pub const _CS_DARWIN_USER_CACHE_DIR: ::c_int = 65538; pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; @@ -3817,6 +3896,20 @@ pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { __opaque: [0; __PTHREAD_RWLOCK_SIZE__], }; +pub const OS_UNFAIR_LOCK_INIT: os_unfair_lock = os_unfair_lock { + _os_unfair_lock_opaque: 0, +}; + +pub const OS_LOG_TYPE_DEFAULT: ::os_log_type_t = 0x00; +pub const OS_LOG_TYPE_INFO: ::os_log_type_t = 0x01; +pub const OS_LOG_TYPE_DEBUG: ::os_log_type_t = 0x02; +pub const OS_LOG_TYPE_ERROR: ::os_log_type_t = 0x10; +pub const OS_LOG_TYPE_FAULT: ::os_log_type_t = 0x11; + +pub const OS_SIGNPOST_EVENT: ::os_signpost_type_t = 0x00; +pub const OS_SIGNPOST_INTERVAL_BEGIN: ::os_signpost_type_t = 0x01; +pub const OS_SIGNPOST_INTERVAL_END: ::os_signpost_type_t = 0x02; + pub const MINSIGSTKSZ: ::size_t = 32768; pub const SIGSTKSZ: ::size_t = 131072; @@ -4678,6 +4771,145 @@ pub const COPYFILE_CONTINUE: ::c_int = 0; pub const COPYFILE_SKIP: ::c_int = 1; pub const COPYFILE_QUIT: ::c_int = 2; +// +pub const ATTR_BIT_MAP_COUNT: ::c_ushort = 5; +pub const FSOPT_NOFOLLOW: u32 = 0x1; +pub const FSOPT_NOFOLLOW_ANY: u32 = 0x800; +pub const FSOPT_REPORT_FULLSIZE: u32 = 0x4; +pub const FSOPT_PACK_INVAL_ATTRS: u32 = 0x8; +pub const FSOPT_ATTR_CMN_EXTENDED: u32 = 0x20; +pub const FSOPT_RETURN_REALDEV: u32 = 0x200; +pub const ATTR_CMN_NAME: attrgroup_t = 0x00000001; +pub const ATTR_CMN_DEVID: attrgroup_t = 0x00000002; +pub const ATTR_CMN_FSID: attrgroup_t = 0x00000004; +pub const ATTR_CMN_OBJTYPE: attrgroup_t = 0x00000008; +pub const ATTR_CMN_OBJTAG: attrgroup_t = 0x00000010; +pub const ATTR_CMN_OBJID: attrgroup_t = 0x00000020; +pub const ATTR_CMN_OBJPERMANENTID: attrgroup_t = 0x00000040; +pub const ATTR_CMN_PAROBJID: attrgroup_t = 0x00000080; +pub const ATTR_CMN_SCRIPT: attrgroup_t = 0x00000100; +pub const ATTR_CMN_CRTIME: attrgroup_t = 0x00000200; +pub const ATTR_CMN_MODTIME: attrgroup_t = 0x00000400; +pub const ATTR_CMN_CHGTIME: attrgroup_t = 0x00000800; +pub const ATTR_CMN_ACCTIME: attrgroup_t = 0x00001000; +pub const ATTR_CMN_BKUPTIME: attrgroup_t = 0x00002000; +pub const ATTR_CMN_FNDRINFO: attrgroup_t = 0x00004000; +pub const ATTR_CMN_OWNERID: attrgroup_t = 0x00008000; +pub const ATTR_CMN_GRPID: attrgroup_t = 0x00010000; +pub const ATTR_CMN_ACCESSMASK: attrgroup_t = 0x00020000; +pub const ATTR_CMN_FLAGS: attrgroup_t = 0x00040000; +pub const ATTR_CMN_GEN_COUNT: attrgroup_t = 0x00080000; +pub const ATTR_CMN_DOCUMENT_ID: attrgroup_t = 0x00100000; +pub const ATTR_CMN_USERACCESS: attrgroup_t = 0x00200000; +pub const ATTR_CMN_EXTENDED_SECURITY: attrgroup_t = 0x00400000; +pub const ATTR_CMN_UUID: attrgroup_t = 0x00800000; +pub const ATTR_CMN_GRPUUID: attrgroup_t = 0x01000000; +pub const ATTR_CMN_FILEID: attrgroup_t = 0x02000000; +pub const ATTR_CMN_PARENTID: attrgroup_t = 0x04000000; +pub const ATTR_CMN_FULLPATH: attrgroup_t = 0x08000000; +pub const ATTR_CMN_ADDEDTIME: attrgroup_t = 0x10000000; +pub const ATTR_CMN_DATA_PROTECT_FLAGS: attrgroup_t = 0x40000000; +pub const ATTR_CMN_RETURNED_ATTRS: attrgroup_t = 0x80000000; +pub const ATTR_VOL_FSTYPE: attrgroup_t = 0x00000001; +pub const ATTR_VOL_SIGNATURE: attrgroup_t = 0x00000002; +pub const ATTR_VOL_SIZE: attrgroup_t = 0x00000004; +pub const ATTR_VOL_SPACEFREE: attrgroup_t = 0x00000008; +pub const ATTR_VOL_SPACEAVAIL: attrgroup_t = 0x00000010; +pub const ATTR_VOL_MINALLOCATION: attrgroup_t = 0x00000020; +pub const ATTR_VOL_ALLOCATIONCLUMP: attrgroup_t = 0x00000040; +pub const ATTR_VOL_IOBLOCKSIZE: attrgroup_t = 0x00000080; +pub const ATTR_VOL_OBJCOUNT: attrgroup_t = 0x00000100; +pub const ATTR_VOL_FILECOUNT: attrgroup_t = 0x00000200; +pub const ATTR_VOL_DIRCOUNT: attrgroup_t = 0x00000400; +pub const ATTR_VOL_MAXOBJCOUNT: attrgroup_t = 0x00000800; +pub const ATTR_VOL_MOUNTPOINT: attrgroup_t = 0x00001000; +pub const ATTR_VOL_NAME: attrgroup_t = 0x00002000; +pub const ATTR_VOL_MOUNTFLAGS: attrgroup_t = 0x00004000; +pub const ATTR_VOL_MOUNTEDDEVICE: attrgroup_t = 0x00008000; +pub const ATTR_VOL_ENCODINGSUSED: attrgroup_t = 0x00010000; +pub const ATTR_VOL_CAPABILITIES: attrgroup_t = 0x00020000; +pub const ATTR_VOL_UUID: attrgroup_t = 0x00040000; +pub const ATTR_VOL_SPACEUSED: attrgroup_t = 0x00800000; +pub const ATTR_VOL_QUOTA_SIZE: attrgroup_t = 0x10000000; +pub const ATTR_VOL_RESERVED_SIZE: attrgroup_t = 0x20000000; +pub const ATTR_VOL_ATTRIBUTES: attrgroup_t = 0x40000000; +pub const ATTR_VOL_INFO: attrgroup_t = 0x80000000; +pub const ATTR_DIR_LINKCOUNT: attrgroup_t = 0x00000001; +pub const ATTR_DIR_ENTRYCOUNT: attrgroup_t = 0x00000002; +pub const ATTR_DIR_MOUNTSTATUS: attrgroup_t = 0x00000004; +pub const ATTR_DIR_ALLOCSIZE: attrgroup_t = 0x00000008; +pub const ATTR_DIR_IOBLOCKSIZE: attrgroup_t = 0x00000010; +pub const ATTR_DIR_DATALENGTH: attrgroup_t = 0x00000020; +pub const ATTR_FILE_LINKCOUNT: attrgroup_t = 0x00000001; +pub const ATTR_FILE_TOTALSIZE: attrgroup_t = 0x00000002; +pub const ATTR_FILE_ALLOCSIZE: attrgroup_t = 0x00000004; +pub const ATTR_FILE_IOBLOCKSIZE: attrgroup_t = 0x00000008; +pub const ATTR_FILE_DEVTYPE: attrgroup_t = 0x00000020; +pub const ATTR_FILE_FORKCOUNT: attrgroup_t = 0x00000080; +pub const ATTR_FILE_FORKLIST: attrgroup_t = 0x00000100; +pub const ATTR_FILE_DATALENGTH: attrgroup_t = 0x00000200; +pub const ATTR_FILE_DATAALLOCSIZE: attrgroup_t = 0x00000400; +pub const ATTR_FILE_RSRCLENGTH: attrgroup_t = 0x00001000; +pub const ATTR_FILE_RSRCALLOCSIZE: attrgroup_t = 0x00002000; +pub const ATTR_CMNEXT_RELPATH: attrgroup_t = 0x00000004; +pub const ATTR_CMNEXT_PRIVATESIZE: attrgroup_t = 0x00000008; +pub const ATTR_CMNEXT_LINKID: attrgroup_t = 0x00000010; +pub const ATTR_CMNEXT_NOFIRMLINKPATH: attrgroup_t = 0x00000020; +pub const ATTR_CMNEXT_REALDEVID: attrgroup_t = 0x00000040; +pub const ATTR_CMNEXT_REALFSID: attrgroup_t = 0x00000080; +pub const ATTR_CMNEXT_CLONEID: attrgroup_t = 0x00000100; +pub const ATTR_CMNEXT_EXT_FLAGS: attrgroup_t = 0x00000200; +pub const ATTR_CMNEXT_RECURSIVE_GENCOUNT: attrgroup_t = 0x00000400; +pub const DIR_MNTSTATUS_MNTPOINT: u32 = 0x1; +pub const VOL_CAPABILITIES_FORMAT: usize = 0; +pub const VOL_CAPABILITIES_INTERFACES: usize = 1; +pub const VOL_CAP_FMT_PERSISTENTOBJECTIDS: attrgroup_t = 0x00000001; +pub const VOL_CAP_FMT_SYMBOLICLINKS: attrgroup_t = 0x00000002; +pub const VOL_CAP_FMT_HARDLINKS: attrgroup_t = 0x00000004; +pub const VOL_CAP_FMT_JOURNAL: attrgroup_t = 0x00000008; +pub const VOL_CAP_FMT_JOURNAL_ACTIVE: attrgroup_t = 0x00000010; +pub const VOL_CAP_FMT_NO_ROOT_TIMES: attrgroup_t = 0x00000020; +pub const VOL_CAP_FMT_SPARSE_FILES: attrgroup_t = 0x00000040; +pub const VOL_CAP_FMT_ZERO_RUNS: attrgroup_t = 0x00000080; +pub const VOL_CAP_FMT_CASE_SENSITIVE: attrgroup_t = 0x00000100; +pub const VOL_CAP_FMT_CASE_PRESERVING: attrgroup_t = 0x00000200; +pub const VOL_CAP_FMT_FAST_STATFS: attrgroup_t = 0x00000400; +pub const VOL_CAP_FMT_2TB_FILESIZE: attrgroup_t = 0x00000800; +pub const VOL_CAP_FMT_OPENDENYMODES: attrgroup_t = 0x00001000; +pub const VOL_CAP_FMT_HIDDEN_FILES: attrgroup_t = 0x00002000; +pub const VOL_CAP_FMT_PATH_FROM_ID: attrgroup_t = 0x00004000; +pub const VOL_CAP_FMT_NO_VOLUME_SIZES: attrgroup_t = 0x00008000; +pub const VOL_CAP_FMT_DECMPFS_COMPRESSION: attrgroup_t = 0x00010000; +pub const VOL_CAP_FMT_64BIT_OBJECT_IDS: attrgroup_t = 0x00020000; +pub const VOL_CAP_FMT_DIR_HARDLINKS: attrgroup_t = 0x00040000; +pub const VOL_CAP_FMT_DOCUMENT_ID: attrgroup_t = 0x00080000; +pub const VOL_CAP_FMT_WRITE_GENERATION_COUNT: attrgroup_t = 0x00100000; +pub const VOL_CAP_FMT_NO_IMMUTABLE_FILES: attrgroup_t = 0x00200000; +pub const VOL_CAP_FMT_NO_PERMISSIONS: attrgroup_t = 0x00400000; +pub const VOL_CAP_FMT_SHARED_SPACE: attrgroup_t = 0x00800000; +pub const VOL_CAP_FMT_VOL_GROUPS: attrgroup_t = 0x01000000; +pub const VOL_CAP_FMT_SEALED: attrgroup_t = 0x02000000; +pub const VOL_CAP_INT_SEARCHFS: attrgroup_t = 0x00000001; +pub const VOL_CAP_INT_ATTRLIST: attrgroup_t = 0x00000002; +pub const VOL_CAP_INT_NFSEXPORT: attrgroup_t = 0x00000004; +pub const VOL_CAP_INT_READDIRATTR: attrgroup_t = 0x00000008; +pub const VOL_CAP_INT_EXCHANGEDATA: attrgroup_t = 0x00000010; +pub const VOL_CAP_INT_COPYFILE: attrgroup_t = 0x00000020; +pub const VOL_CAP_INT_ALLOCATE: attrgroup_t = 0x00000040; +pub const VOL_CAP_INT_VOL_RENAME: attrgroup_t = 0x00000080; +pub const VOL_CAP_INT_ADVLOCK: attrgroup_t = 0x00000100; +pub const VOL_CAP_INT_FLOCK: attrgroup_t = 0x00000200; +pub const VOL_CAP_INT_EXTENDED_SECURITY: attrgroup_t = 0x00000400; +pub const VOL_CAP_INT_USERACCESS: attrgroup_t = 0x00000800; +pub const VOL_CAP_INT_MANLOCK: attrgroup_t = 0x00001000; +pub const VOL_CAP_INT_NAMEDSTREAMS: attrgroup_t = 0x00002000; +pub const VOL_CAP_INT_EXTENDED_ATTR: attrgroup_t = 0x00004000; +pub const VOL_CAP_INT_CLONE: attrgroup_t = 0x00010000; +pub const VOL_CAP_INT_SNAPSHOT: attrgroup_t = 0x00020000; +pub const VOL_CAP_INT_RENAME_SWAP: attrgroup_t = 0x00040000; +pub const VOL_CAP_INT_RENAME_EXCL: attrgroup_t = 0x00080000; +pub const VOL_CAP_INT_RENAME_OPENFAIL: attrgroup_t = 0x00100000; + cfg_if! { if #[cfg(libc_const_extern_fn)] { const fn __DARWIN_ALIGN32(p: usize) -> usize { @@ -4791,6 +5023,18 @@ f! { pub {const} fn VM_MAKE_TAG(id: u8) -> u32 { (id as u32) << 24u32 } + + pub fn major(dev: dev_t) -> i32 { + (dev >> 24) & 0xff + } + + pub fn minor(dev: dev_t) -> i32 { + dev & 0xffffff + } + + pub fn makedev(major: i32, minor: i32) -> dev_t { + (major << 24) | minor + } } safe_f! { @@ -4846,6 +5090,11 @@ extern "C" { pub fn fchflags(fd: ::c_int, flags: ::c_uint) -> ::c_int; pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "confstr$UNIX2003" + )] + pub fn confstr(name: ::c_int, buf: *mut ::c_char, len: ::size_t) -> ::size_t; pub fn lio_listio( mode: ::c_int, aiocb_list: *const *mut aiocb, @@ -5006,8 +5255,34 @@ extern "C" { ) -> *mut ::c_void; pub fn pthread_jit_write_protect_np(enabled: ::c_int); pub fn pthread_jit_write_protect_supported_np() -> ::c_int; + // An array of pthread_jit_write_with_callback_np must declare + // the list of callbacks e.g. + // #[link_section = "__DATA_CONST,__pth_jit_func"] + // static callbacks: [libc::pthread_jit_write_callback_t; 2] = [native_jit_write_cb, + // std::mem::transmute::(std::ptr::null())]; + // (a handy PTHREAD_JIT_WRITE_CALLBACK_NP macro for other languages). + pub fn pthread_jit_write_with_callback_np( + callback: ::pthread_jit_write_callback_t, + ctx: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_jit_write_freeze_callbacks_np(); pub fn pthread_cpu_number_np(cpu_number_out: *mut ::size_t) -> ::c_int; + pub fn os_unfair_lock_lock(lock: os_unfair_lock_t); + pub fn os_unfair_lock_trylock(lock: os_unfair_lock_t) -> bool; + pub fn os_unfair_lock_unlock(lock: os_unfair_lock_t); + pub fn os_unfair_lock_assert_owner(lock: os_unfair_lock_t); + pub fn os_unfair_lock_assert_not_owner(lock: os_unfair_lock_t); + + pub fn os_log_create(subsystem: *const ::c_char, category: *const ::c_char) -> ::os_log_t; + pub fn os_log_type_enabled(oslog: ::os_log_t, tpe: ::os_log_type_t) -> bool; + pub fn os_signpost_id_make_with_pointer( + log: ::os_log_t, + ptr: *const ::c_void, + ) -> ::os_signpost_id_t; + pub fn os_signpost_id_generate(log: ::os_log_t) -> ::os_signpost_id_t; + pub fn os_signpost_enabled(log: ::os_log_t) -> bool; + pub fn thread_policy_set( thread: thread_t, flavor: thread_policy_flavor_t, @@ -5536,6 +5811,61 @@ extern "C" { ) -> ::sysdir_search_path_enumeration_state; pub static vm_page_size: vm_size_t; + + pub fn getattrlist( + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn fgetattrlist( + fd: ::c_int, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn getattrlistat( + fd: ::c_int, + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: ::c_ulong, + ) -> ::c_int; + pub fn setattrlist( + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn fsetattrlist( + fd: ::c_int, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn setattrlistat( + dir_fd: ::c_int, + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn getattrlistbulk( + dirfd: ::c_int, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u64, + ) -> ::c_int; + + pub fn malloc_size(ptr: *const ::c_void) -> ::size_t; + pub fn malloc_good_size(size: ::size_t) -> ::size_t; } pub unsafe fn mach_task_self() -> ::mach_port_t { @@ -5567,7 +5897,10 @@ cfg_if! { } } -#[link(name = "iconv")] +// These require a dependency on `libiconv`, and including this when built as +// part of `std` means every Rust program gets it. Ideally we would have a link +// modifier to only include these if they are used, but we do not. +#[cfg_attr(not(feature = "rustc-dep-of-std"), link(name = "iconv"))] extern "C" { pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; pub fn iconv( diff --git a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs index df7719b4b..418ac3dc8 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -1066,6 +1066,8 @@ pub const CPUCTL_MSRSBIT: ::c_int = 0xc0106305; pub const CPUCTL_MSRCBIT: ::c_int = 0xc0106306; pub const CPUCTL_CPUID_COUNT: ::c_int = 0xc0106307; +pub const CPU_SETSIZE: ::size_t = ::mem::size_of::<::cpumask_t>() * 8; + pub const EVFILT_READ: i16 = -1; pub const EVFILT_WRITE: i16 = -2; pub const EVFILT_AIO: i16 = -3; @@ -1571,6 +1573,15 @@ safe_f! { pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { (status & 0o177) != 0o177 && (status & 0o177) != 0 } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= major << 8; + dev |= minor; + dev + } } extern "C" { diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs index 1af555fa3..aaa043584 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs @@ -434,6 +434,14 @@ pub const MINCORE_SUPER: ::c_int = 0x20; /// max length of devicename pub const SPECNAMELEN: ::c_int = 63; +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + (major << 8) | minor + } +} + extern "C" { // Return type ::c_int was removed in FreeBSD 12 pub fn setgrent() -> ::c_int; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs index 848db3399..e7f8ad780 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs @@ -449,6 +449,19 @@ pub const KI_NSPARE_PTR: usize = 6; pub const MINCORE_SUPER: ::c_int = 0x20; +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + extern "C" { pub fn setgrent(); pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs index a929f9d29..bcd09006b 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs @@ -468,6 +468,19 @@ pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; pub const MINCORE_SUPER: ::c_int = 0x20; +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + extern "C" { pub fn setgrent(); pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs index c655d555d..9da669604 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs @@ -468,6 +468,19 @@ pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; pub const MINCORE_SUPER: ::c_int = 0x60; +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + extern "C" { pub fn setgrent(); pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs index 84e43b23e..08fd5a52d 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -44,6 +44,8 @@ pub type fhandle_t = fhandle; pub type au_id_t = ::uid_t; pub type au_asid_t = ::pid_t; +pub type cpusetid_t = ::c_int; + #[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] #[repr(u32)] pub enum devstat_support_flags { @@ -990,6 +992,12 @@ s! { pub _flags: u32, pub _clockid: u32, } + + pub struct shm_largepage_conf { + pub psind: ::c_int, + pub alloc_policy: ::c_int, + __pad: [::c_int; 10], + } } s_no_extra_traits! { @@ -1890,6 +1898,9 @@ pub const LIO_READV: ::c_int = 6; pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4; pub const DEVSTAT_NAME_LEN: ::c_int = 16; +// sys/cpuset.h +pub const CPU_SETSIZE: ::c_int = 256; + pub const SIGEV_THREAD_ID: ::c_int = 4; pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; @@ -2249,6 +2260,7 @@ pub const FIONWRITE: ::c_ulong = 0x40046677; pub const FIONSPACE: ::c_ulong = 0x40046676; pub const FIOSEEKDATA: ::c_ulong = 0xc0086661; pub const FIOSEEKHOLE: ::c_ulong = 0xc0086662; +pub const FIOSSHMLPGCNF: ::c_ulong = 0x80306664; pub const JAIL_API_VERSION: u32 = 2; pub const JAIL_CREATE: ::c_int = 0x01; @@ -2508,6 +2520,8 @@ pub const IFCAP_TOE4: ::c_int = 0x04000; pub const IFCAP_TOE6: ::c_int = 0x08000; /// interface hw can filter vlan tag pub const IFCAP_VLAN_HWFILTER: ::c_int = 0x10000; +/// can do SIOCGIFCAPNV/SIOCSIFCAPNV +pub const IFCAP_NV: ::c_int = 0x20000; /// can do IFCAP_TSO on VLANs pub const IFCAP_VLAN_HWTSO: ::c_int = 0x40000; /// the runtime link state is dynamic @@ -2543,7 +2557,7 @@ pub const IFCAP_TSO: ::c_int = IFCAP_TSO4 | IFCAP_TSO6; pub const IFCAP_WOL: ::c_int = IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC; pub const IFCAP_TOE: ::c_int = IFCAP_TOE4 | IFCAP_TOE6; pub const IFCAP_TXTLS: ::c_int = IFCAP_TXTLS4 | IFCAP_TXTLS6; -pub const IFCAP_CANTCHANGE: ::c_int = IFCAP_NETMAP; +pub const IFCAP_CANTCHANGE: ::c_int = IFCAP_NETMAP | IFCAP_NV; pub const IFQ_MAXLEN: ::c_int = 50; pub const IFNET_SLOWHZ: ::c_int = 1; @@ -3227,30 +3241,67 @@ pub const KKST_STATE_RUNNING: ::c_int = 2; pub const PRI_MIN: ::c_int = 0; pub const PRI_MAX: ::c_int = 255; pub const PRI_MIN_ITHD: ::c_int = PRI_MIN; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PRI_MAX_ITHD: ::c_int = PRI_MIN_REALTIME - 1; pub const PI_REALTIME: ::c_int = PRI_MIN_ITHD + 0; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PI_AV: ::c_int = PRI_MIN_ITHD + 4; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PI_NET: ::c_int = PRI_MIN_ITHD + 8; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PI_DISK: ::c_int = PRI_MIN_ITHD + 12; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PI_TTY: ::c_int = PRI_MIN_ITHD + 16; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PI_DULL: ::c_int = PRI_MIN_ITHD + 20; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PI_SOFT: ::c_int = PRI_MIN_ITHD + 24; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PRI_MIN_REALTIME: ::c_int = 48; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PRI_MAX_REALTIME: ::c_int = PRI_MIN_KERN - 1; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PRI_MIN_KERN: ::c_int = 80; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PRI_MAX_KERN: ::c_int = PRI_MIN_TIMESHARE - 1; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PSWP: ::c_int = PRI_MIN_KERN + 0; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PVM: ::c_int = PRI_MIN_KERN + 4; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PINOD: ::c_int = PRI_MIN_KERN + 8; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PRIBIO: ::c_int = PRI_MIN_KERN + 12; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PVFS: ::c_int = PRI_MIN_KERN + 16; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PZERO: ::c_int = PRI_MIN_KERN + 20; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PSOCK: ::c_int = PRI_MIN_KERN + 24; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PWAIT: ::c_int = PRI_MIN_KERN + 28; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PLOCK: ::c_int = PRI_MIN_KERN + 32; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PPAUSE: ::c_int = PRI_MIN_KERN + 36; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const PRI_MIN_TIMESHARE: ::c_int = 120; pub const PRI_MAX_TIMESHARE: ::c_int = PRI_MIN_IDLE - 1; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] pub const PUSER: ::c_int = PRI_MIN_TIMESHARE; pub const PRI_MIN_IDLE: ::c_int = 224; pub const PRI_MAX_IDLE: ::c_int = PRI_MAX; @@ -3348,24 +3399,32 @@ pub const TDF_CANSWAP: ::c_int = 0x00000040; pub const TDF_KTH_SUSP: ::c_int = 0x00000100; pub const TDF_ALLPROCSUSP: ::c_int = 0x00000200; pub const TDF_BOUNDARY: ::c_int = 0x00000400; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_ASTPENDING: ::c_int = 0x00000800; pub const TDF_SBDRY: ::c_int = 0x00002000; pub const TDF_UPIBLOCKED: ::c_int = 0x00004000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_NEEDSUSPCHK: ::c_int = 0x00008000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_NEEDRESCHED: ::c_int = 0x00010000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_NEEDSIGCHK: ::c_int = 0x00020000; pub const TDF_NOLOAD: ::c_int = 0x00040000; pub const TDF_SERESTART: ::c_int = 0x00080000; pub const TDF_THRWAKEUP: ::c_int = 0x00100000; pub const TDF_SEINTR: ::c_int = 0x00200000; pub const TDF_SWAPINREQ: ::c_int = 0x00400000; +#[deprecated(since = "0.2.133", note = "Removed in FreeBSD 14")] pub const TDF_UNUSED23: ::c_int = 0x00800000; pub const TDF_SCHED0: ::c_int = 0x01000000; pub const TDF_SCHED1: ::c_int = 0x02000000; pub const TDF_SCHED2: ::c_int = 0x04000000; pub const TDF_SCHED3: ::c_int = 0x08000000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_ALRMPEND: ::c_int = 0x10000000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_PROFPEND: ::c_int = 0x20000000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] pub const TDF_MACPEND: ::c_int = 0x40000000; pub const TDB_SUSPEND: ::c_int = 0x00000001; @@ -3704,6 +3763,16 @@ pub const UMTX_OP_ROBUST_LISTS: ::c_int = 26; pub const UMTX_ABSTIME: u32 = 1; +pub const CPU_LEVEL_ROOT: ::c_int = 1; +pub const CPU_LEVEL_CPUSET: ::c_int = 2; +pub const CPU_LEVEL_WHICH: ::c_int = 3; + +pub const CPU_WHICH_TID: ::c_int = 1; +pub const CPU_WHICH_PID: ::c_int = 2; +pub const CPU_WHICH_CPUSET: ::c_int = 3; +pub const CPU_WHICH_IRQ: ::c_int = 4; +pub const CPU_WHICH_JAIL: ::c_int = 5; + const_fn! { {const} fn _ALIGN(p: usize) -> usize { (p + _ALIGNBYTES) & !_ALIGNBYTES @@ -3985,6 +4054,7 @@ extern "C" { infop: *mut ::siginfo_t, options: ::c_int, ) -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; @@ -4193,6 +4263,14 @@ extern "C" { setsize: ::size_t, mask: *const cpuset_t, ) -> ::c_int; + pub fn cpuset(setid: *mut ::cpusetid_t) -> ::c_int; + pub fn cpuset_getid( + level: cpulevel_t, + which: cpuwhich_t, + id: ::id_t, + setid: *mut ::cpusetid_t, + ) -> ::c_int; + pub fn cpuset_setid(which: cpuwhich_t, id: ::id_t, setid: ::cpusetid_t) -> ::c_int; pub fn cap_enter() -> ::c_int; pub fn cap_getmode(modep: *mut ::c_uint) -> ::c_int; pub fn __cap_rights_init(version: ::c_int, rights: *mut cap_rights_t, ...) diff --git a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs index b314b6856..db21597d9 100644 --- a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs +++ b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs @@ -376,6 +376,10 @@ s! { pub seq: ::c_ushort, pub key: ::key_t, } + + pub struct eui64 { + pub octet: [u8; EUI64_LEN], + } } s_no_extra_traits! { @@ -1329,6 +1333,8 @@ pub const ONLRET: ::tcflag_t = 0x40; pub const CMGROUP_MAX: usize = 16; +pub const EUI64_LEN: usize = 8; + // https://github.com/freebsd/freebsd/blob/master/sys/net/bpf.h pub const BPF_ALIGNMENT: usize = SIZEOF_LONG; @@ -1720,6 +1726,13 @@ extern "C" { pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; pub fn gethostid() -> ::c_long; pub fn sethostid(hostid: ::c_long); + + pub fn eui64_aton(a: *const ::c_char, e: *mut eui64) -> ::c_int; + pub fn eui64_ntoa(id: *const eui64, a: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn eui64_ntohost(hostname: *mut ::c_char, len: ::size_t, id: *const eui64) -> ::c_int; + pub fn eui64_hostton(hostname: *const ::c_char, id: *mut eui64) -> ::c_int; + + pub fn eaccess(path: *const ::c_char, mode: ::c_int) -> ::c_int; } #[link(name = "rt")] diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs index d12fd0730..bfe2de083 100644 --- a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -2271,6 +2271,33 @@ pub const LSZOMB: ::c_int = 5; pub const LSONPROC: ::c_int = 7; pub const LSSUSPENDED: ::c_int = 8; +pub const _REG_RDI: ::c_int = 0; +pub const _REG_RSI: ::c_int = 1; +pub const _REG_RDX: ::c_int = 2; +pub const _REG_RCX: ::c_int = 3; +pub const _REG_R8: ::c_int = 4; +pub const _REG_R9: ::c_int = 5; +pub const _REG_R10: ::c_int = 6; +pub const _REG_R11: ::c_int = 7; +pub const _REG_R12: ::c_int = 8; +pub const _REG_R13: ::c_int = 9; +pub const _REG_R14: ::c_int = 10; +pub const _REG_R15: ::c_int = 11; +pub const _REG_RBP: ::c_int = 12; +pub const _REG_RBX: ::c_int = 13; +pub const _REG_RAX: ::c_int = 14; +pub const _REG_GS: ::c_int = 15; +pub const _REG_FS: ::c_int = 16; +pub const _REG_ES: ::c_int = 17; +pub const _REG_DS: ::c_int = 18; +pub const _REG_TRAPNO: ::c_int = 19; +pub const _REG_ERR: ::c_int = 20; +pub const _REG_RIP: ::c_int = 21; +pub const _REG_CS: ::c_int = 22; +pub const _REG_RFLAGS: ::c_int = 23; +pub const _REG_RSP: ::c_int = 24; +pub const _REG_SS: ::c_int = 25; + const_fn! { {const} fn _ALIGN(p: usize) -> usize { (p + _ALIGNBYTES) & !_ALIGNBYTES @@ -2351,6 +2378,16 @@ safe_f! { pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { status == 0xffff } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major << 8) & 0x000ff00; + dev |= (minor << 12) & 0xfff00000; + dev |= minor & 0xff; + dev + } } extern "C" { diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs index 1910f24a4..506306e9f 100644 --- a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs @@ -1639,6 +1639,10 @@ pub const SF_ARCHIVED: ::c_uint = 0x00010000; pub const SF_IMMUTABLE: ::c_uint = 0x00020000; pub const SF_APPEND: ::c_uint = 0x00040000; +pub const MNT_WAIT: ::c_int = 1; +pub const MNT_NOWAIT: ::c_int = 2; +pub const MNT_LAZY: ::c_int = 3; + const_fn! { {const} fn _ALIGN(p: usize) -> usize { (p + _ALIGNBYTES) & !_ALIGNBYTES @@ -1695,6 +1699,16 @@ safe_f! { pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { (status & 0o177777) == 0o177777 } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0xff) << 8; + dev |= minor & 0xff; + dev |= (minor & 0xffff00) << 8; + dev + } } extern "C" { @@ -1870,6 +1884,8 @@ cfg_if! { // these functions use statfs which uses the union mount_info: pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn getmntinfo(mntbufp: *mut *mut ::statfs, flags: ::c_int) -> ::c_int; + pub fn getfsstat(buf: *mut statfs, bufsize: ::size_t, flags: ::c_int) -> ::c_int; } } } diff --git a/vendor/libc/src/unix/linux_like/android/mod.rs b/vendor/libc/src/unix/linux_like/android/mod.rs index cfd229a47..67e5eb52b 100644 --- a/vendor/libc/src/unix/linux_like/android/mod.rs +++ b/vendor/libc/src/unix/linux_like/android/mod.rs @@ -2709,6 +2709,17 @@ pub const RTMSG_DELDEVICE: u32 = 0x12; pub const RTMSG_NEWROUTE: u32 = 0x21; pub const RTMSG_DELROUTE: u32 = 0x22; +// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the +// following are only available on newer Linux versions than the versions +// currently used in CI in some configurations, so we define them here. +cfg_if! { + if #[cfg(not(target_arch = "s390x"))] { + pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + } else if #[cfg(target_arch = "s390x")] { + pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342; + } +} + f! { pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { @@ -2781,12 +2792,6 @@ f! { pub fn minor(dev: ::dev_t) -> ::c_int { ((dev & 0xff) | ((dev >> 12) & 0xfff00)) as ::c_int } - pub fn makedev(ma: ::c_int, mi: ::c_int) -> ::dev_t { - let ma = ma as ::dev_t; - let mi = mi as ::dev_t; - ((ma & 0xfff) << 8) | (mi & 0xff) | ((mi & 0xfff00) << 12) - } - pub fn NLA_ALIGN(len: ::c_int) -> ::c_int { return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) } @@ -2796,6 +2801,15 @@ f! { } } +safe_f! { + pub {const} fn makedev(ma: ::c_uint, mi: ::c_uint) -> ::dev_t { + let ma = ma as ::dev_t; + let mi = mi as ::dev_t; + ((ma & 0xfff) << 8) | (mi & 0xff) | ((mi & 0xfff00) << 12) + } + +} + extern "C" { pub fn getrlimit64(resource: ::c_int, rlim: *mut rlimit64) -> ::c_int; pub fn setrlimit64(resource: ::c_int, rlim: *const rlimit64) -> ::c_int; diff --git a/vendor/libc/src/unix/linux_like/emscripten/mod.rs b/vendor/libc/src/unix/linux_like/emscripten/mod.rs index 31d0ebf25..11fbb31c3 100644 --- a/vendor/libc/src/unix/linux_like/emscripten/mod.rs +++ b/vendor/libc/src/unix/linux_like/emscripten/mod.rs @@ -1740,8 +1740,10 @@ f! { minor |= (dev & 0xffffff00) >> 12; minor as ::c_uint } +} - pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { let major = major as ::dev_t; let minor = minor as ::dev_t; let mut dev = 0; diff --git a/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs b/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs index 320579955..5265cdd17 100644 --- a/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs @@ -104,6 +104,13 @@ cfg_if! { pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; } } + +cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + pub const FICLONE: ::c_ulong = 0x40049409; + pub const FICLONERANGE: ::c_ulong = 0x4020940D; + } +} // pub const SO_PREFER_BUSY_POLL: ::c_int = 69; // pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs index 2a064974d..e0ac0dfc3 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs @@ -835,6 +835,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; cfg_if! { if #[cfg(libc_align)] { diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs index eb3886fbc..6a03f0ba8 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs @@ -536,6 +536,14 @@ pub const SYS_faccessat2: ::c_long = 4000 + 439; pub const SYS_process_madvise: ::c_long = 4000 + 440; pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; pub const SYS_mount_setattr: ::c_long = 4000 + 442; +pub const SYS_quotactl_fd: ::c_long = 4000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; +pub const SYS_memfd_secret: ::c_long = 4000 + 447; +pub const SYS_process_mrelease: ::c_long = 4000 + 448; +pub const SYS_futex_waitv: ::c_long = 4000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; pub const O_DIRECT: ::c_int = 0x8000; pub const O_DIRECTORY: ::c_int = 0x10000; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs index ad45c607f..e70b216bf 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs @@ -814,3 +814,11 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs index def90d6d1..827f85e86 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs @@ -758,6 +758,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; cfg_if! { if #[cfg(libc_align)] { diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs index 5dd2302db..57ad9fe8e 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs @@ -839,6 +839,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; cfg_if! { if #[cfg(libc_align)] { diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs index e42e9ebd6..93622387e 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs @@ -1040,6 +1040,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; // offsets in user_regs_structs, from sys/reg.h pub const EBX: ::c_int = 0; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs index 60a1b6932..b620cc03f 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs @@ -885,6 +885,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { pub fn sysctl( diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs index cac215dc4..0bf5084d5 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs @@ -587,6 +587,14 @@ pub const SYS_faccessat2: ::c_long = 5000 + 439; pub const SYS_process_madvise: ::c_long = 5000 + 440; pub const SYS_epoll_pwait2: ::c_long = 5000 + 441; pub const SYS_mount_setattr: ::c_long = 5000 + 442; +pub const SYS_quotactl_fd: ::c_long = 5000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 5000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 5000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 5000 + 446; +pub const SYS_memfd_secret: ::c_long = 5000 + 447; +pub const SYS_process_mrelease: ::c_long = 5000 + 448; +pub const SYS_futex_waitv: ::c_long = 5000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 5000 + 450; pub const SFD_CLOEXEC: ::c_int = 0x080000; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs index b5c268706..ce8ce97bb 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs @@ -948,6 +948,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { pub fn sysctl( diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs index f8073902a..9d022f96e 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs @@ -797,6 +797,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; cfg_if! { if #[cfg(libc_align)] { diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs index 212dc898c..c4bae089c 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs @@ -935,6 +935,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs index 8d065e6a3..9fdacfac8 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs @@ -900,6 +900,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { pub fn sysctl( diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs index 7e876f2d8..d515d2231 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs @@ -265,6 +265,14 @@ s! { pub seccomp_notif_resp: ::__u16, pub seccomp_data: ::__u16, } + + pub struct ptrace_rseq_configuration { + pub rseq_abi_pointer: ::__u64, + pub rseq_abi_size: ::__u32, + pub signature: ::__u32, + pub flags: ::__u32, + pub pad: ::__u32, + } } s_no_extra_traits! { @@ -535,6 +543,7 @@ pub const O_ASYNC: ::c_int = 0x2000; pub const O_NDELAY: ::c_int = 0x800; pub const PTRACE_DETACH: ::c_uint = 17; +pub const PTRACE_GET_RSEQ_CONFIGURATION: ::c_uint = 0x420f; pub const EFD_NONBLOCK: ::c_int = 0x800; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs index f840f9f44..35d2714ee 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs @@ -429,6 +429,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { pub fn sysctl( diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs index de1a8b94b..807b948ef 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs @@ -357,6 +357,14 @@ pub const SYS_faccessat2: ::c_long = __X32_SYSCALL_BIT + 439; pub const SYS_process_madvise: ::c_long = __X32_SYSCALL_BIT + 440; pub const SYS_epoll_pwait2: ::c_long = __X32_SYSCALL_BIT + 441; pub const SYS_mount_setattr: ::c_long = __X32_SYSCALL_BIT + 442; +pub const SYS_quotactl_fd: ::c_long = __X32_SYSCALL_BIT + 443; +pub const SYS_landlock_create_ruleset: ::c_long = __X32_SYSCALL_BIT + 444; +pub const SYS_landlock_add_rule: ::c_long = __X32_SYSCALL_BIT + 445; +pub const SYS_landlock_restrict_self: ::c_long = __X32_SYSCALL_BIT + 446; +pub const SYS_memfd_secret: ::c_long = __X32_SYSCALL_BIT + 447; +pub const SYS_process_mrelease: ::c_long = __X32_SYSCALL_BIT + 448; +pub const SYS_futex_waitv: ::c_long = __X32_SYSCALL_BIT + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = __X32_SYSCALL_BIT + 450; pub const SYS_rt_sigaction: ::c_long = __X32_SYSCALL_BIT + 512; pub const SYS_rt_sigreturn: ::c_long = __X32_SYSCALL_BIT + 513; pub const SYS_ioctl: ::c_long = __X32_SYSCALL_BIT + 514; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs index 88bc935f6..21e7619db 100644 --- a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs @@ -954,6 +954,8 @@ pub const NT_LWPSTATUS: ::c_int = 16; pub const NT_LWPSINFO: ::c_int = 17; pub const NT_PRFPXREG: ::c_int = 20; +pub const ELFOSABI_ARM_AEABI: u8 = 64; + // linux/keyctl.h pub const KEYCTL_DH_COMPUTE: u32 = 23; pub const KEYCTL_PKEY_QUERY: u32 = 24; @@ -1024,6 +1026,9 @@ pub const STATX_ATTR_APPEND: ::c_int = 0x0020; pub const STATX_ATTR_NODUMP: ::c_int = 0x0040; pub const STATX_ATTR_ENCRYPTED: ::c_int = 0x0800; pub const STATX_ATTR_AUTOMOUNT: ::c_int = 0x1000; +pub const STATX_ATTR_MOUNT_ROOT: ::c_int = 0x2000; +pub const STATX_ATTR_VERITY: ::c_int = 0x00100000; +pub const STATX_ATTR_DAX: ::c_int = 0x00200000; pub const SOMAXCONN: ::c_int = 4096; @@ -1308,11 +1313,28 @@ extern "C" { buflen: ::size_t, result: *mut *mut ::group, ) -> ::c_int; + pub fn fgetpwent_r( + stream: *mut ::FILE, + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn fgetgrent_r( + stream: *mut ::FILE, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; pub fn sethostid(hostid: ::c_long) -> ::c_int; pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int; + + pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; } extern "C" { diff --git a/vendor/libc/src/unix/linux_like/linux/mod.rs b/vendor/libc/src/unix/linux_like/linux/mod.rs index aba691e5a..43f6399e4 100644 --- a/vendor/libc/src/unix/linux_like/linux/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/mod.rs @@ -596,6 +596,13 @@ s! { pub nla_len: u16, pub nla_type: u16, } + + pub struct file_clone_range { + pub src_fd: ::__s64, + pub src_offset: ::__u64, + pub src_length: ::__u64, + pub dest_offset: ::__u64, + } } s_no_extra_traits! { @@ -1299,6 +1306,181 @@ pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; +// elf.h - Fields in the e_ident array. +pub const EI_NIDENT: usize = 16; + +pub const EI_MAG0: usize = 0; +pub const ELFMAG0: u8 = 0x7f; +pub const EI_MAG1: usize = 1; +pub const ELFMAG1: u8 = b'E'; +pub const EI_MAG2: usize = 2; +pub const ELFMAG2: u8 = b'L'; +pub const EI_MAG3: usize = 3; +pub const ELFMAG3: u8 = b'F'; +pub const SELFMAG: usize = 4; + +pub const EI_CLASS: usize = 4; +pub const ELFCLASSNONE: u8 = 0; +pub const ELFCLASS32: u8 = 1; +pub const ELFCLASS64: u8 = 2; +pub const ELFCLASSNUM: usize = 3; + +pub const EI_DATA: usize = 5; +pub const ELFDATANONE: u8 = 0; +pub const ELFDATA2LSB: u8 = 1; +pub const ELFDATA2MSB: u8 = 2; +pub const ELFDATANUM: usize = 3; + +pub const EI_VERSION: usize = 6; + +pub const EI_OSABI: usize = 7; +pub const ELFOSABI_NONE: u8 = 0; +pub const ELFOSABI_SYSV: u8 = 0; +pub const ELFOSABI_HPUX: u8 = 1; +pub const ELFOSABI_NETBSD: u8 = 2; +pub const ELFOSABI_GNU: u8 = 3; +pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU; +pub const ELFOSABI_SOLARIS: u8 = 6; +pub const ELFOSABI_AIX: u8 = 7; +pub const ELFOSABI_IRIX: u8 = 8; +pub const ELFOSABI_FREEBSD: u8 = 9; +pub const ELFOSABI_TRU64: u8 = 10; +pub const ELFOSABI_MODESTO: u8 = 11; +pub const ELFOSABI_OPENBSD: u8 = 12; +pub const ELFOSABI_ARM: u8 = 97; +pub const ELFOSABI_STANDALONE: u8 = 255; + +pub const EI_ABIVERSION: usize = 8; + +pub const EI_PAD: usize = 9; + +// elf.h - Legal values for e_type (object file type). +pub const ET_NONE: u16 = 0; +pub const ET_REL: u16 = 1; +pub const ET_EXEC: u16 = 2; +pub const ET_DYN: u16 = 3; +pub const ET_CORE: u16 = 4; +pub const ET_NUM: u16 = 5; +pub const ET_LOOS: u16 = 0xfe00; +pub const ET_HIOS: u16 = 0xfeff; +pub const ET_LOPROC: u16 = 0xff00; +pub const ET_HIPROC: u16 = 0xffff; + +// elf.h - Legal values for e_machine (architecture). +pub const EM_NONE: u16 = 0; +pub const EM_M32: u16 = 1; +pub const EM_SPARC: u16 = 2; +pub const EM_386: u16 = 3; +pub const EM_68K: u16 = 4; +pub const EM_88K: u16 = 5; +pub const EM_860: u16 = 7; +pub const EM_MIPS: u16 = 8; +pub const EM_S370: u16 = 9; +pub const EM_MIPS_RS3_LE: u16 = 10; +pub const EM_PARISC: u16 = 15; +pub const EM_VPP500: u16 = 17; +pub const EM_SPARC32PLUS: u16 = 18; +pub const EM_960: u16 = 19; +pub const EM_PPC: u16 = 20; +pub const EM_PPC64: u16 = 21; +pub const EM_S390: u16 = 22; +pub const EM_V800: u16 = 36; +pub const EM_FR20: u16 = 37; +pub const EM_RH32: u16 = 38; +pub const EM_RCE: u16 = 39; +pub const EM_ARM: u16 = 40; +pub const EM_FAKE_ALPHA: u16 = 41; +pub const EM_SH: u16 = 42; +pub const EM_SPARCV9: u16 = 43; +pub const EM_TRICORE: u16 = 44; +pub const EM_ARC: u16 = 45; +pub const EM_H8_300: u16 = 46; +pub const EM_H8_300H: u16 = 47; +pub const EM_H8S: u16 = 48; +pub const EM_H8_500: u16 = 49; +pub const EM_IA_64: u16 = 50; +pub const EM_MIPS_X: u16 = 51; +pub const EM_COLDFIRE: u16 = 52; +pub const EM_68HC12: u16 = 53; +pub const EM_MMA: u16 = 54; +pub const EM_PCP: u16 = 55; +pub const EM_NCPU: u16 = 56; +pub const EM_NDR1: u16 = 57; +pub const EM_STARCORE: u16 = 58; +pub const EM_ME16: u16 = 59; +pub const EM_ST100: u16 = 60; +pub const EM_TINYJ: u16 = 61; +pub const EM_X86_64: u16 = 62; +pub const EM_PDSP: u16 = 63; +pub const EM_FX66: u16 = 66; +pub const EM_ST9PLUS: u16 = 67; +pub const EM_ST7: u16 = 68; +pub const EM_68HC16: u16 = 69; +pub const EM_68HC11: u16 = 70; +pub const EM_68HC08: u16 = 71; +pub const EM_68HC05: u16 = 72; +pub const EM_SVX: u16 = 73; +pub const EM_ST19: u16 = 74; +pub const EM_VAX: u16 = 75; +pub const EM_CRIS: u16 = 76; +pub const EM_JAVELIN: u16 = 77; +pub const EM_FIREPATH: u16 = 78; +pub const EM_ZSP: u16 = 79; +pub const EM_MMIX: u16 = 80; +pub const EM_HUANY: u16 = 81; +pub const EM_PRISM: u16 = 82; +pub const EM_AVR: u16 = 83; +pub const EM_FR30: u16 = 84; +pub const EM_D10V: u16 = 85; +pub const EM_D30V: u16 = 86; +pub const EM_V850: u16 = 87; +pub const EM_M32R: u16 = 88; +pub const EM_MN10300: u16 = 89; +pub const EM_MN10200: u16 = 90; +pub const EM_PJ: u16 = 91; +pub const EM_OPENRISC: u16 = 92; +pub const EM_ARC_A5: u16 = 93; +pub const EM_XTENSA: u16 = 94; +pub const EM_AARCH64: u16 = 183; +pub const EM_TILEPRO: u16 = 188; +pub const EM_TILEGX: u16 = 191; +pub const EM_ALPHA: u16 = 0x9026; + +// elf.h - Legal values for e_version (version). +pub const EV_NONE: u32 = 0; +pub const EV_CURRENT: u32 = 1; +pub const EV_NUM: u32 = 2; + +// elf.h - Legal values for p_type (segment type). +pub const PT_NULL: u32 = 0; +pub const PT_LOAD: u32 = 1; +pub const PT_DYNAMIC: u32 = 2; +pub const PT_INTERP: u32 = 3; +pub const PT_NOTE: u32 = 4; +pub const PT_SHLIB: u32 = 5; +pub const PT_PHDR: u32 = 6; +pub const PT_TLS: u32 = 7; +pub const PT_NUM: u32 = 8; +pub const PT_LOOS: u32 = 0x60000000; +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_STACK: u32 = 0x6474e551; +pub const PT_GNU_RELRO: u32 = 0x6474e552; +pub const PT_LOSUNW: u32 = 0x6ffffffa; +pub const PT_SUNWBSS: u32 = 0x6ffffffa; +pub const PT_SUNWSTACK: u32 = 0x6ffffffb; +pub const PT_HISUNW: u32 = 0x6fffffff; +pub const PT_HIOS: u32 = 0x6fffffff; +pub const PT_LOPROC: u32 = 0x70000000; +pub const PT_HIPROC: u32 = 0x7fffffff; + +// Legal values for p_flags (segment flags). +pub const PF_X: u32 = 1 << 0; +pub const PF_W: u32 = 1 << 1; +pub const PF_R: u32 = 1 << 2; +pub const PF_MASKOS: u32 = 0x0ff00000; +pub const PF_MASKPROC: u32 = 0xf0000000; + +// elf.h - Legal values for a_type (entry type). pub const AT_NULL: ::c_ulong = 0; pub const AT_IGNORE: ::c_ulong = 1; pub const AT_EXECFD: ::c_ulong = 2; @@ -1951,26 +2133,6 @@ pub const RESOLVE_BENEATH: ::__u64 = 0x08; pub const RESOLVE_IN_ROOT: ::__u64 = 0x10; pub const RESOLVE_CACHED: ::__u64 = 0x20; -// these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has -// the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 -// so we can use that type here to avoid having to cast. -pub const PT_NULL: u32 = 0; -pub const PT_LOAD: u32 = 1; -pub const PT_DYNAMIC: u32 = 2; -pub const PT_INTERP: u32 = 3; -pub const PT_NOTE: u32 = 4; -pub const PT_SHLIB: u32 = 5; -pub const PT_PHDR: u32 = 6; -pub const PT_TLS: u32 = 7; -pub const PT_NUM: u32 = 8; -pub const PT_LOOS: u32 = 0x60000000; -pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; -pub const PT_GNU_STACK: u32 = 0x6474e551; -pub const PT_GNU_RELRO: u32 = 0x6474e552; -pub const PT_HIOS: u32 = 0x6fffffff; -pub const PT_LOPROC: u32 = 0x70000000; -pub const PT_HIPROC: u32 = 0x7fffffff; - // linux/if_ether.h pub const ETH_ALEN: ::c_int = 6; pub const ETH_HLEN: ::c_int = 14; @@ -2086,6 +2248,7 @@ pub const NFNLGRP_CONNTRACK_EXP_UPDATE: ::c_int = 5; pub const NFNLGRP_CONNTRACK_EXP_DESTROY: ::c_int = 6; pub const NFNLGRP_NFTABLES: ::c_int = 7; pub const NFNLGRP_ACCT_QUOTA: ::c_int = 8; +pub const NFNLGRP_NFTRACE: ::c_int = 9; pub const NFNETLINK_V0: ::c_int = 0; @@ -2101,15 +2264,23 @@ pub const NFNL_SUBSYS_CTNETLINK_TIMEOUT: ::c_int = 8; pub const NFNL_SUBSYS_CTHELPER: ::c_int = 9; pub const NFNL_SUBSYS_NFTABLES: ::c_int = 10; pub const NFNL_SUBSYS_NFT_COMPAT: ::c_int = 11; -pub const NFNL_SUBSYS_COUNT: ::c_int = 12; +pub const NFNL_SUBSYS_HOOK: ::c_int = 12; +pub const NFNL_SUBSYS_COUNT: ::c_int = 13; pub const NFNL_MSG_BATCH_BEGIN: ::c_int = NLMSG_MIN_TYPE; pub const NFNL_MSG_BATCH_END: ::c_int = NLMSG_MIN_TYPE + 1; +pub const NFNL_BATCH_UNSPEC: ::c_int = 0; +pub const NFNL_BATCH_GENID: ::c_int = 1; + // linux/netfilter/nfnetlink_log.h pub const NFULNL_MSG_PACKET: ::c_int = 0; pub const NFULNL_MSG_CONFIG: ::c_int = 1; +pub const NFULA_VLAN_UNSPEC: ::c_int = 0; +pub const NFULA_VLAN_PROTO: ::c_int = 1; +pub const NFULA_VLAN_TCI: ::c_int = 2; + pub const NFULA_UNSPEC: ::c_int = 0; pub const NFULA_PACKET_HDR: ::c_int = 1; pub const NFULA_MARK: ::c_int = 2; @@ -2130,6 +2301,8 @@ pub const NFULA_HWHEADER: ::c_int = 16; pub const NFULA_HWLEN: ::c_int = 17; pub const NFULA_CT: ::c_int = 18; pub const NFULA_CT_INFO: ::c_int = 19; +pub const NFULA_VLAN: ::c_int = 20; +pub const NFULA_L2HDR: ::c_int = 21; pub const NFULNL_CFG_CMD_NONE: ::c_int = 0; pub const NFULNL_CFG_CMD_BIND: ::c_int = 1; @@ -2153,7 +2326,7 @@ pub const NFULNL_CFG_F_SEQ: ::c_int = 0x0001; pub const NFULNL_CFG_F_SEQ_GLOBAL: ::c_int = 0x0002; pub const NFULNL_CFG_F_CONNTRACK: ::c_int = 0x0004; -// linux/netfilter/nfnetlink_log.h +// linux/netfilter/nfnetlink_queue.h pub const NFQNL_MSG_PACKET: ::c_int = 0; pub const NFQNL_MSG_VERDICT: ::c_int = 1; pub const NFQNL_MSG_CONFIG: ::c_int = 2; @@ -2178,18 +2351,13 @@ pub const NFQA_EXP: ::c_int = 15; pub const NFQA_UID: ::c_int = 16; pub const NFQA_GID: ::c_int = 17; pub const NFQA_SECCTX: ::c_int = 18; -/* - FIXME: These are not yet available in musl sanitized kernel headers and - make the tests fail. Enable them once musl has them. - - See https://github.com/rust-lang/libc/pull/1628 for more details. pub const NFQA_VLAN: ::c_int = 19; pub const NFQA_L2HDR: ::c_int = 20; +pub const NFQA_PRIORITY: ::c_int = 21; pub const NFQA_VLAN_UNSPEC: ::c_int = 0; pub const NFQA_VLAN_PROTO: ::c_int = 1; pub const NFQA_VLAN_TCI: ::c_int = 2; -*/ pub const NFQNL_CFG_CMD_NONE: ::c_int = 0; pub const NFQNL_CFG_CMD_BIND: ::c_int = 1; @@ -2219,6 +2387,8 @@ pub const NFQA_SKB_CSUMNOTREADY: ::c_int = 0x0001; pub const NFQA_SKB_GSO: ::c_int = 0x0002; pub const NFQA_SKB_CSUM_NOTVERIFIED: ::c_int = 0x0004; +// linux/genetlink.h + pub const GENL_NAMSIZ: ::c_int = 16; pub const GENL_MIN_ID: ::c_int = NLMSG_MIN_TYPE; @@ -2661,6 +2831,62 @@ pub const ARPD_LOOKUP: ::c_ushort = 0x02; pub const ARPD_FLUSH: ::c_ushort = 0x03; pub const ATF_MAGIC: ::c_int = 0x80; +// userspace compat definitions for RTNLGRP_* +pub const RTMGRP_LINK: ::c_int = 0x00001; +pub const RTMGRP_NOTIFY: ::c_int = 0x00002; +pub const RTMGRP_NEIGH: ::c_int = 0x00004; +pub const RTMGRP_TC: ::c_int = 0x00008; +pub const RTMGRP_IPV4_IFADDR: ::c_int = 0x00010; +pub const RTMGRP_IPV4_MROUTE: ::c_int = 0x00020; +pub const RTMGRP_IPV4_ROUTE: ::c_int = 0x00040; +pub const RTMGRP_IPV4_RULE: ::c_int = 0x00080; +pub const RTMGRP_IPV6_IFADDR: ::c_int = 0x00100; +pub const RTMGRP_IPV6_MROUTE: ::c_int = 0x00200; +pub const RTMGRP_IPV6_ROUTE: ::c_int = 0x00400; +pub const RTMGRP_IPV6_IFINFO: ::c_int = 0x00800; +pub const RTMGRP_DECnet_IFADDR: ::c_int = 0x01000; +pub const RTMGRP_DECnet_ROUTE: ::c_int = 0x04000; +pub const RTMGRP_IPV6_PREFIX: ::c_int = 0x20000; + +// enum rtnetlink_groups +pub const RTNLGRP_NONE: ::c_uint = 0x00; +pub const RTNLGRP_LINK: ::c_uint = 0x01; +pub const RTNLGRP_NOTIFY: ::c_uint = 0x02; +pub const RTNLGRP_NEIGH: ::c_uint = 0x03; +pub const RTNLGRP_TC: ::c_uint = 0x04; +pub const RTNLGRP_IPV4_IFADDR: ::c_uint = 0x05; +pub const RTNLGRP_IPV4_MROUTE: ::c_uint = 0x06; +pub const RTNLGRP_IPV4_ROUTE: ::c_uint = 0x07; +pub const RTNLGRP_IPV4_RULE: ::c_uint = 0x08; +pub const RTNLGRP_IPV6_IFADDR: ::c_uint = 0x09; +pub const RTNLGRP_IPV6_MROUTE: ::c_uint = 0x0a; +pub const RTNLGRP_IPV6_ROUTE: ::c_uint = 0x0b; +pub const RTNLGRP_IPV6_IFINFO: ::c_uint = 0x0c; +pub const RTNLGRP_DECnet_IFADDR: ::c_uint = 0x0d; +pub const RTNLGRP_NOP2: ::c_uint = 0x0e; +pub const RTNLGRP_DECnet_ROUTE: ::c_uint = 0x0f; +pub const RTNLGRP_DECnet_RULE: ::c_uint = 0x10; +pub const RTNLGRP_NOP4: ::c_uint = 0x11; +pub const RTNLGRP_IPV6_PREFIX: ::c_uint = 0x12; +pub const RTNLGRP_IPV6_RULE: ::c_uint = 0x13; +pub const RTNLGRP_ND_USEROPT: ::c_uint = 0x14; +pub const RTNLGRP_PHONET_IFADDR: ::c_uint = 0x15; +pub const RTNLGRP_PHONET_ROUTE: ::c_uint = 0x16; +pub const RTNLGRP_DCB: ::c_uint = 0x17; +pub const RTNLGRP_IPV4_NETCONF: ::c_uint = 0x18; +pub const RTNLGRP_IPV6_NETCONF: ::c_uint = 0x19; +pub const RTNLGRP_MDB: ::c_uint = 0x1a; +pub const RTNLGRP_MPLS_ROUTE: ::c_uint = 0x1b; +pub const RTNLGRP_NSID: ::c_uint = 0x1c; +pub const RTNLGRP_MPLS_NETCONF: ::c_uint = 0x1d; +pub const RTNLGRP_IPV4_MROUTE_R: ::c_uint = 0x1e; +pub const RTNLGRP_IPV6_MROUTE_R: ::c_uint = 0x1f; +pub const RTNLGRP_NEXTHOP: ::c_uint = 0x20; +pub const RTNLGRP_BRVLAN: ::c_uint = 0x21; +pub const RTNLGRP_MCTP_IFADDR: ::c_uint = 0x22; +pub const RTNLGRP_TUNNEL: ::c_uint = 0x23; +pub const RTNLGRP_STATS: ::c_uint = 0x24; + // linux/module.h pub const MODULE_INIT_IGNORE_MODVERSIONS: ::c_uint = 0x0001; pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002; @@ -2673,6 +2899,14 @@ pub const SOF_TIMESTAMPING_RX_SOFTWARE: ::c_uint = 1 << 3; pub const SOF_TIMESTAMPING_SOFTWARE: ::c_uint = 1 << 4; pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5; pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6; +pub const SOF_TIMESTAMPING_OPT_ID: ::c_uint = 1 << 7; +pub const SOF_TIMESTAMPING_TX_SCHED: ::c_uint = 1 << 8; +pub const SOF_TIMESTAMPING_TX_ACK: ::c_uint = 1 << 9; +pub const SOF_TIMESTAMPING_OPT_CMSG: ::c_uint = 1 << 10; +pub const SOF_TIMESTAMPING_OPT_TSONLY: ::c_uint = 1 << 11; +pub const SOF_TIMESTAMPING_OPT_STATS: ::c_uint = 1 << 12; +pub const SOF_TIMESTAMPING_OPT_PKTINFO: ::c_uint = 1 << 13; +pub const SOF_TIMESTAMPING_OPT_TX_SWHW: ::c_uint = 1 << 14; pub const SOF_TXTIME_DEADLINE_MODE: u32 = 1 << 0; pub const SOF_TXTIME_REPORT_ERRORS: u32 = 1 << 1; @@ -3343,17 +3577,6 @@ f! { minor as ::c_uint } - pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { - let major = major as ::dev_t; - let minor = minor as ::dev_t; - let mut dev = 0; - dev |= (major & 0x00000fff) << 8; - dev |= (major & 0xfffff000) << 32; - dev |= (minor & 0x000000ff) << 0; - dev |= (minor & 0xffffff00) << 12; - dev - } - pub fn IPTOS_TOS(tos: u8) -> u8 { tos & IPTOS_TOS_MASK } @@ -3395,6 +3618,19 @@ f! { } } +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0x00000fff) << 8; + dev |= (major & 0xfffff000) << 32; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } +} + cfg_if! { if #[cfg(not(target_env = "uclibc"))] { extern "C" { diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs index 7e4868b85..c47fa2c4c 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs @@ -837,6 +837,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs index 7443a09ed..40b507bcd 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs @@ -777,6 +777,14 @@ pub const SYS_faccessat2: ::c_long = 4000 + 439; pub const SYS_process_madvise: ::c_long = 4000 + 440; pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; pub const SYS_mount_setattr: ::c_long = 4000 + 442; +pub const SYS_quotactl_fd: ::c_long = 4000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; +pub const SYS_memfd_secret: ::c_long = 4000 + 447; +pub const SYS_process_mrelease: ::c_long = 4000 + 448; +pub const SYS_futex_waitv: ::c_long = 4000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; cfg_if! { if #[cfg(libc_align)] { diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs index 6d2ecf2d8..63824fbf5 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs @@ -3,6 +3,7 @@ pub type c_ulong = u32; pub type nlink_t = u32; pub type blksize_t = ::c_long; pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; pub type regoff_t = ::c_int; s! { diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs index d7ca03813..5b1bf17ed 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs @@ -790,6 +790,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; extern "C" { pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs index 9b68ce258..573624620 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs @@ -271,6 +271,7 @@ pub const ENOPROTOOPT: ::c_int = 92; pub const EPROTONOSUPPORT: ::c_int = 93; pub const ESOCKTNOSUPPORT: ::c_int = 94; pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; pub const EPFNOSUPPORT: ::c_int = 96; pub const EAFNOSUPPORT: ::c_int = 97; pub const EADDRINUSE: ::c_int = 98; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs index a6efea13b..c319b91b6 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs @@ -856,6 +856,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; // offsets in user_regs_structs, from sys/reg.h pub const EBX: ::c_int = 0; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs index 845707dcd..14b4bc6d6 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs @@ -1,5 +1,6 @@ pub type c_char = u8; pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; pub type wchar_t = u32; pub type nlink_t = u32; pub type blksize_t = ::c_int; @@ -555,6 +556,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; pub const MCL_CURRENT: ::c_int = 0x0001; pub const MCL_FUTURE: ::c_int = 0x0002; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs index 1ed13f66b..22ac91690 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs @@ -1,6 +1,7 @@ pub type c_char = i8; pub type wchar_t = i32; pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; pub type nlink_t = u64; pub type blksize_t = i64; @@ -444,6 +445,14 @@ pub const SYS_faccessat2: ::c_long = 5000 + 439; pub const SYS_process_madvise: ::c_long = 5000 + 440; pub const SYS_epoll_pwait2: ::c_long = 5000 + 441; pub const SYS_mount_setattr: ::c_long = 5000 + 442; +pub const SYS_quotactl_fd: ::c_long = 5000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 5000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 5000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 5000 + 446; +pub const SYS_memfd_secret: ::c_long = 5000 + 447; +pub const SYS_process_mrelease: ::c_long = 5000 + 448; +pub const SYS_futex_waitv: ::c_long = 5000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 5000 + 450; pub const O_DIRECT: ::c_int = 0x8000; pub const O_DIRECTORY: ::c_int = 0x10000; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs index f17d72cb1..0bb4cf837 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs @@ -1,6 +1,7 @@ pub type c_char = u8; pub type wchar_t = i32; pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; pub type nlink_t = u64; pub type blksize_t = ::c_long; @@ -600,6 +601,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; pub const EDEADLK: ::c_int = 58; pub const EDEADLOCK: ::c_int = EDEADLK; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs index fcb28c3cf..f354293e0 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs @@ -8,6 +8,7 @@ pub type blksize_t = ::c_int; pub type fsblkcnt64_t = ::c_ulong; pub type fsfilcnt64_t = ::c_ulong; pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; s! { pub struct pthread_attr_t { diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs index cb6237abc..60bfc8d3e 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs @@ -4,6 +4,7 @@ pub type nlink_t = u64; pub type wchar_t = i32; pub type greg_t = u64; pub type __u64 = u64; +pub type __s64 = i64; s! { pub struct ipc_perm { @@ -710,3 +711,11 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs index 3429c2c1a..8198dc2f3 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs @@ -3,6 +3,7 @@ pub type wchar_t = i32; pub type nlink_t = u64; pub type blksize_t = ::c_long; pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; pub type greg_t = i64; s! { @@ -599,6 +600,14 @@ pub const SYS_faccessat2: ::c_long = 439; pub const SYS_process_madvise: ::c_long = 440; pub const SYS_epoll_pwait2: ::c_long = 441; pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; // offsets in user_regs_structs, from sys/reg.h pub const R15: ::c_int = 0; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs index 6cdc31388..894f377ac 100644 --- a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs @@ -754,6 +754,9 @@ extern "C" { pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int; pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + + pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; } cfg_if! { diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs index e0279574b..a0035b277 100644 --- a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs @@ -19,6 +19,7 @@ pub type blkcnt_t = ::c_long; pub type fsblkcnt64_t = u64; pub type fsfilcnt64_t = u64; pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; s! { pub struct cmsghdr { diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs index 529711fce..43ac79296 100644 --- a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs @@ -20,6 +20,7 @@ pub type wchar_t = ::c_int; pub type fsblkcnt64_t = u64; pub type fsfilcnt64_t = u64; pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; s! { pub struct ipc_perm { diff --git a/vendor/libc/src/unix/linux_like/mod.rs b/vendor/libc/src/unix/linux_like/mod.rs index 57600f24b..46964cc17 100644 --- a/vendor/libc/src/unix/linux_like/mod.rs +++ b/vendor/libc/src/unix/linux_like/mod.rs @@ -1434,6 +1434,7 @@ cfg_if! { pub const UDF_SUPER_MAGIC: ::c_long = 0x15013346; pub const USBDEVICE_SUPER_MAGIC: ::c_long = 0x00009fa2; pub const XENFS_SUPER_MAGIC: ::c_long = 0xabba1974; + pub const NSFS_MAGIC: ::c_long = 0x6e736673; } else if #[cfg(target_arch = "s390x")] { pub const ADFS_SUPER_MAGIC: ::c_uint = 0x0000adf5; pub const AFFS_SUPER_MAGIC: ::c_uint = 0x0000adff; @@ -1487,6 +1488,7 @@ cfg_if! { pub const UDF_SUPER_MAGIC: ::c_uint = 0x15013346; pub const USBDEVICE_SUPER_MAGIC: ::c_uint = 0x00009fa2; pub const XENFS_SUPER_MAGIC: ::c_uint = 0xabba1974; + pub const NSFS_MAGIC: ::c_uint = 0x6e736673; } } diff --git a/vendor/libc/src/unix/newlib/mod.rs b/vendor/libc/src/unix/newlib/mod.rs index 34a63a81a..1a694691a 100644 --- a/vendor/libc/src/unix/newlib/mod.rs +++ b/vendor/libc/src/unix/newlib/mod.rs @@ -41,7 +41,7 @@ pub type tcflag_t = ::c_uint; pub type useconds_t = u32; cfg_if! { - if #[cfg(target_os = "horizon")] { + if #[cfg(any(target_os = "horizon", all(target_os = "espidf", espidf_time64)))] { pub type time_t = ::c_longlong; } else { pub type time_t = i32; diff --git a/vendor/libc/src/unix/solarish/illumos.rs b/vendor/libc/src/unix/solarish/illumos.rs index c86c6d69d..7d491d382 100644 --- a/vendor/libc/src/unix/solarish/illumos.rs +++ b/vendor/libc/src/unix/solarish/illumos.rs @@ -42,6 +42,9 @@ pub const F_OFD_SETLKW: ::c_int = 49; pub const F_FLOCK: ::c_int = 53; pub const F_FLOCKW: ::c_int = 54; +pub const F_DUPFD_CLOEXEC: ::c_int = 37; +pub const F_DUP2FD_CLOEXEC: ::c_int = 36; + pub const FIL_ATTACH: ::c_int = 0x1; pub const FIL_DETACH: ::c_int = 0x2; pub const FIL_LIST: ::c_int = 0x3; @@ -51,6 +54,8 @@ pub const FILF_AUTO: ::c_int = 0x2; pub const FILF_BYPASS: ::c_int = 0x4; pub const SOL_FILTER: ::c_int = 0xfffc; +pub const MADV_PURGE: ::c_int = 9; + pub const MR_HDR_AOUT: ::c_uint = 0x3; pub const B1000000: ::speed_t = 24; diff --git a/vendor/libc/src/unix/solarish/mod.rs b/vendor/libc/src/unix/solarish/mod.rs index fef08d08f..c5da62be0 100644 --- a/vendor/libc/src/unix/solarish/mod.rs +++ b/vendor/libc/src/unix/solarish/mod.rs @@ -1327,7 +1327,6 @@ pub const F_LOCK: ::c_int = 1; pub const F_TEST: ::c_int = 3; pub const F_TLOCK: ::c_int = 2; pub const F_ULOCK: ::c_int = 0; -pub const F_DUPFD_CLOEXEC: ::c_int = 37; pub const F_SETLK: ::c_int = 6; pub const F_SETLKW: ::c_int = 7; pub const F_GETLK: ::c_int = 14; @@ -1441,6 +1440,7 @@ pub const MAP_RENAME: ::c_int = 0x20; pub const MAP_ALIGN: ::c_int = 0x200; pub const MAP_TEXT: ::c_int = 0x400; pub const MAP_INITDATA: ::c_int = 0x800; +pub const MAP_32BIT: ::c_int = 0x80; pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; pub const MCL_CURRENT: ::c_int = 0x0001; @@ -1601,7 +1601,6 @@ pub const NI_NUMERICSCOPE: ::c_uint = 0x0040; pub const F_DUPFD: ::c_int = 0; pub const F_DUP2FD: ::c_int = 9; -pub const F_DUP2FD_CLOEXEC: ::c_int = 36; pub const F_GETFD: ::c_int = 1; pub const F_SETFD: ::c_int = 2; pub const F_GETFL: ::c_int = 3; @@ -1685,6 +1684,9 @@ pub const MADV_SEQUENTIAL: ::c_int = 2; pub const MADV_WILLNEED: ::c_int = 3; pub const MADV_DONTNEED: ::c_int = 4; pub const MADV_FREE: ::c_int = 5; +pub const MADV_ACCESS_DEFAULT: ::c_int = 6; +pub const MADV_ACCESS_LWP: ::c_int = 7; +pub const MADV_ACCESS_MANY: ::c_int = 8; pub const AF_UNSPEC: ::c_int = 0; pub const AF_UNIX: ::c_int = 1; @@ -1894,6 +1896,14 @@ pub const IPC_RMID: ::c_int = 10; pub const IPC_SET: ::c_int = 11; pub const IPC_SEAT: ::c_int = 12; +// sys/shm.h +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_SHARE_MMU: ::c_int = 0o40000; +pub const SHM_PAGEABLE: ::c_int = 0o100000; + pub const SHUT_RD: ::c_int = 0; pub const SHUT_WR: ::c_int = 1; pub const SHUT_RDWR: ::c_int = 2; @@ -3135,6 +3145,8 @@ extern "C" { pub fn setpflags(flags: ::c_uint, value: ::c_uint) -> ::c_int; pub fn sysinfo(command: ::c_int, buf: *mut ::c_char, count: ::c_long) -> ::c_int; + + pub fn faccessat(fd: ::c_int, path: *const ::c_char, amode: ::c_int, flag: ::c_int) -> ::c_int; } #[link(name = "sendfile")] diff --git a/vendor/libc/src/unix/solarish/solaris.rs b/vendor/libc/src/unix/solarish/solaris.rs index 8ea070c6d..3fb166049 100644 --- a/vendor/libc/src/unix/solarish/solaris.rs +++ b/vendor/libc/src/unix/solarish/solaris.rs @@ -33,8 +33,13 @@ pub const AF_LOCAL: ::c_int = 0; pub const AF_FILE: ::c_int = 0; pub const TCP_KEEPIDLE: ::c_int = 0x1d; -pub const TCP_KEEPCNT: ::c_int = 0x1e; -pub const TCP_KEEPINTVL: ::c_int = 0x1f; +pub const TCP_KEEPINTVL: ::c_int = 0x1e; +pub const TCP_KEEPCNT: ::c_int = 0x1f; + +pub const F_DUPFD_CLOEXEC: ::c_int = 47; +pub const F_DUPFD_CLOFORK: ::c_int = 49; +pub const F_DUP2FD_CLOEXEC: ::c_int = 48; +pub const F_DUP2FD_CLOFORK: ::c_int = 50; extern "C" { pub fn fexecve( @@ -67,6 +72,8 @@ extern "C" { pub fn fattach(fildes: ::c_int, path: *const ::c_char) -> ::c_int; pub fn pthread_getattr_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + + pub fn euidaccess(path: *const ::c_char, amode: ::c_int) -> ::c_int; } s_no_extra_traits! { diff --git a/vendor/libc/src/unix/solarish/x86_64.rs b/vendor/libc/src/unix/solarish/x86_64.rs index 5f75bdb79..bca552f37 100644 --- a/vendor/libc/src/unix/solarish/x86_64.rs +++ b/vendor/libc/src/unix/solarish/x86_64.rs @@ -157,3 +157,34 @@ cfg_if! { } } + +// sys/regset.h + +pub const REG_GSBASE: ::c_int = 27; +pub const REG_FSBASE: ::c_int = 26; +pub const REG_DS: ::c_int = 25; +pub const REG_ES: ::c_int = 24; +pub const REG_GS: ::c_int = 23; +pub const REG_FS: ::c_int = 22; +pub const REG_SS: ::c_int = 21; +pub const REG_RSP: ::c_int = 20; +pub const REG_RFL: ::c_int = 19; +pub const REG_CS: ::c_int = 18; +pub const REG_RIP: ::c_int = 17; +pub const REG_ERR: ::c_int = 16; +pub const REG_TRAPNO: ::c_int = 15; +pub const REG_RAX: ::c_int = 14; +pub const REG_RCX: ::c_int = 13; +pub const REG_RDX: ::c_int = 12; +pub const REG_RBX: ::c_int = 11; +pub const REG_RBP: ::c_int = 10; +pub const REG_RSI: ::c_int = 9; +pub const REG_RDI: ::c_int = 8; +pub const REG_R8: ::c_int = 7; +pub const REG_R9: ::c_int = 6; +pub const REG_R10: ::c_int = 5; +pub const REG_R11: ::c_int = 4; +pub const REG_R12: ::c_int = 3; +pub const REG_R13: ::c_int = 2; +pub const REG_R14: ::c_int = 1; +pub const REG_R15: ::c_int = 0; diff --git a/vendor/lock_api/.cargo-checksum.json b/vendor/lock_api/.cargo-checksum.json index ceb83ada3..cf8df26fa 100644 --- a/vendor/lock_api/.cargo-checksum.json +++ b/vendor/lock_api/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f0fb3e65549d1353e2e199977db7825c29721bbeb71dee9bb3905437dd444dce","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","build.rs":"af84139c71d151adead0b4398c394a7dd16087bb2db44b14a0ed970ce868a6c6","src/lib.rs":"7b67c3b69c1b5e97248afe0f6c3bc353c793ed1ce4a5d5177e63f3f05d79c63b","src/mutex.rs":"dc4131ebf73e0474948d1849934ad5156e4a3dbd55f6881e60fd6c0acb6aa861","src/remutex.rs":"659454e66fa72e678e0aa1b83151c81c90321368dc6f4c31315230b969d4936e","src/rwlock.rs":"4f35072ca1fb476089d1548c40af775564bb7e763f86ec41a2190f8c659593cc"},"package":"327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"} \ No newline at end of file +{"files":{"Cargo.toml":"15453a84e25ac6ed84c95e11e71d9bee5b360b6dc787a433b8416b91bf8e216c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","build.rs":"af84139c71d151adead0b4398c394a7dd16087bb2db44b14a0ed970ce868a6c6","src/lib.rs":"7b67c3b69c1b5e97248afe0f6c3bc353c793ed1ce4a5d5177e63f3f05d79c63b","src/mutex.rs":"f5627b1269a9b0d116507af19b8619b9922b95b73a84ab5be3134620c97caadb","src/remutex.rs":"4fa5f0448591a32ac37f2cf9af89813f32e415d2a1ca426670a0cdaccbca66aa","src/rwlock.rs":"9160cbada7e3179bd8ec13769761437e90bfb616316947dc0cc5959f0bcdc5b9"},"package":"435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"} \ No newline at end of file diff --git a/vendor/lock_api/Cargo.toml b/vendor/lock_api/Cargo.toml index c1ebdb7b7..b1ff8c4db 100644 --- a/vendor/lock_api/Cargo.toml +++ b/vendor/lock_api/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2018" name = "lock_api" -version = "0.4.7" +version = "0.4.9" authors = ["Amanieu d'Antras "] description = "Wrappers to create fully-featured Mutex and RwLock types. Compatible with no_std." keywords = [ diff --git a/vendor/lock_api/src/mutex.rs b/vendor/lock_api/src/mutex.rs index 4e1b879e5..c97e5430b 100644 --- a/vendor/lock_api/src/mutex.rs +++ b/vendor/lock_api/src/mutex.rs @@ -681,15 +681,38 @@ unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<' #[must_use = "if unused the Mutex will immediately unlock"] pub struct ArcMutexGuard { mutex: Arc>, - marker: PhantomData, + marker: PhantomData<*const ()>, +} + +#[cfg(feature = "arc_lock")] +unsafe impl Send for ArcMutexGuard where + R::GuardMarker: Send +{ +} +#[cfg(feature = "arc_lock")] +unsafe impl Sync for ArcMutexGuard where + R::GuardMarker: Sync +{ } #[cfg(feature = "arc_lock")] impl ArcMutexGuard { /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`. #[inline] - pub fn mutex(&self) -> &Arc> { - &self.mutex + pub fn mutex(s: &Self) -> &Arc> { + &s.mutex + } + + /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`]. + #[inline] + pub fn into_arc(s: Self) -> Arc> { + // Safety: Skip our Drop impl and manually unlock the mutex. + let arc = unsafe { ptr::read(&s.mutex) }; + mem::forget(s); + unsafe { + arc.raw.unlock(); + } + arc } /// Temporarily unlocks the mutex to execute the given function. diff --git a/vendor/lock_api/src/remutex.rs b/vendor/lock_api/src/remutex.rs index fa0e934d1..3e2010f2b 100644 --- a/vendor/lock_api/src/remutex.rs +++ b/vendor/lock_api/src/remutex.rs @@ -646,7 +646,7 @@ impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> ReentrantMutexGu /// in already locked the mutex. /// /// This is an associated function that needs to be - /// used as `ReentrantMutexGuard::map(...)`. A method would interfere with methods of + /// used as `ReentrantMutexGuard::try_map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn try_map( @@ -654,10 +654,10 @@ impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> ReentrantMutexGu f: F, ) -> Result, Self> where - F: FnOnce(&mut T) -> Option<&mut U>, + F: FnOnce(&T) -> Option<&U>, { let raw = &s.remutex.raw; - let data = match f(unsafe { &mut *s.remutex.data.get() }) { + let data = match f(unsafe { &*s.remutex.data.get() }) { Some(data) => data, None => return Err(s), }; @@ -942,7 +942,7 @@ impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> /// in already locked the mutex. /// /// This is an associated function that needs to be - /// used as `MappedReentrantMutexGuard::map(...)`. A method would interfere with methods of + /// used as `MappedReentrantMutexGuard::try_map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn try_map( diff --git a/vendor/lock_api/src/rwlock.rs b/vendor/lock_api/src/rwlock.rs index e947f1ec0..c972fb6c6 100644 --- a/vendor/lock_api/src/rwlock.rs +++ b/vendor/lock_api/src/rwlock.rs @@ -1218,13 +1218,13 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> { } /// Attempts to make a new `MappedRwLockReadGuard` for a component of the - /// locked data. The original guard is return if the closure returns `None`. + /// locked data. Returns the original guard if the closure returns `None`. /// /// This operation cannot fail as the `RwLockReadGuard` passed /// in already locked the data. /// /// This is an associated function that needs to be - /// used as `RwLockReadGuard::map(...)`. A method would interfere with methods of + /// used as `RwLockReadGuard::try_map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn try_map(s: Self, f: F) -> Result, Self> @@ -1512,7 +1512,7 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { /// in already locked the data. /// /// This is an associated function that needs to be - /// used as `RwLockWriteGuard::map(...)`. A method would interfere with methods of + /// used as `RwLockWriteGuard::try_map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn try_map(s: Self, f: F) -> Result, Self> @@ -2374,7 +2374,7 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> { /// in already locked the data. /// /// This is an associated function that needs to be - /// used as `MappedRwLockReadGuard::map(...)`. A method would interfere with methods of + /// used as `MappedRwLockReadGuard::try_map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn try_map(s: Self, f: F) -> Result, Self> @@ -2512,7 +2512,7 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> { /// in already locked the data. /// /// This is an associated function that needs to be - /// used as `MappedRwLockWriteGuard::map(...)`. A method would interfere with methods of + /// used as `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn try_map(s: Self, f: F) -> Result, Self> diff --git a/vendor/matches/.cargo-checksum.json b/vendor/matches/.cargo-checksum.json deleted file mode 100644 index 65871b7ff..000000000 --- a/vendor/matches/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"194024a82bba1c84226ac827330511fba74474a7914b1319e6700285c15f5812","LICENSE":"d7b49708075b5f43f8e108464f1970c8c66fa8b6afce4f9c944da3af77cc1460","lib.rs":"9f4187510972f5fc356ca60d19daa0e69643dd6b530edf7c928cbd75a2b990c5","tests/macro_use_one.rs":"4f599fae16f1aef369050bf0ad74cbefec06c430b29e0c9ab0811ac9592e997a","tests/use_star.rs":"39a23b8002544f65e7a896e2cefe8e0af7404151fa65d327e748f5c1101badf8"},"package":"a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"} \ No newline at end of file diff --git a/vendor/matches/Cargo.toml b/vendor/matches/Cargo.toml deleted file mode 100644 index 57a249a40..000000000 --- a/vendor/matches/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -# 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 believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "matches" -version = "0.1.9" -authors = ["Simon Sapin "] -description = "A macro to evaluate, as a boolean, whether an expression matches a pattern." -documentation = "https://docs.rs/matches/" -license = "MIT" -repository = "https://github.com/SimonSapin/rust-std-candidates" - -[lib] -name = "matches" -path = "lib.rs" diff --git a/vendor/matches/LICENSE b/vendor/matches/LICENSE deleted file mode 100644 index a7b759a49..000000000 --- a/vendor/matches/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2014-2016 Simon Sapin - -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. diff --git a/vendor/matches/lib.rs b/vendor/matches/lib.rs deleted file mode 100644 index 3bcd6e2fe..000000000 --- a/vendor/matches/lib.rs +++ /dev/null @@ -1,128 +0,0 @@ -#![no_std] - -/// Check if an expression matches a refutable pattern. -/// -/// Syntax: `matches!(` *expression* `,` *pattern* `)` -/// -/// Return a boolean, true if the expression matches the pattern, false otherwise. -/// -/// # Examples -/// -/// ``` -/// #[macro_use] -/// extern crate matches; -/// -/// pub enum Foo { -/// A, -/// B(T), -/// } -/// -/// impl Foo { -/// pub fn is_a(&self) -> bool { -/// matches!(*self, Foo::A) -/// } -/// -/// pub fn is_b(&self) -> bool { -/// matches!(*self, Foo::B(_)) -/// } -/// } -/// -/// # fn main() { } -/// ``` -#[macro_export] -macro_rules! matches { - ($expression:expr, $($pattern:tt)+) => { - match $expression { - $($pattern)+ => true, - _ => false - } - } -} - -/// Assert that an expression matches a refutable pattern. -/// -/// Syntax: `assert_matches!(` *expression* `,` *pattern* `)` -/// -/// Panic with a message that shows the expression if it does not match the -/// pattern. -/// -/// # Examples -/// -/// ``` -/// #[macro_use] -/// extern crate matches; -/// -/// fn main() { -/// let data = [1, 2, 3]; -/// assert_matches!(data.get(1), Some(_)); -/// } -/// ``` -#[macro_export] -macro_rules! assert_matches { - ($expression:expr, $($pattern:tt)+) => { - match $expression { - $($pattern)+ => (), - ref e => panic!("assertion failed: `{:?}` does not match `{}`", e, stringify!($($pattern)+)), - } - } -} - -/// Assert that an expression matches a refutable pattern using debug assertions. -/// -/// Syntax: `debug_assert_matches!(` *expression* `,` *pattern* `)` -/// -/// If debug assertions are enabled, panic with a message that shows the -/// expression if it does not match the pattern. -/// -/// When debug assertions are not enabled, this macro does nothing. -/// -/// # Examples -/// -/// ``` -/// #[macro_use] -/// extern crate matches; -/// -/// fn main() { -/// let data = [1, 2, 3]; -/// debug_assert_matches!(data.get(1), Some(_)); -/// } -/// ``` -#[macro_export] -macro_rules! debug_assert_matches { - ($expression:expr, $($pattern:tt)+) => { - if cfg!(debug_assertions) { - match $expression { - $($pattern)+ => (), - ref e => panic!("assertion failed: `{:?}` does not match `{}`", e, stringify!($($pattern)+)), - } - } - } -} - -#[test] -fn matches_works() { - let foo = Some("-12"); - assert!(matches!(foo, Some(bar) if - matches!(bar.as_bytes()[0], b'+' | b'-') && - matches!(bar.as_bytes()[1], b'0'...b'9') - )); -} - -#[test] -fn assert_matches_works() { - let foo = Some("-12"); - assert_matches!(foo, Some(bar) if - matches!(bar.as_bytes()[0], b'+' | b'-') && - matches!(bar.as_bytes()[1], b'0'...b'9') - ); -} - -#[test] -#[should_panic(expected = "assertion failed: `Some(\"-AB\")` does not match ")] -fn assert_matches_panics() { - let foo = Some("-AB"); - assert_matches!(foo, Some(bar) if - matches!(bar.as_bytes()[0], b'+' | b'-') && - matches!(bar.as_bytes()[1], b'0'...b'9') - ); -} diff --git a/vendor/matches/tests/macro_use_one.rs b/vendor/matches/tests/macro_use_one.rs deleted file mode 100644 index a527a89ce..000000000 --- a/vendor/matches/tests/macro_use_one.rs +++ /dev/null @@ -1,11 +0,0 @@ -// https://github.com/SimonSapin/rust-std-candidates/issues/12 -#[macro_use(matches)] extern crate matches; - -#[test] -fn matches_works() { - let foo = Some("-12"); - assert!(matches!(foo, Some(bar) if - matches!(bar.as_bytes()[0], b'+' | b'-') && - matches!(bar.as_bytes()[1], b'0'...b'9') - )); -} diff --git a/vendor/matches/tests/use_star.rs b/vendor/matches/tests/use_star.rs deleted file mode 100644 index 58a670b93..000000000 --- a/vendor/matches/tests/use_star.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! https://github.com/SimonSapin/rust-std-candidates/issues/22 - -extern crate matches; - -use matches::*; - -#[test] -fn test_assert_matches() { - assert_matches!(4, 4) -} diff --git a/vendor/miniz_oxide/.cargo-checksum.json b/vendor/miniz_oxide/.cargo-checksum.json index a30f6d5ad..16e89c510 100644 --- a/vendor/miniz_oxide/.cargo-checksum.json +++ b/vendor/miniz_oxide/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"bdec209313b683bf315ff5134fde0322e46a27ae8ec9de303ffa22cc67826365","LICENSE":"e190940e8ad3cdd4fca962a6508ed6865d589d314b1cb055f86000e124b88d8d","LICENSE-APACHE.md":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT.md":"e190940e8ad3cdd4fca962a6508ed6865d589d314b1cb055f86000e124b88d8d","LICENSE-ZLIB.md":"c89bcc058da12a0fb24402b8ea4542a21515dd1da2e8c67bba4ed9bd269f1c96","Readme.md":"b6a6668b073a3356748b642ce51b31233b6408ffcca3e52801ef473a9f7925c7","src/deflate/buffer.rs":"76bcca4e79bef412eeebdd06d2d0a4348ed9ee17edbdaa6d451d8bf03b1cde85","src/deflate/core.rs":"8087c155cb47f57a9747565857dcef59fff0a7a499abbfdb0c60e694d3234db8","src/deflate/mod.rs":"8ade5b9683b8d728fe5e8f5c23e0630165bfdbef3e56a18b1b729f9bbd4a4b1d","src/deflate/stream.rs":"016c82b09a989492c8c8ea89027d339fcf59a5ca2155e7026ac094ca74344712","src/inflate/core.rs":"49bd596d5255ac88b486f6f978ab7b26663cdab01a6ebaa41bf4559f12b0fed8","src/inflate/mod.rs":"8b65692f1bb71b4973df8da7ca9ffc8c4e4e439f6b5993e16a96d20dc3a08f52","src/inflate/output_buffer.rs":"1ae90d03ba8c9d667fe248b6066731774afdf93cc79cd3bf90e0711b963b0b72","src/inflate/stream.rs":"f82c44ffdff054aff05307ed5709e432b54d5997bb4bbfff8f760171c33c76c3","src/lib.rs":"a9d6a889415ffe3d800c8516fb0ac0bae3585010966d1fdf3b06a85330c36854","src/shared.rs":"a8c47fcb566591e39fcd50d44f3b4d0f567318b8ca36c8d732ee0d8c99a14906"},"package":"6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"} \ No newline at end of file +{"files":{"Cargo.toml":"14ec71e104b90decb8b84170557138a51cc39a8b83b721d74eb476fb13f6bdd2","LICENSE":"e190940e8ad3cdd4fca962a6508ed6865d589d314b1cb055f86000e124b88d8d","LICENSE-APACHE.md":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT.md":"e190940e8ad3cdd4fca962a6508ed6865d589d314b1cb055f86000e124b88d8d","LICENSE-ZLIB.md":"c89bcc058da12a0fb24402b8ea4542a21515dd1da2e8c67bba4ed9bd269f1c96","Readme.md":"b6a6668b073a3356748b642ce51b31233b6408ffcca3e52801ef473a9f7925c7","src/deflate/buffer.rs":"76bcca4e79bef412eeebdd06d2d0a4348ed9ee17edbdaa6d451d8bf03b1cde85","src/deflate/core.rs":"8087c155cb47f57a9747565857dcef59fff0a7a499abbfdb0c60e694d3234db8","src/deflate/mod.rs":"8ade5b9683b8d728fe5e8f5c23e0630165bfdbef3e56a18b1b729f9bbd4a4b1d","src/deflate/stream.rs":"016c82b09a989492c8c8ea89027d339fcf59a5ca2155e7026ac094ca74344712","src/inflate/core.rs":"49bd596d5255ac88b486f6f978ab7b26663cdab01a6ebaa41bf4559f12b0fed8","src/inflate/mod.rs":"690a8cd50a7da88672b750bb2c62d52d2a58efa41e6ddb2084589a17095cb875","src/inflate/output_buffer.rs":"1ae90d03ba8c9d667fe248b6066731774afdf93cc79cd3bf90e0711b963b0b72","src/inflate/stream.rs":"f82c44ffdff054aff05307ed5709e432b54d5997bb4bbfff8f760171c33c76c3","src/lib.rs":"a9d6a889415ffe3d800c8516fb0ac0bae3585010966d1fdf3b06a85330c36854","src/shared.rs":"a8c47fcb566591e39fcd50d44f3b4d0f567318b8ca36c8d732ee0d8c99a14906"},"package":"96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"} \ No newline at end of file diff --git a/vendor/miniz_oxide/Cargo.toml b/vendor/miniz_oxide/Cargo.toml index 7546128ce..7fa9d3e06 100644 --- a/vendor/miniz_oxide/Cargo.toml +++ b/vendor/miniz_oxide/Cargo.toml @@ -12,20 +12,32 @@ [package] edition = "2018" name = "miniz_oxide" -version = "0.5.3" -authors = ["Frommi ", "oyvindln "] -exclude = ["benches/*", "tests/*"] +version = "0.5.4" +authors = [ + "Frommi ", + "oyvindln ", +] +exclude = [ + "benches/*", + "tests/*", +] description = "DEFLATE compression and decompression library rewritten in Rust based on miniz" homepage = "https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide" documentation = "https://docs.rs/miniz_oxide" readme = "Readme.md" -keywords = ["zlib", "miniz", "deflate", "encoding"] +keywords = [ + "zlib", + "miniz", + "deflate", + "encoding", +] categories = ["compression"] license = "MIT OR Zlib OR Apache-2.0" repository = "https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide" [lib] name = "miniz_oxide" + [dependencies.adler] version = "1.0" default-features = false @@ -51,5 +63,10 @@ default-features = false [features] default = [] -rustc-dep-of-std = ["core", "alloc", "compiler_builtins", "adler/rustc-dep-of-std"] +rustc-dep-of-std = [ + "core", + "alloc", + "compiler_builtins", + "adler/rustc-dep-of-std", +] simd = ["simd-adler32"] diff --git a/vendor/miniz_oxide/src/inflate/mod.rs b/vendor/miniz_oxide/src/inflate/mod.rs index 535392327..03b9dc988 100644 --- a/vendor/miniz_oxide/src/inflate/mod.rs +++ b/vendor/miniz_oxide/src/inflate/mod.rs @@ -151,14 +151,12 @@ fn decompress_to_vec_inner( } TINFLStatus::HasMoreOutput => { - // We need more space, so check if we can resize the buffer and do it. - let new_len = ret - .len() - .checked_add(out_pos) - .ok_or(TINFLStatus::HasMoreOutput)?; - if new_len > max_output_size { + // if the buffer has already reached the size limit, return an error + if ret.len() >= max_output_size { return Err(TINFLStatus::HasMoreOutput); - }; + } + // calculate the new length, capped at `max_output_size` + let new_len = ret.len().saturating_mul(2).min(max_output_size); ret.resize(new_len, 0); } diff --git a/vendor/once_cell/.cargo-checksum.json b/vendor/once_cell/.cargo-checksum.json index 9dffae3ad..6f8adad72 100644 --- a/vendor/once_cell/.cargo-checksum.json +++ b/vendor/once_cell/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"1638f5757551c399130656e1daab76b0322538923a791bf39e9ec247257daf79","Cargo.lock":"417a830ee5d5359f413fdf973391bf137de7ea8b075d83dcf798f1d3de36cfda","Cargo.toml":"d083a23d498e2dbf1cb3f249bdade38715b3cb237a38b733df79f20824eec4f7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"813d262a320611ba874c4b2488256bdb2b4073649616a1471b389d464a704301","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"90541b093ed1d1cbb73f4097ff02cf80657e28264d281d6a31d96a708fdfea90","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_pl.rs":"1959494004fb0ee7443e97c4abd8be69d7173fe2b66f8fff0bca7b5c8e512525","src/imp_std.rs":"33be3a0df87e092abd68280dc72d50534d273d17eb86940e7ba2b8a45da78a70","src/lib.rs":"5320847175dc279e7abd2d98e17ab8d05b2eb7e383a4f249623b71a5209f2346","src/race.rs":"5a19afca4b5510d09ca7317b96f5642725c58b0969b2bdeb7275ed674d061e5d","tests/it.rs":"501c4ab3f4e718fa555707e9d32f3688c05e4ef8ea967e72e1c99da6bb06a0ad"},"package":"074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"} \ No newline at end of file +{"files":{"CHANGELOG.md":"f6198c1a83a8245a7b2ab062a316f3f97dfba190ac1d6bb47949e9c0cf4dac80","Cargo.lock":"e69c2663fe7efb3a4e463af446fa1367bd8e008100500137052ef15b84b02ebc","Cargo.toml":"d08e0411e5eda265a3359939f1fb646dff29ca38896222ffe0900b0af8e3ae70","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"813d262a320611ba874c4b2488256bdb2b4073649616a1471b389d464a704301","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_pl.rs":"1959494004fb0ee7443e97c4abd8be69d7173fe2b66f8fff0bca7b5c8e512525","src/imp_std.rs":"33be3a0df87e092abd68280dc72d50534d273d17eb86940e7ba2b8a45da78a70","src/lib.rs":"88d2f7a63bd63f630733c86ea035b53e53f2f8d3c44f1025bc9bbe5ceaa7375f","src/race.rs":"5a19afca4b5510d09ca7317b96f5642725c58b0969b2bdeb7275ed674d061e5d","tests/it.rs":"4448a74a9898babfb943bae42ebfe3b07ec2b002ea39712127159955015d33b4"},"package":"e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"} \ No newline at end of file diff --git a/vendor/once_cell/CHANGELOG.md b/vendor/once_cell/CHANGELOG.md index ffb5b1df3..005ce6951 100644 --- a/vendor/once_cell/CHANGELOG.md +++ b/vendor/once_cell/CHANGELOG.md @@ -4,6 +4,18 @@ - +## 1.15.0 + +- Increase minimal supported Rust version to 1.56.0. +- Implement `UnwindSafe` even if the `std` feature is disabled. + +## 1.14.0 + +- Add extension to `unsync` and `sync` `Lazy` mut API: + - `force_mut` + - `get_mut` + + ## 1.13.1 - Make implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). diff --git a/vendor/once_cell/Cargo.lock b/vendor/once_cell/Cargo.lock index 2e981967f..83f83681a 100644 --- a/vendor/once_cell/Cargo.lock +++ b/vendor/once_cell/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.4" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -34,9 +34,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "critical-section" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce181dda5a65c00fcbce2b9d44ad9be001202a54fb321865ed273ac39aa8ccbe" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] name = "crossbeam-utils" @@ -45,36 +45,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if", - "once_cell 1.13.0", + "once_cell 1.14.0", ] [[package]] name = "lazy_static" -version = "1.0.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.131" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "memchr" -version = "2.2.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "once_cell" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "once_cell" -version = "1.13.1" +version = "1.15.0" dependencies = [ "atomic-polyfill", "crossbeam-utils", @@ -107,25 +107,20 @@ dependencies = [ [[package]] name = "regex" -version = "1.2.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", - "utf8-ranges", ] [[package]] name = "regex-syntax" -version = "0.6.9" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaca88e749e19dffb60f77b55e5d87a872fac7e9e48598f7cf93b2d8c047b0a" -dependencies = [ - "ucd-util", -] +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "smallvec" @@ -133,27 +128,6 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "ucd-util" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3bf5cdf1df6b578c0947a94d4740bbb2b2afd1b898e33df1ff07b555a335e4" - -[[package]] -name = "utf8-ranges" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" - [[package]] name = "windows-sys" version = "0.36.1" diff --git a/vendor/once_cell/Cargo.toml b/vendor/once_cell/Cargo.toml index e8222f163..bde77ee9d 100644 --- a/vendor/once_cell/Cargo.toml +++ b/vendor/once_cell/Cargo.toml @@ -10,9 +10,10 @@ # See Cargo.toml.orig for the original contents. [package] -edition = "2018" +edition = "2021" +rust-version = "1.56" name = "once_cell" -version = "1.13.1" +version = "1.15.0" authors = ["Aleksey Kladov "] exclude = [ "*.png", @@ -33,6 +34,7 @@ categories = [ ] license = "MIT OR Apache-2.0" repository = "https://github.com/matklad/once_cell" +resolver = "2" [package.metadata.docs.rs] all-features = true diff --git a/vendor/once_cell/examples/lazy_static.rs b/vendor/once_cell/examples/lazy_static.rs index f0505609b..3cdb19f2a 100644 --- a/vendor/once_cell/examples/lazy_static.rs +++ b/vendor/once_cell/examples/lazy_static.rs @@ -32,5 +32,5 @@ fn main() { // The same works for function-style: assert_eq!(hashmap().get(&0), Some(&"foo")); - assert_eq!(hashmap().get(&0), Some(&"bar")); + assert_eq!(hashmap().get(&1), Some(&"bar")); } diff --git a/vendor/once_cell/src/lib.rs b/vendor/once_cell/src/lib.rs index 70f08dea6..6de1e3eeb 100644 --- a/vendor/once_cell/src/lib.rs +++ b/vendor/once_cell/src/lib.rs @@ -267,7 +267,7 @@ //! //! # Minimum Supported `rustc` Version //! -//! This crate's minimum supported `rustc` version is `1.36.0`. +//! This crate's minimum supported `rustc` version is `1.56.0`. //! //! If only the `std` feature is enabled, MSRV will be updated conservatively. //! When using other features, like `parking_lot`, MSRV might be updated more frequently, up to the latest stable. @@ -348,11 +348,9 @@ pub mod unsync { cell::{Cell, UnsafeCell}, fmt, hint, mem, ops::{Deref, DerefMut}, + panic::{RefUnwindSafe, UnwindSafe}, }; - #[cfg(feature = "std")] - use std::panic::{RefUnwindSafe, UnwindSafe}; - /// A cell which can be written to only once. It is not thread safe. /// /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&` @@ -382,9 +380,7 @@ pub mod unsync { // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`, // by initializing the cell in closure and extracting the value in the // `Drop`. - #[cfg(feature = "std")] impl RefUnwindSafe for OnceCell {} - #[cfg(feature = "std")] impl UnwindSafe for OnceCell {} impl Default for OnceCell { @@ -680,7 +676,6 @@ pub mod unsync { init: Cell>, } - #[cfg(feature = "std")] impl RefUnwindSafe for Lazy where OnceCell: RefUnwindSafe {} impl fmt::Debug for Lazy { @@ -742,6 +737,25 @@ pub mod unsync { }) } + /// Forces the evaluation of this lazy value and returns a mutable reference to + /// the result. + /// + /// This is equivalent to the `DerefMut` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force_mut(&mut lazy), &92); + /// assert_eq!(*lazy, 92); + /// ``` + pub fn force_mut(this: &mut Lazy) -> &mut T { + Self::force(this); + Self::get_mut(this).unwrap_or_else(|| unreachable!()) + } + /// Gets the reference to the result of this lazy value if /// it was initialized, otherwise returns `None`. /// @@ -758,6 +772,23 @@ pub mod unsync { pub fn get(this: &Lazy) -> Option<&T> { this.cell.get() } + + /// Gets the mutable reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get_mut(&mut lazy), None); + /// assert_eq!(*lazy, 92); + /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92)); + /// ``` + pub fn get_mut(this: &mut Lazy) -> Option<&mut T> { + this.cell.get_mut() + } } impl T> Deref for Lazy { @@ -1189,7 +1220,6 @@ pub mod sync { unsafe impl Sync for Lazy where OnceCell: Sync {} // auto-derived `Send` impl is OK. - #[cfg(feature = "std")] impl RefUnwindSafe for Lazy where OnceCell: RefUnwindSafe {} impl Lazy { @@ -1232,6 +1262,23 @@ pub mod sync { }) } + /// Forces the evaluation of this lazy value and + /// returns a mutable reference to the result. This is equivalent + /// to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92); + /// ``` + pub fn force_mut(this: &mut Lazy) -> &mut T { + Self::force(this); + Self::get_mut(this).unwrap_or_else(|| unreachable!()) + } + /// Gets the reference to the result of this lazy value if /// it was initialized, otherwise returns `None`. /// @@ -1248,6 +1295,23 @@ pub mod sync { pub fn get(this: &Lazy) -> Option<&T> { this.cell.get() } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get_mut(&mut lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92)); + /// ``` + pub fn get_mut(this: &mut Lazy) -> Option<&mut T> { + this.cell.get_mut() + } } impl T> Deref for Lazy { diff --git a/vendor/once_cell/tests/it.rs b/vendor/once_cell/tests/it.rs index 476f14bb0..410b93b64 100644 --- a/vendor/once_cell/tests/it.rs +++ b/vendor/once_cell/tests/it.rs @@ -137,6 +137,41 @@ mod unsync { assert_eq!(called.get(), 1); } + #[test] + fn lazy_force_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + assert_eq!(called.get(), 0); + let v = Lazy::force_mut(&mut x); + assert_eq!(called.get(), 1); + + *v /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); + } + + #[test] + fn lazy_get_mut() { + let called = Cell::new(0); + let mut x: Lazy = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + assert_eq!(*x, 92); + + let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); + assert_eq!(called.get(), 1); + + *mut_ref /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); + } + #[test] fn lazy_default() { static CALLED: AtomicUsize = AtomicUsize::new(0); diff --git a/vendor/percent-encoding/.cargo-checksum.json b/vendor/percent-encoding/.cargo-checksum.json index 7576f0fde..e37d79346 100644 --- a/vendor/percent-encoding/.cargo-checksum.json +++ b/vendor/percent-encoding/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"dd59f4e6c033f011625ede444aa27fc8df4be53297af238b4f76d05144de5878","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","lib.rs":"b9dd3a27fb0f56aebe3c4c411ea768a106a54e480ac08d9023c35bbba0bdcbdc"},"package":"d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"} \ No newline at end of file +{"files":{"Cargo.toml":"7330cca9fe75c0f7cadf87d42f1af587e57d7f3e90efad7b4476d8d78580e435","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"76e972ac0f4ddb116e86e10100132a783931a596e7b9872eaa31be15cd4d751d","src/lib.rs":"5eafa40dda1d5de9770181b836c37b078f790ccdee4f461d4601fc5bc17716b8"},"package":"478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"} \ No newline at end of file diff --git a/vendor/percent-encoding/Cargo.toml b/vendor/percent-encoding/Cargo.toml index b51d1d449..53d0b6307 100644 --- a/vendor/percent-encoding/Cargo.toml +++ b/vendor/percent-encoding/Cargo.toml @@ -3,21 +3,22 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" +rust-version = "1.51" name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" authors = ["The rust-url developers"] description = "Percent encoding and decoding" -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/servo/rust-url/" -[lib] -path = "lib.rs" -test = false +[features] +alloc = [] +default = ["alloc"] diff --git a/vendor/percent-encoding/LICENSE-MIT b/vendor/percent-encoding/LICENSE-MIT index 24de6b418..51d5dc7eb 100644 --- a/vendor/percent-encoding/LICENSE-MIT +++ b/vendor/percent-encoding/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2013-2016 The rust-url developers +Copyright (c) 2013-2022 The rust-url developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/vendor/percent-encoding/lib.rs b/vendor/percent-encoding/lib.rs deleted file mode 100644 index 27eaf6740..000000000 --- a/vendor/percent-encoding/lib.rs +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright 2013-2016 The rust-url developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! URLs use special chacters to indicate the parts of the request. -//! For example, a `?` question mark marks the end of a path and the start of a query string. -//! In order for that character to exist inside a path, it needs to be encoded differently. -//! -//! Percent encoding replaces reserved characters with the `%` escape character -//! followed by a byte value as two hexadecimal digits. -//! For example, an ASCII space is replaced with `%20`. -//! -//! When encoding, the set of characters that can (and should, for readability) be left alone -//! depends on the context. -//! The `?` question mark mentioned above is not a separator when used literally -//! inside of a query string, and therefore does not need to be encoded. -//! The [`AsciiSet`] parameter of [`percent_encode`] and [`utf8_percent_encode`] -//! lets callers configure this. -//! -//! This crate delibarately does not provide many different sets. -//! Users should consider in what context the encoded string will be used, -//! real relevant specifications, and define their own set. -//! This is done by using the `add` method of an existing set. -//! -//! # Examples -//! -//! ``` -//! use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; -//! -//! /// https://url.spec.whatwg.org/#fragment-percent-encode-set -//! const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); -//! -//! assert_eq!(utf8_percent_encode("foo ", FRAGMENT).to_string(), "foo%20%3Cbar%3E"); -//! ``` - -use std::borrow::Cow; -use std::fmt; -use std::slice; -use std::str; - -/// Represents a set of characters or bytes in the ASCII range. -/// -/// This used in [`percent_encode`] and [`utf8_percent_encode`]. -/// This is simlar to [percent-encode sets](https://url.spec.whatwg.org/#percent-encoded-bytes). -/// -/// Use the `add` method of an existing set to define a new set. For example: -/// -/// ``` -/// use percent_encoding::{AsciiSet, CONTROLS}; -/// -/// /// https://url.spec.whatwg.org/#fragment-percent-encode-set -/// const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); -/// ``` -pub struct AsciiSet { - mask: [Chunk; ASCII_RANGE_LEN / BITS_PER_CHUNK], -} - -type Chunk = u32; - -const ASCII_RANGE_LEN: usize = 0x80; - -const BITS_PER_CHUNK: usize = 8 * std::mem::size_of::(); - -impl AsciiSet { - /// Called with UTF-8 bytes rather than code points. - /// Not used for non-ASCII bytes. - const fn contains(&self, byte: u8) -> bool { - let chunk = self.mask[byte as usize / BITS_PER_CHUNK]; - let mask = 1 << (byte as usize % BITS_PER_CHUNK); - (chunk & mask) != 0 - } - - fn should_percent_encode(&self, byte: u8) -> bool { - !byte.is_ascii() || self.contains(byte) - } - - pub const fn add(&self, byte: u8) -> Self { - let mut mask = self.mask; - mask[byte as usize / BITS_PER_CHUNK] |= 1 << (byte as usize % BITS_PER_CHUNK); - AsciiSet { mask } - } - - pub const fn remove(&self, byte: u8) -> Self { - let mut mask = self.mask; - mask[byte as usize / BITS_PER_CHUNK] &= !(1 << (byte as usize % BITS_PER_CHUNK)); - AsciiSet { mask } - } -} - -/// The set of 0x00 to 0x1F (C0 controls), and 0x7F (DEL). -/// -/// Note that this includes the newline and tab characters, but not the space 0x20. -/// -/// -pub const CONTROLS: &AsciiSet = &AsciiSet { - mask: [ - !0_u32, // C0: 0x00 to 0x1F (32 bits set) - 0, - 0, - 1 << (0x7F_u32 % 32), // DEL: 0x7F (one bit set) - ], -}; - -macro_rules! static_assert { - ($( $bool: expr, )+) => { - fn _static_assert() { - $( - let _ = std::mem::transmute::<[u8; $bool as usize], u8>; - )+ - } - } -} - -static_assert! { - CONTROLS.contains(0x00), - CONTROLS.contains(0x1F), - !CONTROLS.contains(0x20), - !CONTROLS.contains(0x7E), - CONTROLS.contains(0x7F), -} - -/// Everything that is not an ASCII letter or digit. -/// -/// This is probably more eager than necessary in any context. -pub const NON_ALPHANUMERIC: &AsciiSet = &CONTROLS - .add(b' ') - .add(b'!') - .add(b'"') - .add(b'#') - .add(b'$') - .add(b'%') - .add(b'&') - .add(b'\'') - .add(b'(') - .add(b')') - .add(b'*') - .add(b'+') - .add(b',') - .add(b'-') - .add(b'.') - .add(b'/') - .add(b':') - .add(b';') - .add(b'<') - .add(b'=') - .add(b'>') - .add(b'?') - .add(b'@') - .add(b'[') - .add(b'\\') - .add(b']') - .add(b'^') - .add(b'_') - .add(b'`') - .add(b'{') - .add(b'|') - .add(b'}') - .add(b'~'); - -/// Return the percent-encoding of the given byte. -/// -/// This is unconditional, unlike `percent_encode()` which has an `AsciiSet` parameter. -/// -/// # Examples -/// -/// ``` -/// use percent_encoding::percent_encode_byte; -/// -/// assert_eq!("foo bar".bytes().map(percent_encode_byte).collect::(), -/// "%66%6F%6F%20%62%61%72"); -/// ``` -pub fn percent_encode_byte(byte: u8) -> &'static str { - let index = usize::from(byte) * 3; - &"\ - %00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F\ - %10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F\ - %20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F\ - %30%31%32%33%34%35%36%37%38%39%3A%3B%3C%3D%3E%3F\ - %40%41%42%43%44%45%46%47%48%49%4A%4B%4C%4D%4E%4F\ - %50%51%52%53%54%55%56%57%58%59%5A%5B%5C%5D%5E%5F\ - %60%61%62%63%64%65%66%67%68%69%6A%6B%6C%6D%6E%6F\ - %70%71%72%73%74%75%76%77%78%79%7A%7B%7C%7D%7E%7F\ - %80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F\ - %90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F\ - %A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF\ - %B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF\ - %C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF\ - %D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF\ - %E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF\ - %F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF\ - "[index..index + 3] -} - -/// Percent-encode the given bytes with the given set. -/// -/// Non-ASCII bytes and bytes in `ascii_set` are encoded. -/// -/// The return type: -/// -/// * Implements `Iterator` and therefore has a `.collect::()` method, -/// * Implements `Display` and therefore has a `.to_string()` method, -/// * Implements `Into>` borrowing `input` when none of its bytes are encoded. -/// -/// # Examples -/// -/// ``` -/// use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; -/// -/// assert_eq!(percent_encode(b"foo bar?", NON_ALPHANUMERIC).to_string(), "foo%20bar%3F"); -/// ``` -#[inline] -pub fn percent_encode<'a>(input: &'a [u8], ascii_set: &'static AsciiSet) -> PercentEncode<'a> { - PercentEncode { - bytes: input, - ascii_set, - } -} - -/// Percent-encode the UTF-8 encoding of the given string. -/// -/// See [`percent_encode`] regarding the return type. -/// -/// # Examples -/// -/// ``` -/// use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; -/// -/// assert_eq!(utf8_percent_encode("foo bar?", NON_ALPHANUMERIC).to_string(), "foo%20bar%3F"); -/// ``` -#[inline] -pub fn utf8_percent_encode<'a>(input: &'a str, ascii_set: &'static AsciiSet) -> PercentEncode<'a> { - percent_encode(input.as_bytes(), ascii_set) -} - -/// The return type of [`percent_encode`] and [`utf8_percent_encode`]. -#[derive(Clone)] -pub struct PercentEncode<'a> { - bytes: &'a [u8], - ascii_set: &'static AsciiSet, -} - -impl<'a> Iterator for PercentEncode<'a> { - type Item = &'a str; - - fn next(&mut self) -> Option<&'a str> { - if let Some((&first_byte, remaining)) = self.bytes.split_first() { - if self.ascii_set.should_percent_encode(first_byte) { - self.bytes = remaining; - Some(percent_encode_byte(first_byte)) - } else { - for (i, &byte) in remaining.iter().enumerate() { - if self.ascii_set.should_percent_encode(byte) { - // 1 for first_byte + i for previous iterations of this loop - let (unchanged_slice, remaining) = self.bytes.split_at(1 + i); - self.bytes = remaining; - return Some(unsafe { str::from_utf8_unchecked(unchanged_slice) }); - } - } - let unchanged_slice = self.bytes; - self.bytes = &[][..]; - Some(unsafe { str::from_utf8_unchecked(unchanged_slice) }) - } - } else { - None - } - } - - fn size_hint(&self) -> (usize, Option) { - if self.bytes.is_empty() { - (0, Some(0)) - } else { - (1, Some(self.bytes.len())) - } - } -} - -impl<'a> fmt::Display for PercentEncode<'a> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - for c in (*self).clone() { - formatter.write_str(c)? - } - Ok(()) - } -} - -impl<'a> From> for Cow<'a, str> { - fn from(mut iter: PercentEncode<'a>) -> Self { - match iter.next() { - None => "".into(), - Some(first) => match iter.next() { - None => first.into(), - Some(second) => { - let mut string = first.to_owned(); - string.push_str(second); - string.extend(iter); - string.into() - } - }, - } - } -} - -/// Percent-decode the given string. -/// -/// -/// -/// See [`percent_decode`] regarding the return type. -#[inline] -pub fn percent_decode_str(input: &str) -> PercentDecode { - percent_decode(input.as_bytes()) -} - -/// Percent-decode the given bytes. -/// -/// -/// -/// Any sequence of `%` followed by two hexadecimal digits is decoded. -/// The return type: -/// -/// * Implements `Into>` borrowing `input` when it contains no percent-encoded sequence, -/// * Implements `Iterator` and therefore has a `.collect::>()` method, -/// * Has `decode_utf8()` and `decode_utf8_lossy()` methods. -/// -/// # Examples -/// -/// ``` -/// use percent_encoding::percent_decode; -/// -/// assert_eq!(percent_decode(b"foo%20bar%3f").decode_utf8().unwrap(), "foo bar?"); -/// ``` -#[inline] -pub fn percent_decode(input: &[u8]) -> PercentDecode { - PercentDecode { - bytes: input.iter(), - } -} - -/// The return type of [`percent_decode`]. -#[derive(Clone, Debug)] -pub struct PercentDecode<'a> { - bytes: slice::Iter<'a, u8>, -} - -fn after_percent_sign(iter: &mut slice::Iter) -> Option { - let mut cloned_iter = iter.clone(); - let h = char::from(*cloned_iter.next()?).to_digit(16)?; - let l = char::from(*cloned_iter.next()?).to_digit(16)?; - *iter = cloned_iter; - Some(h as u8 * 0x10 + l as u8) -} - -impl<'a> Iterator for PercentDecode<'a> { - type Item = u8; - - fn next(&mut self) -> Option { - self.bytes.next().map(|&byte| { - if byte == b'%' { - after_percent_sign(&mut self.bytes).unwrap_or(byte) - } else { - byte - } - }) - } - - fn size_hint(&self) -> (usize, Option) { - let bytes = self.bytes.len(); - (bytes / 3, Some(bytes)) - } -} - -impl<'a> From> for Cow<'a, [u8]> { - fn from(iter: PercentDecode<'a>) -> Self { - match iter.if_any() { - Some(vec) => Cow::Owned(vec), - None => Cow::Borrowed(iter.bytes.as_slice()), - } - } -} - -impl<'a> PercentDecode<'a> { - /// If the percent-decoding is different from the input, return it as a new bytes vector. - fn if_any(&self) -> Option> { - let mut bytes_iter = self.bytes.clone(); - while bytes_iter.any(|&b| b == b'%') { - if let Some(decoded_byte) = after_percent_sign(&mut bytes_iter) { - let initial_bytes = self.bytes.as_slice(); - let unchanged_bytes_len = initial_bytes.len() - bytes_iter.len() - 3; - let mut decoded = initial_bytes[..unchanged_bytes_len].to_owned(); - decoded.push(decoded_byte); - decoded.extend(PercentDecode { bytes: bytes_iter }); - return Some(decoded); - } - } - // Nothing to decode - None - } - - /// Decode the result of percent-decoding as UTF-8. - /// - /// This is return `Err` when the percent-decoded bytes are not well-formed in UTF-8. - pub fn decode_utf8(self) -> Result, str::Utf8Error> { - match self.clone().into() { - Cow::Borrowed(bytes) => match str::from_utf8(bytes) { - Ok(s) => Ok(s.into()), - Err(e) => Err(e), - }, - Cow::Owned(bytes) => match String::from_utf8(bytes) { - Ok(s) => Ok(s.into()), - Err(e) => Err(e.utf8_error()), - }, - } - } - - /// Decode the result of percent-decoding as UTF-8, lossily. - /// - /// Invalid UTF-8 percent-encoded byte sequences will be replaced � U+FFFD, - /// the replacement character. - pub fn decode_utf8_lossy(self) -> Cow<'a, str> { - decode_utf8_lossy(self.clone().into()) - } -} - -fn decode_utf8_lossy(input: Cow<[u8]>) -> Cow { - match input { - Cow::Borrowed(bytes) => String::from_utf8_lossy(bytes), - Cow::Owned(bytes) => { - let raw_utf8: *const [u8]; - match String::from_utf8_lossy(&bytes) { - Cow::Borrowed(utf8) => raw_utf8 = utf8.as_bytes(), - Cow::Owned(s) => return s.into(), - } - // from_utf8_lossy returned a borrow of `bytes` unchanged. - debug_assert!(raw_utf8 == &*bytes as *const [u8]); - // Reuse the existing `Vec` allocation. - unsafe { String::from_utf8_unchecked(bytes) }.into() - } - } -} diff --git a/vendor/percent-encoding/src/lib.rs b/vendor/percent-encoding/src/lib.rs new file mode 100644 index 000000000..46a5d747c --- /dev/null +++ b/vendor/percent-encoding/src/lib.rs @@ -0,0 +1,468 @@ +// Copyright 2013-2016 The rust-url developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! URLs use special characters to indicate the parts of the request. +//! For example, a `?` question mark marks the end of a path and the start of a query string. +//! In order for that character to exist inside a path, it needs to be encoded differently. +//! +//! Percent encoding replaces reserved characters with the `%` escape character +//! followed by a byte value as two hexadecimal digits. +//! For example, an ASCII space is replaced with `%20`. +//! +//! When encoding, the set of characters that can (and should, for readability) be left alone +//! depends on the context. +//! The `?` question mark mentioned above is not a separator when used literally +//! inside of a query string, and therefore does not need to be encoded. +//! The [`AsciiSet`] parameter of [`percent_encode`] and [`utf8_percent_encode`] +//! lets callers configure this. +//! +//! This crate deliberately does not provide many different sets. +//! Users should consider in what context the encoded string will be used, +//! read relevant specifications, and define their own set. +//! This is done by using the `add` method of an existing set. +//! +//! # Examples +//! +//! ``` +//! use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; +//! +//! /// https://url.spec.whatwg.org/#fragment-percent-encode-set +//! const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); +//! +//! assert_eq!(utf8_percent_encode("foo ", FRAGMENT).to_string(), "foo%20%3Cbar%3E"); +//! ``` + +#![no_std] +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(feature = "alloc")] +use alloc::{ + borrow::{Cow, ToOwned}, + string::String, + vec::Vec, +}; +use core::{fmt, mem, slice, str}; + +/// Represents a set of characters or bytes in the ASCII range. +/// +/// This is used in [`percent_encode`] and [`utf8_percent_encode`]. +/// This is similar to [percent-encode sets](https://url.spec.whatwg.org/#percent-encoded-bytes). +/// +/// Use the `add` method of an existing set to define a new set. For example: +/// +/// ``` +/// use percent_encoding::{AsciiSet, CONTROLS}; +/// +/// /// https://url.spec.whatwg.org/#fragment-percent-encode-set +/// const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); +/// ``` +pub struct AsciiSet { + mask: [Chunk; ASCII_RANGE_LEN / BITS_PER_CHUNK], +} + +type Chunk = u32; + +const ASCII_RANGE_LEN: usize = 0x80; + +const BITS_PER_CHUNK: usize = 8 * mem::size_of::(); + +impl AsciiSet { + /// Called with UTF-8 bytes rather than code points. + /// Not used for non-ASCII bytes. + const fn contains(&self, byte: u8) -> bool { + let chunk = self.mask[byte as usize / BITS_PER_CHUNK]; + let mask = 1 << (byte as usize % BITS_PER_CHUNK); + (chunk & mask) != 0 + } + + fn should_percent_encode(&self, byte: u8) -> bool { + !byte.is_ascii() || self.contains(byte) + } + + pub const fn add(&self, byte: u8) -> Self { + let mut mask = self.mask; + mask[byte as usize / BITS_PER_CHUNK] |= 1 << (byte as usize % BITS_PER_CHUNK); + AsciiSet { mask } + } + + pub const fn remove(&self, byte: u8) -> Self { + let mut mask = self.mask; + mask[byte as usize / BITS_PER_CHUNK] &= !(1 << (byte as usize % BITS_PER_CHUNK)); + AsciiSet { mask } + } +} + +/// The set of 0x00 to 0x1F (C0 controls), and 0x7F (DEL). +/// +/// Note that this includes the newline and tab characters, but not the space 0x20. +/// +/// +pub const CONTROLS: &AsciiSet = &AsciiSet { + mask: [ + !0_u32, // C0: 0x00 to 0x1F (32 bits set) + 0, + 0, + 1 << (0x7F_u32 % 32), // DEL: 0x7F (one bit set) + ], +}; + +macro_rules! static_assert { + ($( $bool: expr, )+) => { + fn _static_assert() { + $( + let _ = mem::transmute::<[u8; $bool as usize], u8>; + )+ + } + } +} + +static_assert! { + CONTROLS.contains(0x00), + CONTROLS.contains(0x1F), + !CONTROLS.contains(0x20), + !CONTROLS.contains(0x7E), + CONTROLS.contains(0x7F), +} + +/// Everything that is not an ASCII letter or digit. +/// +/// This is probably more eager than necessary in any context. +pub const NON_ALPHANUMERIC: &AsciiSet = &CONTROLS + .add(b' ') + .add(b'!') + .add(b'"') + .add(b'#') + .add(b'$') + .add(b'%') + .add(b'&') + .add(b'\'') + .add(b'(') + .add(b')') + .add(b'*') + .add(b'+') + .add(b',') + .add(b'-') + .add(b'.') + .add(b'/') + .add(b':') + .add(b';') + .add(b'<') + .add(b'=') + .add(b'>') + .add(b'?') + .add(b'@') + .add(b'[') + .add(b'\\') + .add(b']') + .add(b'^') + .add(b'_') + .add(b'`') + .add(b'{') + .add(b'|') + .add(b'}') + .add(b'~'); + +/// Return the percent-encoding of the given byte. +/// +/// This is unconditional, unlike `percent_encode()` which has an `AsciiSet` parameter. +/// +/// # Examples +/// +/// ``` +/// use percent_encoding::percent_encode_byte; +/// +/// assert_eq!("foo bar".bytes().map(percent_encode_byte).collect::(), +/// "%66%6F%6F%20%62%61%72"); +/// ``` +pub fn percent_encode_byte(byte: u8) -> &'static str { + let index = usize::from(byte) * 3; + &"\ + %00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F\ + %10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F\ + %20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F\ + %30%31%32%33%34%35%36%37%38%39%3A%3B%3C%3D%3E%3F\ + %40%41%42%43%44%45%46%47%48%49%4A%4B%4C%4D%4E%4F\ + %50%51%52%53%54%55%56%57%58%59%5A%5B%5C%5D%5E%5F\ + %60%61%62%63%64%65%66%67%68%69%6A%6B%6C%6D%6E%6F\ + %70%71%72%73%74%75%76%77%78%79%7A%7B%7C%7D%7E%7F\ + %80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F\ + %90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F\ + %A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF\ + %B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF\ + %C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF\ + %D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF\ + %E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF\ + %F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF\ + "[index..index + 3] +} + +/// Percent-encode the given bytes with the given set. +/// +/// Non-ASCII bytes and bytes in `ascii_set` are encoded. +/// +/// The return type: +/// +/// * Implements `Iterator` and therefore has a `.collect::()` method, +/// * Implements `Display` and therefore has a `.to_string()` method, +/// * Implements `Into>` borrowing `input` when none of its bytes are encoded. +/// +/// # Examples +/// +/// ``` +/// use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; +/// +/// assert_eq!(percent_encode(b"foo bar?", NON_ALPHANUMERIC).to_string(), "foo%20bar%3F"); +/// ``` +#[inline] +pub fn percent_encode<'a>(input: &'a [u8], ascii_set: &'static AsciiSet) -> PercentEncode<'a> { + PercentEncode { + bytes: input, + ascii_set, + } +} + +/// Percent-encode the UTF-8 encoding of the given string. +/// +/// See [`percent_encode`] regarding the return type. +/// +/// # Examples +/// +/// ``` +/// use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; +/// +/// assert_eq!(utf8_percent_encode("foo bar?", NON_ALPHANUMERIC).to_string(), "foo%20bar%3F"); +/// ``` +#[inline] +pub fn utf8_percent_encode<'a>(input: &'a str, ascii_set: &'static AsciiSet) -> PercentEncode<'a> { + percent_encode(input.as_bytes(), ascii_set) +} + +/// The return type of [`percent_encode`] and [`utf8_percent_encode`]. +#[derive(Clone)] +pub struct PercentEncode<'a> { + bytes: &'a [u8], + ascii_set: &'static AsciiSet, +} + +impl<'a> Iterator for PercentEncode<'a> { + type Item = &'a str; + + fn next(&mut self) -> Option<&'a str> { + if let Some((&first_byte, remaining)) = self.bytes.split_first() { + if self.ascii_set.should_percent_encode(first_byte) { + self.bytes = remaining; + Some(percent_encode_byte(first_byte)) + } else { + // The unsafe blocks here are appropriate because the bytes are + // confirmed as a subset of UTF-8 in should_percent_encode. + for (i, &byte) in remaining.iter().enumerate() { + if self.ascii_set.should_percent_encode(byte) { + // 1 for first_byte + i for previous iterations of this loop + let (unchanged_slice, remaining) = self.bytes.split_at(1 + i); + self.bytes = remaining; + return Some(unsafe { str::from_utf8_unchecked(unchanged_slice) }); + } + } + let unchanged_slice = self.bytes; + self.bytes = &[][..]; + Some(unsafe { str::from_utf8_unchecked(unchanged_slice) }) + } + } else { + None + } + } + + fn size_hint(&self) -> (usize, Option) { + if self.bytes.is_empty() { + (0, Some(0)) + } else { + (1, Some(self.bytes.len())) + } + } +} + +impl<'a> fmt::Display for PercentEncode<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + for c in (*self).clone() { + formatter.write_str(c)? + } + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl<'a> From> for Cow<'a, str> { + fn from(mut iter: PercentEncode<'a>) -> Self { + match iter.next() { + None => "".into(), + Some(first) => match iter.next() { + None => first.into(), + Some(second) => { + let mut string = first.to_owned(); + string.push_str(second); + string.extend(iter); + string.into() + } + }, + } + } +} + +/// Percent-decode the given string. +/// +/// +/// +/// See [`percent_decode`] regarding the return type. +#[inline] +pub fn percent_decode_str(input: &str) -> PercentDecode<'_> { + percent_decode(input.as_bytes()) +} + +/// Percent-decode the given bytes. +/// +/// +/// +/// Any sequence of `%` followed by two hexadecimal digits is decoded. +/// The return type: +/// +/// * Implements `Into>` borrowing `input` when it contains no percent-encoded sequence, +/// * Implements `Iterator` and therefore has a `.collect::>()` method, +/// * Has `decode_utf8()` and `decode_utf8_lossy()` methods. +/// +/// # Examples +/// +/// ``` +/// use percent_encoding::percent_decode; +/// +/// assert_eq!(percent_decode(b"foo%20bar%3f").decode_utf8().unwrap(), "foo bar?"); +/// ``` +#[inline] +pub fn percent_decode(input: &[u8]) -> PercentDecode<'_> { + PercentDecode { + bytes: input.iter(), + } +} + +/// The return type of [`percent_decode`]. +#[derive(Clone, Debug)] +pub struct PercentDecode<'a> { + bytes: slice::Iter<'a, u8>, +} + +fn after_percent_sign(iter: &mut slice::Iter<'_, u8>) -> Option { + let mut cloned_iter = iter.clone(); + let h = char::from(*cloned_iter.next()?).to_digit(16)?; + let l = char::from(*cloned_iter.next()?).to_digit(16)?; + *iter = cloned_iter; + Some(h as u8 * 0x10 + l as u8) +} + +impl<'a> Iterator for PercentDecode<'a> { + type Item = u8; + + fn next(&mut self) -> Option { + self.bytes.next().map(|&byte| { + if byte == b'%' { + after_percent_sign(&mut self.bytes).unwrap_or(byte) + } else { + byte + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let bytes = self.bytes.len(); + ((bytes + 2) / 3, Some(bytes)) + } +} + +#[cfg(feature = "alloc")] +impl<'a> From> for Cow<'a, [u8]> { + fn from(iter: PercentDecode<'a>) -> Self { + match iter.if_any() { + Some(vec) => Cow::Owned(vec), + None => Cow::Borrowed(iter.bytes.as_slice()), + } + } +} + +impl<'a> PercentDecode<'a> { + /// If the percent-decoding is different from the input, return it as a new bytes vector. + #[cfg(feature = "alloc")] + fn if_any(&self) -> Option> { + let mut bytes_iter = self.bytes.clone(); + while bytes_iter.any(|&b| b == b'%') { + if let Some(decoded_byte) = after_percent_sign(&mut bytes_iter) { + let initial_bytes = self.bytes.as_slice(); + let unchanged_bytes_len = initial_bytes.len() - bytes_iter.len() - 3; + let mut decoded = initial_bytes[..unchanged_bytes_len].to_owned(); + decoded.push(decoded_byte); + decoded.extend(PercentDecode { bytes: bytes_iter }); + return Some(decoded); + } + } + // Nothing to decode + None + } + + /// Decode the result of percent-decoding as UTF-8. + /// + /// This is return `Err` when the percent-decoded bytes are not well-formed in UTF-8. + #[cfg(feature = "alloc")] + pub fn decode_utf8(self) -> Result, str::Utf8Error> { + match self.clone().into() { + Cow::Borrowed(bytes) => match str::from_utf8(bytes) { + Ok(s) => Ok(s.into()), + Err(e) => Err(e), + }, + Cow::Owned(bytes) => match String::from_utf8(bytes) { + Ok(s) => Ok(s.into()), + Err(e) => Err(e.utf8_error()), + }, + } + } + + /// Decode the result of percent-decoding as UTF-8, lossily. + /// + /// Invalid UTF-8 percent-encoded byte sequences will be replaced � U+FFFD, + /// the replacement character. + #[cfg(feature = "alloc")] + pub fn decode_utf8_lossy(self) -> Cow<'a, str> { + decode_utf8_lossy(self.clone().into()) + } +} + +#[cfg(feature = "alloc")] +fn decode_utf8_lossy(input: Cow<'_, [u8]>) -> Cow<'_, str> { + // Note: This function is duplicated in `form_urlencoded/src/query_encoding.rs`. + match input { + Cow::Borrowed(bytes) => String::from_utf8_lossy(bytes), + Cow::Owned(bytes) => { + match String::from_utf8_lossy(&bytes) { + Cow::Borrowed(utf8) => { + // If from_utf8_lossy returns a Cow::Borrowed, then we can + // be sure our original bytes were valid UTF-8. This is because + // if the bytes were invalid UTF-8 from_utf8_lossy would have + // to allocate a new owned string to back the Cow so it could + // replace invalid bytes with a placeholder. + + // First we do a debug_assert to confirm our description above. + let raw_utf8: *const [u8] = utf8.as_bytes(); + debug_assert!(raw_utf8 == &*bytes as *const [u8]); + + // Given we know the original input bytes are valid UTF-8, + // and we have ownership of those bytes, we re-use them and + // return a Cow::Owned here. + Cow::Owned(unsafe { String::from_utf8_unchecked(bytes) }) + } + Cow::Owned(s) => Cow::Owned(s), + } + } + } +} diff --git a/vendor/proc-macro2/.cargo-checksum.json b/vendor/proc-macro2/.cargo-checksum.json index 59f2a8483..b20fcaba3 100644 --- a/vendor/proc-macro2/.cargo-checksum.json +++ b/vendor/proc-macro2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"774906eb037620dba1ef4cf6adc14ec35e7f9f81d1e2d967dfedfab8e7b603d9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"0c17148c1957c3f721d99fc99aedaefee5f2f1ba7e2336a289b02f91609099fb","build.rs":"2c6ddbeeb1700b8dba3689185a535c672dc43e9d61b54f835cf4f3cc163b4afc","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/fallback.rs":"5aab7b73e381dc192256a0c67c99706ae0850159fd9f805fb0c9418fc14b1e00","src/lib.rs":"8bd3da5c9f048acda3799d53eefb7fb2f8b4046612d48f34ec30102b10f4ab08","src/marker.rs":"344a8394f06a1d43355b514920e7e3c0c6dce507be767e3a590bbe3552edd110","src/parse.rs":"34fa3c2e03fa9ab3e63ea57595d1dea4edf0fcfa313a04057e4dd7dc7d7269e0","src/rcvec.rs":"49b6784c6ca5f32573cd8a83758b485d8acbfa126e5fb516ae439e429ef4c144","src/wrapper.rs":"a88d0dff9bb8317071ec205b0c2a79717cd8313041e03ef58e0645be65ab05e8","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"cb6d776eba6a238d726b0f531883adf41957e06f2717ee8a069821c81e7081d6","tests/test.rs":"2fe87d2eab135fb2417cac2876998e9314616fb68981918d7d76333c22b199a0","tests/test_fmt.rs":"9357769945784354909259084ec8b34d2aa52081dd3967cac6dae3a5e3df3bc0"},"package":"0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"} \ No newline at end of file +{"files":{"Cargo.toml":"070b0704e5cdbac330b9cecee44e488a40b6daf6161215e4457bdfc3e7e9bf94","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"0c17148c1957c3f721d99fc99aedaefee5f2f1ba7e2336a289b02f91609099fb","build.rs":"275f7a9ee0b9eff972124951de544ae17ee3e698a4e89b0f0393b334344f5e30","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/fallback.rs":"a9e6fa159d6a111a231fa9367d54859103e9d49f6662397baea951b5f3e7e983","src/lib.rs":"81865a868ef697987cafef5eb9512d3109da373456eead2a36c22d44e769c947","src/marker.rs":"344a8394f06a1d43355b514920e7e3c0c6dce507be767e3a590bbe3552edd110","src/parse.rs":"637a9fe6e3e21c36fa411b70674f617743fe0129787c17a559e78f86418d0da4","src/rcvec.rs":"49b6784c6ca5f32573cd8a83758b485d8acbfa126e5fb516ae439e429ef4c144","src/wrapper.rs":"8ea825cdac628570719a258419fcffd1c9d2ca1ca5e2fbbbf283dd9cc6695910","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"cb6d776eba6a238d726b0f531883adf41957e06f2717ee8a069821c81e7081d6","tests/test.rs":"d7f21088314d1df25447fdc0a32feffae26d4d637e3ce68e23c0190060cb5652","tests/test_fmt.rs":"9357769945784354909259084ec8b34d2aa52081dd3967cac6dae3a5e3df3bc0"},"package":"5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"} \ No newline at end of file diff --git a/vendor/proc-macro2/Cargo.toml b/vendor/proc-macro2/Cargo.toml index b8b46430d..1bda7e36d 100644 --- a/vendor/proc-macro2/Cargo.toml +++ b/vendor/proc-macro2/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" authors = [ "David Tolnay ", "Alex Crichton ", diff --git a/vendor/proc-macro2/build.rs b/vendor/proc-macro2/build.rs index 38404967d..b69d813f0 100644 --- a/vendor/proc-macro2/build.rs +++ b/vendor/proc-macro2/build.rs @@ -111,7 +111,10 @@ fn main() { println!("cargo:rustc-cfg=wrap_proc_macro"); } - if version.nightly && feature_allowed("proc_macro_span") { + if version.nightly + && feature_allowed("proc_macro_span") + && feature_allowed("proc_macro_span_shrink") + { println!("cargo:rustc-cfg=proc_macro_span"); } diff --git a/vendor/proc-macro2/src/fallback.rs b/vendor/proc-macro2/src/fallback.rs index 378ef7e94..fe4f248d3 100644 --- a/vendor/proc-macro2/src/fallback.rs +++ b/vendor/proc-macro2/src/fallback.rs @@ -182,7 +182,13 @@ impl FromStr for TokenStream { fn from_str(src: &str) -> Result { // Create a dummy file & add it to the source map - let cursor = get_cursor(src); + let mut cursor = get_cursor(src); + + // Strip a byte order mark if present + const BYTE_ORDER_MARK: &str = "\u{feff}"; + if cursor.starts_with(BYTE_ORDER_MARK) { + cursor = cursor.advance(BYTE_ORDER_MARK.len()); + } parse::token_stream(cursor) } @@ -512,6 +518,26 @@ impl Span { }) } + #[cfg(procmacro2_semver_exempt)] + pub fn before(&self) -> Span { + Span { + #[cfg(span_locations)] + lo: self.lo, + #[cfg(span_locations)] + hi: self.lo, + } + } + + #[cfg(procmacro2_semver_exempt)] + pub fn after(&self) -> Span { + Span { + #[cfg(span_locations)] + lo: self.hi, + #[cfg(span_locations)] + hi: self.hi, + } + } + #[cfg(not(span_locations))] pub fn join(&self, _other: Span) -> Option { Some(Span {}) diff --git a/vendor/proc-macro2/src/lib.rs b/vendor/proc-macro2/src/lib.rs index be5aa5114..3fda02d5c 100644 --- a/vendor/proc-macro2/src/lib.rs +++ b/vendor/proc-macro2/src/lib.rs @@ -86,8 +86,11 @@ //! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.43")] -#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.47")] +#![cfg_attr( + any(proc_macro_span, super_unstable), + feature(proc_macro_span, proc_macro_span_shrink) +)] #![cfg_attr(super_unstable, feature(proc_macro_def_site))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![allow( @@ -509,6 +512,24 @@ impl Span { LineColumn { line, column } } + /// Creates an empty span pointing to directly before this span. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] + #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + pub fn before(&self) -> Span { + Span::_new(self.inner.before()) + } + + /// Creates an empty span pointing to directly after this span. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] + #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + pub fn after(&self) -> Span { + Span::_new(self.inner.after()) + } + /// Create a new span encompassing `self` and `other`. /// /// Returns `None` if `self` and `other` are from different files. diff --git a/vendor/proc-macro2/src/parse.rs b/vendor/proc-macro2/src/parse.rs index 1c9974cfa..307e06508 100644 --- a/vendor/proc-macro2/src/parse.rs +++ b/vendor/proc-macro2/src/parse.rs @@ -14,7 +14,7 @@ pub(crate) struct Cursor<'a> { } impl<'a> Cursor<'a> { - fn advance(&self, bytes: usize) -> Cursor<'a> { + pub fn advance(&self, bytes: usize) -> Cursor<'a> { let (_front, rest) = self.rest.split_at(bytes); Cursor { rest, @@ -23,7 +23,7 @@ impl<'a> Cursor<'a> { } } - fn starts_with(&self, s: &str) -> bool { + pub fn starts_with(&self, s: &str) -> bool { self.rest.starts_with(s) } @@ -116,9 +116,9 @@ fn block_comment(input: Cursor) -> PResult<&str> { return Err(Reject); } - let mut depth = 0; + let mut depth = 0usize; let bytes = input.as_bytes(); - let mut i = 0; + let mut i = 0usize; let upper = bytes.len() - 1; while i < upper { @@ -283,8 +283,9 @@ fn ident_any(input: Cursor) -> PResult { return Ok((rest, ident)); } - if sym == "_" { - return Err(Reject); + match sym { + "_" | "super" | "self" | "Self" | "crate" => return Err(Reject), + _ => {} } let ident = crate::Ident::_new_raw(sym, crate::Span::call_site()); diff --git a/vendor/proc-macro2/src/wrapper.rs b/vendor/proc-macro2/src/wrapper.rs index 934440139..47d149473 100644 --- a/vendor/proc-macro2/src/wrapper.rs +++ b/vendor/proc-macro2/src/wrapper.rs @@ -505,6 +505,22 @@ impl Span { } } + #[cfg(super_unstable)] + pub fn before(&self) -> Span { + match self { + Span::Compiler(s) => Span::Compiler(s.before()), + Span::Fallback(s) => Span::Fallback(s.before()), + } + } + + #[cfg(super_unstable)] + pub fn after(&self) -> Span { + match self { + Span::Compiler(s) => Span::Compiler(s.after()), + Span::Fallback(s) => Span::Fallback(s.after()), + } + } + pub fn join(&self, other: Span) -> Option { let ret = match (self, other) { #[cfg(proc_macro_span)] diff --git a/vendor/proc-macro2/tests/test.rs b/vendor/proc-macro2/tests/test.rs index 16f775ed0..8f5624dbc 100644 --- a/vendor/proc-macro2/tests/test.rs +++ b/vendor/proc-macro2/tests/test.rs @@ -630,3 +630,16 @@ fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usi } } } + +#[test] +fn byte_order_mark() { + let string = "\u{feff}foo"; + let tokens = string.parse::().unwrap(); + match tokens.into_iter().next().unwrap() { + TokenTree::Ident(ident) => assert_eq!(ident, "foo"), + _ => unreachable!(), + } + + let string = "foo\u{feff}"; + string.parse::().unwrap_err(); +} diff --git a/vendor/rowan/.cargo-checksum.json b/vendor/rowan/.cargo-checksum.json index f2cbdfc1d..82ca4c645 100644 --- a/vendor/rowan/.cargo-checksum.json +++ b/vendor/rowan/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"d89194369a60b64062043f52664726c5f114542c20c2fbfaafac9fad682c139b","Cargo.toml":"fbd2ff15249776d6bbc4d3646ed0a7681172aad7c7f7a42b512308b7672b43b4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"69657dd291f7b245820ee01fa7bdbfdc5dc2b47284767641ffb8f94e9f9bc522","examples/math.rs":"e7557914686973cc16c6b2736a9934708465ef996b4f0a54fdb454b524641dc9","examples/s_expressions.rs":"6d963a8c030978e2648a059f2dcd5314d9fef47f0dda45e4134caedae1429eee","src/api.rs":"b5d48c0d401014c09ef9d8ee54c849735b1235e5faa798f7291be3d6a8a335c9","src/arc.rs":"fef1aa58a57d167bf4ba99b186b7e9a9c0df8c6096c2f604fbff86430dbaa6e3","src/ast.rs":"6eeedc3fcfb7b1d3d53aa54fc68a8f3bc6381ba2433e12d82b13f51fb5a82446","src/cow_mut.rs":"c90f47a013ae8cfb00bee089b75bbc2e493424e344fb4aaeff78cb2db8558ec2","src/cursor.rs":"b150f5d016aee8b196f5c02af6e7473b32e62f39fc62242dd7adbfddb21f8b69","src/green.rs":"34d58d497d2af2bbd1533aea6b4aa91496d65275b3b6def8dd6f5b1210ec0ce0","src/green/builder.rs":"517e4f6393f8fe6deaabd288f5e5b6a670dc7deec99e5bd92df34cdb4f02db49","src/green/element.rs":"df199a8b6adefef54398f209e7316525eaf84133e952325d46641b66cb89ada9","src/green/node.rs":"02701fc84ad6fdf44bd2c9b63923b0c919ca77acdb09c40d1d2b949830eab185","src/green/node_cache.rs":"f85ca104edb7d2261fd111a6fa4165f076e802aa9414457bdb028788db8dde9d","src/green/token.rs":"a1440de773044e82686dc9173ca7732a6a415a7ba6272c8bc68b3dd896f0cd7b","src/lib.rs":"e0eb1ba73978636b577094ebb726e2e222f347587928ba3930b196b809f17f86","src/serde_impls.rs":"603a459c1e3ad6edd2915e6ef3d103bae36364e01d781a8521486d618ba7b678","src/sll.rs":"f476ecf40629de8f45f5d952a88ebd91f91c71ac635ddc7cd2eebf5a90ce07bf","src/syntax_text.rs":"e387fa481a53aa9dd220a350acabd150daa8440c07ade49ea8a2f69275c6b366","src/utility_types.rs":"ce0874ae3e2b1eccb77025322c4453ceafef983f5d41b442448fb848259edf06","tests/tidy.rs":"15f655d7022a23cea887c6ac52727811f72c7d6a0fd54cdbb0476521ab4fea7f"},"package":"e88acf7b001007e9e8c989fe7449f6601d909e5dd2c56399fc158977ad6c56e8"} \ No newline at end of file +{"files":{"Cargo.lock":"c9b42773521ed23cc479fbacab073a4facfff8e75d2142c309503c1d4ad7fab5","Cargo.toml":"30d67cf548adf18e21fe99a8b1fe12ce8d5a78efbd1e470745d6fbab513576aa","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"69657dd291f7b245820ee01fa7bdbfdc5dc2b47284767641ffb8f94e9f9bc522","examples/math.rs":"e7557914686973cc16c6b2736a9934708465ef996b4f0a54fdb454b524641dc9","examples/s_expressions.rs":"6d963a8c030978e2648a059f2dcd5314d9fef47f0dda45e4134caedae1429eee","src/api.rs":"b5d48c0d401014c09ef9d8ee54c849735b1235e5faa798f7291be3d6a8a335c9","src/arc.rs":"fef1aa58a57d167bf4ba99b186b7e9a9c0df8c6096c2f604fbff86430dbaa6e3","src/ast.rs":"6eeedc3fcfb7b1d3d53aa54fc68a8f3bc6381ba2433e12d82b13f51fb5a82446","src/cow_mut.rs":"c90f47a013ae8cfb00bee089b75bbc2e493424e344fb4aaeff78cb2db8558ec2","src/cursor.rs":"025684328fb9138bae300e1dec9a7c016640e583ff3729a7d0a34c17854d74cc","src/green.rs":"34d58d497d2af2bbd1533aea6b4aa91496d65275b3b6def8dd6f5b1210ec0ce0","src/green/builder.rs":"517e4f6393f8fe6deaabd288f5e5b6a670dc7deec99e5bd92df34cdb4f02db49","src/green/element.rs":"df199a8b6adefef54398f209e7316525eaf84133e952325d46641b66cb89ada9","src/green/node.rs":"02701fc84ad6fdf44bd2c9b63923b0c919ca77acdb09c40d1d2b949830eab185","src/green/node_cache.rs":"f85ca104edb7d2261fd111a6fa4165f076e802aa9414457bdb028788db8dde9d","src/green/token.rs":"a1440de773044e82686dc9173ca7732a6a415a7ba6272c8bc68b3dd896f0cd7b","src/lib.rs":"e0eb1ba73978636b577094ebb726e2e222f347587928ba3930b196b809f17f86","src/serde_impls.rs":"603a459c1e3ad6edd2915e6ef3d103bae36364e01d781a8521486d618ba7b678","src/sll.rs":"f476ecf40629de8f45f5d952a88ebd91f91c71ac635ddc7cd2eebf5a90ce07bf","src/syntax_text.rs":"e387fa481a53aa9dd220a350acabd150daa8440c07ade49ea8a2f69275c6b366","src/utility_types.rs":"ce0874ae3e2b1eccb77025322c4453ceafef983f5d41b442448fb848259edf06","tests/tidy.rs":"15f655d7022a23cea887c6ac52727811f72c7d6a0fd54cdbb0476521ab4fea7f"},"package":"5811547e7ba31e903fe48c8ceab10d40d70a101f3d15523c847cce91aa71f332"} \ No newline at end of file diff --git a/vendor/rowan/Cargo.lock b/vendor/rowan/Cargo.lock index a53655c96..a492ecc3a 100644 --- a/vendor/rowan/Cargo.lock +++ b/vendor/rowan/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -72,7 +72,7 @@ checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "rowan" -version = "0.15.8" +version = "0.15.10" dependencies = [ "countme", "hashbrown", @@ -91,9 +91,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "serde" -version = "1.0.140" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" [[package]] name = "text-size" diff --git a/vendor/rowan/Cargo.toml b/vendor/rowan/Cargo.toml index c717f55d0..44c527d42 100644 --- a/vendor/rowan/Cargo.toml +++ b/vendor/rowan/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "rowan" -version = "0.15.8" +version = "0.15.10" authors = ["Aleksey Kladov "] exclude = [ ".github/", @@ -23,7 +23,6 @@ description = "Library for generic lossless syntax trees" readme = "README.md" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-analyzer/rowan" -resolver = "2" [dependencies.countme] version = "3.0.0" diff --git a/vendor/rowan/src/cursor.rs b/vendor/rowan/src/cursor.rs index 39b0c9624..671be2348 100644 --- a/vendor/rowan/src/cursor.rs +++ b/vendor/rowan/src/cursor.rs @@ -390,7 +390,7 @@ impl NodeData { } fn prev_sibling(&self) -> Option { let mut rev_siblings = self.green_siblings().enumerate().rev(); - let index = rev_siblings.len() - (self.index() as usize); + let index = rev_siblings.len().checked_sub(self.index() as usize + 1)?; rev_siblings.nth(index); rev_siblings.find_map(|(index, child)| { diff --git a/vendor/rustc_tools_util/.cargo-checksum.json b/vendor/rustc_tools_util/.cargo-checksum.json new file mode 100644 index 000000000..fa6b5aa1b --- /dev/null +++ b/vendor/rustc_tools_util/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"19638c267dcbea07037fae9353aafa031a81bde979a48d3333d7400cabcb0560","LICENSE-APACHE":"7ce8f5804da3116a112112a3b6ace5f58977fccf878d48dc9b108cc5e26c298c","LICENSE-MIT":"f4acf81886b4abbe3b7938d279536763774b1f061cf25881652300726ada3bda","README.md":"f90d8251e2485a4a0b3ab1b136728e429fbde3b7d6ddb222dc58fd3bae169bd1","src/lib.rs":"d2a621ad6319d586b100f796dd3d2bac9624325df4fead4edf62f6486ac8f26a"},"package":"598f48ce2a421542b3e64828aa742b687cc1b91d2f96591cfdb7ac5988cd6366"} \ No newline at end of file diff --git a/vendor/rustc_tools_util/Cargo.toml b/vendor/rustc_tools_util/Cargo.toml new file mode 100644 index 000000000..44a165131 --- /dev/null +++ b/vendor/rustc_tools_util/Cargo.toml @@ -0,0 +1,32 @@ +# 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 = "2018" +name = "rustc_tools_util" +version = "0.2.1" +description = "small helper to generate version information for git packages" +readme = "README.md" +keywords = [ + "rustc", + "tool", + "git", + "version", + "hash", +] +categories = ["development-tools"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/rust-clippy" + +[dependencies] + +[features] +deny-warnings = [] diff --git a/vendor/rustc_tools_util/LICENSE-APACHE b/vendor/rustc_tools_util/LICENSE-APACHE new file mode 100644 index 000000000..0d62c3727 --- /dev/null +++ b/vendor/rustc_tools_util/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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 2014-2022 The Rust Project Developers + +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. diff --git a/vendor/rustc_tools_util/LICENSE-MIT b/vendor/rustc_tools_util/LICENSE-MIT new file mode 100644 index 000000000..b724b24aa --- /dev/null +++ b/vendor/rustc_tools_util/LICENSE-MIT @@ -0,0 +1,27 @@ +MIT License + +Copyright (c) 2014-2022 The Rust Project Developers + +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. diff --git a/vendor/rustc_tools_util/README.md b/vendor/rustc_tools_util/README.md new file mode 100644 index 000000000..e947f9c7e --- /dev/null +++ b/vendor/rustc_tools_util/README.md @@ -0,0 +1,62 @@ +# rustc_tools_util + +A small tool to help you generate version information +for packages installed from a git repo + +## Usage + +Add a `build.rs` file to your repo and list it in `Cargo.toml` +````toml +build = "build.rs" +```` + +List rustc_tools_util as regular AND build dependency. +````toml +[dependencies] +rustc_tools_util = "0.2.1" + +[build-dependencies] +rustc_tools_util = "0.2.1" +```` + +In `build.rs`, generate the data in your `main()` +````rust +fn main() { + println!( + "cargo:rustc-env=GIT_HASH={}", + rustc_tools_util::get_commit_hash().unwrap_or_default() + ); + println!( + "cargo:rustc-env=COMMIT_DATE={}", + rustc_tools_util::get_commit_date().unwrap_or_default() + ); + println!( + "cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}", + rustc_tools_util::get_channel().unwrap_or_default() + ); +} + +```` + +Use the version information in your main.rs +````rust +use rustc_tools_util::*; + +fn show_version() { + let version_info = rustc_tools_util::get_version_info!(); + println!("{}", version_info); +} +```` +This gives the following output in clippy: +`clippy 0.0.212 (a416c5e 2018-12-14)` + + +## License + +Copyright 2014-2022 The Rust Project Developers + +Licensed under the Apache License, Version 2.0 or the MIT license +, at your +option. All files in the project carrying such notice may not be +copied, modified, or distributed except according to those terms. diff --git a/vendor/rustc_tools_util/src/lib.rs b/vendor/rustc_tools_util/src/lib.rs new file mode 100644 index 000000000..01d25c531 --- /dev/null +++ b/vendor/rustc_tools_util/src/lib.rs @@ -0,0 +1,162 @@ +#![cfg_attr(feature = "deny-warnings", deny(warnings))] + +use std::env; + +#[macro_export] +macro_rules! get_version_info { + () => {{ + let major = env!("CARGO_PKG_VERSION_MAJOR").parse::().unwrap(); + let minor = env!("CARGO_PKG_VERSION_MINOR").parse::().unwrap(); + let patch = env!("CARGO_PKG_VERSION_PATCH").parse::().unwrap(); + let crate_name = String::from(env!("CARGO_PKG_NAME")); + + let host_compiler = option_env!("RUSTC_RELEASE_CHANNEL").map(str::to_string); + let commit_hash = option_env!("GIT_HASH").map(str::to_string); + let commit_date = option_env!("COMMIT_DATE").map(str::to_string); + + VersionInfo { + major, + minor, + patch, + host_compiler, + commit_hash, + commit_date, + crate_name, + } + }}; +} + +// some code taken and adapted from RLS and cargo +pub struct VersionInfo { + pub major: u8, + pub minor: u8, + pub patch: u16, + pub host_compiler: Option, + pub commit_hash: Option, + pub commit_date: Option, + pub crate_name: String, +} + +impl std::fmt::Display for VersionInfo { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let hash = self.commit_hash.clone().unwrap_or_default(); + let hash_trimmed = hash.trim(); + + let date = self.commit_date.clone().unwrap_or_default(); + let date_trimmed = date.trim(); + + if (hash_trimmed.len() + date_trimmed.len()) > 0 { + write!( + f, + "{} {}.{}.{} ({hash_trimmed} {date_trimmed})", + self.crate_name, self.major, self.minor, self.patch, + )?; + } else { + write!(f, "{} {}.{}.{}", self.crate_name, self.major, self.minor, self.patch)?; + } + + Ok(()) + } +} + +impl std::fmt::Debug for VersionInfo { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "VersionInfo {{ crate_name: \"{}\", major: {}, minor: {}, patch: {}", + self.crate_name, self.major, self.minor, self.patch, + )?; + if self.commit_hash.is_some() { + write!( + f, + ", commit_hash: \"{}\", commit_date: \"{}\" }}", + self.commit_hash.clone().unwrap_or_default().trim(), + self.commit_date.clone().unwrap_or_default().trim() + )?; + } else { + write!(f, " }}")?; + } + + Ok(()) + } +} + +#[must_use] +pub fn get_commit_hash() -> Option { + std::process::Command::new("git") + .args(["rev-parse", "--short", "HEAD"]) + .output() + .ok() + .and_then(|r| String::from_utf8(r.stdout).ok()) +} + +#[must_use] +pub fn get_commit_date() -> Option { + std::process::Command::new("git") + .args(["log", "-1", "--date=short", "--pretty=format:%cd"]) + .output() + .ok() + .and_then(|r| String::from_utf8(r.stdout).ok()) +} + +#[must_use] +pub fn get_channel() -> String { + match env::var("CFG_RELEASE_CHANNEL") { + Ok(channel) => channel, + Err(_) => { + // if that failed, try to ask rustc -V, do some parsing and find out + match std::process::Command::new("rustc") + .arg("-V") + .output() + .ok() + .and_then(|r| String::from_utf8(r.stdout).ok()) + { + Some(rustc_output) => { + if rustc_output.contains("beta") { + String::from("beta") + } else if rustc_output.contains("stable") { + String::from("stable") + } else { + // default to nightly if we fail to parse + String::from("nightly") + } + }, + // default to nightly + None => String::from("nightly"), + } + }, + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_struct_local() { + let vi = get_version_info!(); + assert_eq!(vi.major, 0); + assert_eq!(vi.minor, 2); + assert_eq!(vi.patch, 1); + assert_eq!(vi.crate_name, "rustc_tools_util"); + // hard to make positive tests for these since they will always change + assert!(vi.commit_hash.is_none()); + assert!(vi.commit_date.is_none()); + } + + #[test] + fn test_display_local() { + let vi = get_version_info!(); + assert_eq!(vi.to_string(), "rustc_tools_util 0.2.1"); + } + + #[test] + fn test_debug_local() { + let vi = get_version_info!(); + let s = format!("{vi:?}"); + assert_eq!( + s, + "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 2, patch: 1 }" + ); + } +} diff --git a/vendor/semver/.cargo-checksum.json b/vendor/semver/.cargo-checksum.json index f9b5c853b..afd692226 100644 --- a/vendor/semver/.cargo-checksum.json +++ b/vendor/semver/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"2841cf520fc7e71e16036c48021789cdf36182786556b2a97eb8371193e0c69c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"83e92a83348171f60d768651091803e69e4cb7ea3190cdfc45918d4637f38e1e","benches/parse.rs":"6531f66f80ce2fc83878f9bf84f94c42e96f1e709466f2b88be8d95a3cec1511","build.rs":"eedfc19afa205955347175916974cdad121b55cb940e40c61931e5e7629f0e65","src/backport.rs":"f8866548840434c8974f135528693f25aacc4ad03639c4e3aea3be351e13fdf8","src/display.rs":"9ba42f7a6579aa9c7dd72f2380036f5c9664592f3eacd09ea25cef291a3e64e5","src/error.rs":"3bb489f4a29f38d93370e64ae8d6e4e9b451a055cd7d392b6aeacab7eb3e1953","src/eval.rs":"b7e7ec976051b9f87ddf5cfdbaad64654d98d86ae0763f7d88b14eeaeac6013c","src/identifier.rs":"601231351ac58602b7d193cb0951b5146bd868b62aba938d5cbe52cf2b93414b","src/impls.rs":"79b5a2ac6ca3d4cb46adfb1494756079f53bef780dd81c3a8d3adf86f91395c8","src/lib.rs":"f59b217cd6d3e26389562710c540f0f0e1af7184ac5cbf75b2200f7ed7538f1d","src/parse.rs":"ffbb84081f0f66ec47b752a1e32f1bea5f206ca84f464b99d0497451305a92f8","src/serde.rs":"e2a9b9dc3cd2cccc250eaffad049de418ef791bf8c4a34111a48f068353e0a37","tests/node/mod.rs":"2710d9b8daace2038b66db0f8f4cc522dee938e7cbc42d7739c31995343c32f4","tests/test_autotrait.rs":"070500c32ceee14a8a0110c04a01f98278b24614a0aec8c382dcea3da0343f58","tests/test_identifier.rs":"6c3da46c73df210527b60f1069131b15e2c65eb7b5d11793940d00cf66812f4d","tests/test_version.rs":"09e37c3df162205acf3683d1c760a6001e34e1c709fd4a1a265d82450e340003","tests/test_version_req.rs":"b6eea0258cc3b6d567a9f6c42693a97316345083495236c47e85374fd45f7cf0","tests/util/mod.rs":"db61c2cd86af864d8be4f2a3d5f25c86d7712201cc6ab47b715facf5f7f275b7"},"package":"93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"} \ No newline at end of file +{"files":{"Cargo.toml":"2ef1bca69e829c310ba591cf769d26b9599343b5e8277607c810fcc27b08b507","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"83e92a83348171f60d768651091803e69e4cb7ea3190cdfc45918d4637f38e1e","benches/parse.rs":"6531f66f80ce2fc83878f9bf84f94c42e96f1e709466f2b88be8d95a3cec1511","build.rs":"eedfc19afa205955347175916974cdad121b55cb940e40c61931e5e7629f0e65","src/backport.rs":"c1335129f4969ac887dcf4cdee7592d0854163ee3023c14649d1fba2ab5f08ba","src/display.rs":"9ba42f7a6579aa9c7dd72f2380036f5c9664592f3eacd09ea25cef291a3e64e5","src/error.rs":"3bb489f4a29f38d93370e64ae8d6e4e9b451a055cd7d392b6aeacab7eb3e1953","src/eval.rs":"b7e7ec976051b9f87ddf5cfdbaad64654d98d86ae0763f7d88b14eeaeac6013c","src/identifier.rs":"2fcc23896070ed0a658282a5c7053f1439a55c9e2ea927703408fea8321bfbee","src/impls.rs":"79b5a2ac6ca3d4cb46adfb1494756079f53bef780dd81c3a8d3adf86f91395c8","src/lib.rs":"4118a9d0aedfdbfb930fac79f6aa03771b7a3348b7fe2b4d3d02530dc8b6f387","src/parse.rs":"ffbb84081f0f66ec47b752a1e32f1bea5f206ca84f464b99d0497451305a92f8","src/serde.rs":"e2a9b9dc3cd2cccc250eaffad049de418ef791bf8c4a34111a48f068353e0a37","tests/node/mod.rs":"2710d9b8daace2038b66db0f8f4cc522dee938e7cbc42d7739c31995343c32f4","tests/test_autotrait.rs":"070500c32ceee14a8a0110c04a01f98278b24614a0aec8c382dcea3da0343f58","tests/test_identifier.rs":"6c3da46c73df210527b60f1069131b15e2c65eb7b5d11793940d00cf66812f4d","tests/test_version.rs":"09e37c3df162205acf3683d1c760a6001e34e1c709fd4a1a265d82450e340003","tests/test_version_req.rs":"b6eea0258cc3b6d567a9f6c42693a97316345083495236c47e85374fd45f7cf0","tests/util/mod.rs":"db61c2cd86af864d8be4f2a3d5f25c86d7712201cc6ab47b715facf5f7f275b7"},"package":"e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"} \ No newline at end of file diff --git a/vendor/semver/Cargo.toml b/vendor/semver/Cargo.toml index e8ad37c7a..68aa0b972 100644 --- a/vendor/semver/Cargo.toml +++ b/vendor/semver/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "semver" -version = "1.0.13" +version = "1.0.14" authors = ["David Tolnay "] description = "Parser and evaluator for Cargo's flavor of Semantic Versioning" documentation = "https://docs.rs/semver" diff --git a/vendor/semver/src/backport.rs b/vendor/semver/src/backport.rs index c7751b29f..4b67f56a5 100644 --- a/vendor/semver/src/backport.rs +++ b/vendor/semver/src/backport.rs @@ -22,7 +22,9 @@ pub(crate) mod alloc { pub mod alloc { use std::mem; + use std::process; + #[derive(Copy, Clone)] pub struct Layout { size: usize, } @@ -47,5 +49,12 @@ pub(crate) mod alloc { let len_u16 = (layout.size + 1) / 2; unsafe { Vec::from_raw_parts(ptr as *mut u16, 0, len_u16) }; } + + pub fn handle_alloc_error(_layout: Layout) -> ! { + // This is unreachable because the alloc implementation above never + // returns null; Vec::reserve_exact would already have called std's + // internal handle_alloc_error. + process::abort(); + } } } diff --git a/vendor/semver/src/identifier.rs b/vendor/semver/src/identifier.rs index 170a4e05e..fbe1df020 100644 --- a/vendor/semver/src/identifier.rs +++ b/vendor/semver/src/identifier.rs @@ -66,7 +66,7 @@ // repr, leaving it available as a niche for downstream code. For example this // allows size_of::() == size_of::>(). -use crate::alloc::alloc::{alloc, dealloc, Layout}; +use crate::alloc::alloc::{alloc, dealloc, handle_alloc_error, Layout}; use core::mem; use core::num::{NonZeroU64, NonZeroUsize}; use core::ptr::{self, NonNull}; @@ -123,6 +123,9 @@ impl Identifier { let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; // SAFETY: layout's size is nonzero. let ptr = unsafe { alloc(layout) }; + if ptr.is_null() { + handle_alloc_error(layout); + } let mut write = ptr; let mut varint_remaining = len; while varint_remaining > 0 { @@ -203,6 +206,9 @@ impl Clone for Identifier { let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; // SAFETY: layout's size is nonzero. let clone = unsafe { alloc(layout) }; + if clone.is_null() { + handle_alloc_error(layout); + } // SAFETY: new allocation cannot overlap the previous one (this was // not a realloc). The argument ptrs are readable/writeable // respectively for size bytes. diff --git a/vendor/semver/src/lib.rs b/vendor/semver/src/lib.rs index b3c3ea286..ca4d1119c 100644 --- a/vendor/semver/src/lib.rs +++ b/vendor/semver/src/lib.rs @@ -60,7 +60,7 @@ //! //! [Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html -#![doc(html_root_url = "https://docs.rs/semver/1.0.13")] +#![doc(html_root_url = "https://docs.rs/semver/1.0.14")] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr(all(not(feature = "std"), not(no_alloc_crate)), no_std)] #![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))] diff --git a/vendor/serde/.cargo-checksum.json b/vendor/serde/.cargo-checksum.json index 1149006a8..0aefd0d73 100644 --- a/vendor/serde/.cargo-checksum.json +++ b/vendor/serde/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"a55cd52d7858718ed68b8c1aaac689aa8fb801d9194b904e3df31850c95b71f0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"89cfc904243b611a8a2fc1c8724d6f1c2b61c166ca81676b903ddf80b8ff1c10","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/de/format.rs":"4b466a6a7f0070e884d14457759671c6ad7394fe9603708b7151ef6159258146","src/de/ignored_any.rs":"c69d6071191c2075372218442e9e73991335c6b4be18736a7a789f04bb305525","src/de/impls.rs":"b2fea640830a690d09b453fe126034f1f3f77e553b604a7a9ac83b043315248f","src/de/mod.rs":"1ac7de9cfc47d0a8ac104c1809fd81d7febfcd01d74d6abcbf0bf31ec200f625","src/de/seed.rs":"e8cf0233afe0af5b8fb9e4c94f301c92729c5ba417280af9e2201b732e374a72","src/de/utf8.rs":"f17524ee0af98ec3abcfd7d0b812fbd1033263bd8e2ce2f57c1e1999ce153558","src/de/value.rs":"a511298691a1505955eace480afd19bfa2d5abeb06cba3b7bc92af3d0c99968c","src/integer128.rs":"ca49591abde2d8c4f582174533fee28f0fa9139e5d71bf22b25a6b175f8abccc","src/lib.rs":"ef1afaa6c1a4989102b46763c24e13d39573c8619a585ae6e9dc7c5a49efb7d9","src/macros.rs":"3d695a51f0a07f9f719dcb5620012c21a1b084c06a6283349cabf574ceba8123","src/private/de.rs":"ae9fd944944f9c2fb2eb07a622439c7ebdeab5e9d218cdaec9197cb5caa0941c","src/private/doc.rs":"e9801a43c3088fccd5f1fac76416698f948e65b647024aa9da17d673e1e8c217","src/private/mod.rs":"37b204775e572396515477b393ce793b2579de48e5971e6f596ba3723c489fd6","src/private/ser.rs":"3a90dfb5c17e81bf1d959fed60a9477713498e9d0934463627c98709132f066e","src/private/size_hint.rs":"605521227e9ba3100fbb9d5ea7fd5853385097c35015ce6908bd5f1ea20d59ad","src/ser/fmt.rs":"7827ed07fd8897e6324f75625ba0c926a4c4e7ec2914cd067391ce54d942ac7b","src/ser/impls.rs":"8b303e6231ec6d0c0ab8402d348d75229ce91d5e50a065f8209eb7d8a35c4a17","src/ser/impossible.rs":"db17913522c1c27389c5a085113911353b9813c1b116518681362e7c8b692c3a","src/ser/mod.rs":"e5008f26bd6100f52c7223184802e63f4d046651c9db56f68602752cea20745c","src/std_error.rs":"3aac687856c035517fae44ed2906dd4a1e3184bae4bf613adcdeb73f74126c57"},"package":"53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"} \ No newline at end of file +{"files":{"Cargo.toml":"7726b0fc6476d58de05dd5342dd517da6968c3b774cb2443b09f8c1e0926d347","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"89cfc904243b611a8a2fc1c8724d6f1c2b61c166ca81676b903ddf80b8ff1c10","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/de/format.rs":"4b466a6a7f0070e884d14457759671c6ad7394fe9603708b7151ef6159258146","src/de/ignored_any.rs":"967184c86707c99b77a1cfb218dfc823f560fae227b6635aee6af19ee82962f5","src/de/impls.rs":"363f9f9400dcaf46176ab5c0a3592996abbed0618fddb51b090a7617a78eb5a0","src/de/mod.rs":"1dbddc2870da5cae0a725c7aacca83f0dabba55895f17849f2d5da254b1ebeb6","src/de/seed.rs":"e8cf0233afe0af5b8fb9e4c94f301c92729c5ba417280af9e2201b732e374a72","src/de/utf8.rs":"f17524ee0af98ec3abcfd7d0b812fbd1033263bd8e2ce2f57c1e1999ce153558","src/de/value.rs":"aa5055923e2c3fd1c1f1abdfb380a1d63d07cf4d602ef62d2df2b7da33dd8c81","src/integer128.rs":"ca49591abde2d8c4f582174533fee28f0fa9139e5d71bf22b25a6b175f8abccc","src/lib.rs":"66d086f0da93675b6d467814d593e03521007f5e319bcfdb1eb35eabb5974fa5","src/macros.rs":"3d695a51f0a07f9f719dcb5620012c21a1b084c06a6283349cabf574ceba8123","src/private/de.rs":"cc6f7fa8d0345db5918bcea549cd302a1159a7e4c5fe3e10027fbe57517ceb49","src/private/doc.rs":"e9801a43c3088fccd5f1fac76416698f948e65b647024aa9da17d673e1e8c217","src/private/mod.rs":"37b204775e572396515477b393ce793b2579de48e5971e6f596ba3723c489fd6","src/private/ser.rs":"087cf1141d1053f932f51b362ed08fd1fec43b4dbe5504bedc0c183fc8ce05e6","src/private/size_hint.rs":"605521227e9ba3100fbb9d5ea7fd5853385097c35015ce6908bd5f1ea20d59ad","src/ser/fmt.rs":"7827ed07fd8897e6324f75625ba0c926a4c4e7ec2914cd067391ce54d942ac7b","src/ser/impls.rs":"97288074fb0ff40f4178359a37879a996c7d0e5d5a7f173b9203f885d90d3ba0","src/ser/impossible.rs":"db17913522c1c27389c5a085113911353b9813c1b116518681362e7c8b692c3a","src/ser/mod.rs":"e5008f26bd6100f52c7223184802e63f4d046651c9db56f68602752cea20745c","src/std_error.rs":"3aac687856c035517fae44ed2906dd4a1e3184bae4bf613adcdeb73f74126c57"},"package":"d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"} \ No newline at end of file diff --git a/vendor/serde/Cargo.toml b/vendor/serde/Cargo.toml index 7424736c0..a319d423d 100644 --- a/vendor/serde/Cargo.toml +++ b/vendor/serde/Cargo.toml @@ -12,7 +12,7 @@ [package] rust-version = "1.13" name = "serde" -version = "1.0.143" +version = "1.0.147" authors = [ "Erick Tryzelaar ", "David Tolnay ", @@ -41,7 +41,6 @@ categories = [ ] license = "MIT OR Apache-2.0" repository = "https://github.com/serde-rs/serde" -resolver = "1" [package.metadata.playground] features = [ @@ -53,7 +52,7 @@ features = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies.serde_derive] -version = "=1.0.143" +version = "=1.0.147" optional = true [dev-dependencies.serde_derive] diff --git a/vendor/serde/src/de/ignored_any.rs b/vendor/serde/src/de/ignored_any.rs index 1d50f5ec3..9ed438e79 100644 --- a/vendor/serde/src/de/ignored_any.rs +++ b/vendor/serde/src/de/ignored_any.rs @@ -228,7 +228,7 @@ impl<'de> Visitor<'de> for IgnoredAny { where A: EnumAccess<'de>, { - data.variant::()?.1.newtype_variant() + try!(data.variant::()).1.newtype_variant() } } diff --git a/vendor/serde/src/de/impls.rs b/vendor/serde/src/de/impls.rs index c2a56b4fc..c048f7145 100644 --- a/vendor/serde/src/de/impls.rs +++ b/vendor/serde/src/de/impls.rs @@ -2268,14 +2268,14 @@ where where D: Deserializer<'de>, { - let (start, end) = deserializer.deserialize_struct( + let (start, end) = try!(deserializer.deserialize_struct( "Range", range::FIELDS, range::RangeVisitor { expecting: "struct Range", phantom: PhantomData, }, - )?; + )); Ok(start..end) } } @@ -2289,14 +2289,14 @@ where where D: Deserializer<'de>, { - let (start, end) = deserializer.deserialize_struct( + let (start, end) = try!(deserializer.deserialize_struct( "RangeInclusive", range::FIELDS, range::RangeVisitor { expecting: "struct RangeInclusive", phantom: PhantomData, }, - )?; + )); Ok(RangeInclusive::new(start, end)) } } diff --git a/vendor/serde/src/de/mod.rs b/vendor/serde/src/de/mod.rs index e8a47cfc1..d9dafbe1e 100644 --- a/vendor/serde/src/de/mod.rs +++ b/vendor/serde/src/de/mod.rs @@ -565,7 +565,7 @@ pub trait Deserialize<'de>: Sized { D: Deserializer<'de>, { // Default implementation just delegates to `deserialize` impl. - *place = Deserialize::deserialize(deserializer)?; + *place = try!(Deserialize::deserialize(deserializer)); Ok(()) } } @@ -862,10 +862,10 @@ where /// The `Deserializer` trait supports two entry point styles which enables /// different kinds of deserialization. /// -/// 1. The `deserialize` method. Self-describing data formats like JSON are able -/// to look at the serialized data and tell what it represents. For example -/// the JSON deserializer may see an opening curly brace (`{`) and know that -/// it is seeing a map. If the data format supports +/// 1. The `deserialize_any` method. Self-describing data formats like JSON are +/// able to look at the serialized data and tell what it represents. For +/// example the JSON deserializer may see an opening curly brace (`{`) and +/// know that it is seeing a map. If the data format supports /// `Deserializer::deserialize_any`, it will drive the Visitor using whatever /// type it sees in the input. JSON uses this approach when deserializing /// `serde_json::Value` which is an enum that can represent any JSON diff --git a/vendor/serde/src/de/value.rs b/vendor/serde/src/de/value.rs index e7afdd8d1..5d8886215 100644 --- a/vendor/serde/src/de/value.rs +++ b/vendor/serde/src/de/value.rs @@ -1501,7 +1501,7 @@ where where T: de::DeserializeSeed<'de>, { - match self.map.next_key_seed(seed)? { + match try!(self.map.next_key_seed(seed)) { Some(key) => Ok((key, private::map_as_enum(self.map))), None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")), } @@ -1510,6 +1510,41 @@ where //////////////////////////////////////////////////////////////////////////////// +/// A deserializer holding an `EnumAccess`. +#[derive(Clone, Debug)] +pub struct EnumAccessDeserializer { + access: A, +} + +impl EnumAccessDeserializer { + /// Construct a new `EnumAccessDeserializer`. + pub fn new(access: A) -> Self { + EnumAccessDeserializer { access: access } + } +} + +impl<'de, A> de::Deserializer<'de> for EnumAccessDeserializer +where + A: de::EnumAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self.access) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +//////////////////////////////////////////////////////////////////////////////// + mod private { use lib::*; diff --git a/vendor/serde/src/lib.rs b/vendor/serde/src/lib.rs index f2b28d985..02c57ae9d 100644 --- a/vendor/serde/src/lib.rs +++ b/vendor/serde/src/lib.rs @@ -65,7 +65,7 @@ //! [Pickle]: https://github.com/birkenfeld/serde-pickle //! [RON]: https://github.com/ron-rs/ron //! [BSON]: https://github.com/mongodb/bson-rust -//! [Avro]: https://github.com/flavray/avro-rs +//! [Avro]: https://docs.rs/apache-avro //! [JSON5]: https://github.com/callum-oakley/json5-rs //! [URL]: https://docs.rs/serde_qs //! [Envy]: https://github.com/softprops/envy @@ -81,7 +81,7 @@ //////////////////////////////////////////////////////////////////////////////// // Serde types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/serde/1.0.143")] +#![doc(html_root_url = "https://docs.rs/serde/1.0.147")] // Support using Serde without the standard library! #![cfg_attr(not(feature = "std"), no_std)] // Unstable functionality only if the user asks for it. For tracking and @@ -249,6 +249,19 @@ mod lib { pub use self::core::time::Duration; } +// None of this crate's error handling needs the `From::from` error conversion +// performed implicitly by the `?` operator or the standard library's `try!` +// macro. This simplified macro gives a 5.5% improvement in compile time +// compared to standard `try!`, and 9% improvement compared to `?`. +macro_rules! try { + ($expr:expr) => { + match $expr { + Ok(val) => val, + Err(err) => return Err(err), + } + }; +} + //////////////////////////////////////////////////////////////////////////////// #[macro_use] diff --git a/vendor/serde/src/private/de.rs b/vendor/serde/src/private/de.rs index f0697d64f..01e5bf787 100644 --- a/vendor/serde/src/private/de.rs +++ b/vendor/serde/src/private/de.rs @@ -1262,6 +1262,17 @@ mod content { { match self.content { Content::Unit => visitor.visit_unit(), + + // Allow deserializing newtype variant containing unit. + // + // #[derive(Deserialize)] + // #[serde(tag = "result")] + // enum Response { + // Success(T), + // } + // + // We want {"result":"Success"} to deserialize into Response<()>. + Content::Map(ref v) if v.is_empty() => visitor.visit_unit(), _ => Err(self.invalid_type(&visitor)), } } diff --git a/vendor/serde/src/private/ser.rs b/vendor/serde/src/private/ser.rs index 6ee999389..293d8a865 100644 --- a/vendor/serde/src/private/ser.rs +++ b/vendor/serde/src/private/ser.rs @@ -51,7 +51,6 @@ enum Unsupported { String, ByteArray, Optional, - Unit, #[cfg(any(feature = "std", feature = "alloc"))] UnitStruct, Sequence, @@ -70,7 +69,6 @@ impl Display for Unsupported { Unsupported::String => formatter.write_str("a string"), Unsupported::ByteArray => formatter.write_str("a byte array"), Unsupported::Optional => formatter.write_str("an optional"), - Unsupported::Unit => formatter.write_str("unit"), #[cfg(any(feature = "std", feature = "alloc"))] Unsupported::UnitStruct => formatter.write_str("unit struct"), Unsupported::Sequence => formatter.write_str("a sequence"), @@ -184,7 +182,9 @@ where } fn serialize_unit(self) -> Result { - Err(self.bad_type(Unsupported::Unit)) + let mut map = try!(self.delegate.serialize_map(Some(1))); + try!(map.serialize_entry(self.tag, self.variant_name)); + map.end() } fn serialize_unit_struct(self, _: &'static str) -> Result { diff --git a/vendor/serde/src/ser/impls.rs b/vendor/serde/src/ser/impls.rs index 7219f51b7..8e8655582 100644 --- a/vendor/serde/src/ser/impls.rs +++ b/vendor/serde/src/ser/impls.rs @@ -522,7 +522,7 @@ where } } -impl Serialize for RefCell +impl Serialize for RefCell where T: Serialize, { @@ -538,7 +538,7 @@ where } #[cfg(feature = "std")] -impl Serialize for Mutex +impl Serialize for Mutex where T: Serialize, { @@ -554,7 +554,7 @@ where } #[cfg(feature = "std")] -impl Serialize for RwLock +impl Serialize for RwLock where T: Serialize, { @@ -614,9 +614,10 @@ impl Serialize for SystemTime { S: Serializer, { use super::SerializeStruct; - let duration_since_epoch = self - .duration_since(UNIX_EPOCH) - .map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?; + let duration_since_epoch = match self.duration_since(UNIX_EPOCH) { + Ok(duration_since_epoch) => duration_since_epoch, + Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")), + }; let mut state = try!(serializer.serialize_struct("SystemTime", 2)); try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs())); try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos())); @@ -916,7 +917,7 @@ macro_rules! atomic_impl { S: Serializer, { // Matches the atomic ordering used in libcore for the Debug impl - self.load(Ordering::SeqCst).serialize(serializer) + self.load(Ordering::Relaxed).serialize(serializer) } } )* diff --git a/vendor/serde_derive/.cargo-checksum.json b/vendor/serde_derive/.cargo-checksum.json index 0b2fde61e..55e1585d8 100644 --- a/vendor/serde_derive/.cargo-checksum.json +++ b/vendor/serde_derive/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"9eb295576509c448841f03d77bb2ea40d587f67ad25aa1cebc3c3e99b2369123","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"c01db20e19c31505b26b9e9a5aff1c5327a7501fc88917f372a9e718edcb50ab","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/bound.rs":"268b4995a5d0a129dcbd6e32ef11f587bd271df3f6c4f7230ed54bc99f5ce871","src/de.rs":"c5a41016ce15f8176a2d7a8445ba06d2eb8de0863c1fea0dab51c395dd7dccff","src/dummy.rs":"cb154465020973be8ab6079ab8574df46f38fbe028a5561cd6b1a8bfa1a35478","src/fragment.rs":"5548ba65a53d90a296f60c1328a7a7fb040db467f59c2f5210b2fb320457145d","src/internals/ast.rs":"b019865eef92c1ddbb9029423ac22179f132dc655a51c09fb2a42f4aaef172fd","src/internals/attr.rs":"778074380c4e353b77e03aff9edf15fda9e15a0e7ec25cdfc51d79a26636ddef","src/internals/case.rs":"9492f0c5142d7b7e8cd39c86d13a855e5ce4489425adb2b96aed89e1b7851ac0","src/internals/check.rs":"11ea94257d2a2ee2276938a6beb4ae11b74c39225c1e342e6df1e7d2b2924496","src/internals/ctxt.rs":"6fa544ae52914498a62a395818ebdc1b36ac2fb5903c60afb741a864ad559f1c","src/internals/mod.rs":"f32138ff19d57eb00f88ba11f6b015efab2102657804f71ebbf386a3698dad91","src/internals/receiver.rs":"cd125ba4a3dd6250ed4737555c58627bffd630a536cd7223068eed7c10a170d8","src/internals/respan.rs":"899753859c58ce5f532a3ec4584796a52f13ed5a0533191e48c953ba5c1b52ff","src/internals/symbol.rs":"3c9ce461773b7df3bb64d82aa5a0d93052c3bb0e60209db6c0b5c10ee9cfc9cf","src/lib.rs":"0872481fb836d38af7f9819922a0269b3dbe27ce81a16443b905d44b3a03e349","src/pretend.rs":"4aa53bf6c1350fbcfc8c4997f720cde61a8eb3aab73bb8c101b0f0a74901892b","src/ser.rs":"0d99c841f6c7bc9751ab225fe42d1f8b7fe56e36903efcb4ff10bf6e35c390ba","src/try.rs":"b171b0088c23ebf4bfa07ba457881b41ac5e547d55dd16f737ea988d34badf61"},"package":"d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"} \ No newline at end of file +{"files":{"Cargo.toml":"74849419177cf3d29dc77892c9519708ac38eecd3c2d4e4367de3c171cd2d410","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7049b88cb7366be0c8e593f3ffffa313803a5b382f35686c542b4a0da3b291f3","build.rs":"c01db20e19c31505b26b9e9a5aff1c5327a7501fc88917f372a9e718edcb50ab","crates-io.md":"5c42406936cf9af6d4cd7fe0ac730c609e82fd3f15a54549518c72d0ded70c29","src/bound.rs":"268b4995a5d0a129dcbd6e32ef11f587bd271df3f6c4f7230ed54bc99f5ce871","src/de.rs":"c5a41016ce15f8176a2d7a8445ba06d2eb8de0863c1fea0dab51c395dd7dccff","src/dummy.rs":"cb154465020973be8ab6079ab8574df46f38fbe028a5561cd6b1a8bfa1a35478","src/fragment.rs":"5548ba65a53d90a296f60c1328a7a7fb040db467f59c2f5210b2fb320457145d","src/internals/ast.rs":"b019865eef92c1ddbb9029423ac22179f132dc655a51c09fb2a42f4aaef172fd","src/internals/attr.rs":"778074380c4e353b77e03aff9edf15fda9e15a0e7ec25cdfc51d79a26636ddef","src/internals/case.rs":"9492f0c5142d7b7e8cd39c86d13a855e5ce4489425adb2b96aed89e1b7851ac0","src/internals/check.rs":"11ea94257d2a2ee2276938a6beb4ae11b74c39225c1e342e6df1e7d2b2924496","src/internals/ctxt.rs":"6fa544ae52914498a62a395818ebdc1b36ac2fb5903c60afb741a864ad559f1c","src/internals/mod.rs":"f32138ff19d57eb00f88ba11f6b015efab2102657804f71ebbf386a3698dad91","src/internals/receiver.rs":"cd125ba4a3dd6250ed4737555c58627bffd630a536cd7223068eed7c10a170d8","src/internals/respan.rs":"899753859c58ce5f532a3ec4584796a52f13ed5a0533191e48c953ba5c1b52ff","src/internals/symbol.rs":"3c9ce461773b7df3bb64d82aa5a0d93052c3bb0e60209db6c0b5c10ee9cfc9cf","src/lib.rs":"82c587dfec75c78b53fc64ab9366f61213f2776cefea256c9eaeb18193c8cbf4","src/pretend.rs":"4aa53bf6c1350fbcfc8c4997f720cde61a8eb3aab73bb8c101b0f0a74901892b","src/ser.rs":"0d99c841f6c7bc9751ab225fe42d1f8b7fe56e36903efcb4ff10bf6e35c390ba","src/try.rs":"b171b0088c23ebf4bfa07ba457881b41ac5e547d55dd16f737ea988d34badf61"},"package":"4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"} \ No newline at end of file diff --git a/vendor/serde_derive/Cargo.toml b/vendor/serde_derive/Cargo.toml index be824e985..dc5abf1b4 100644 --- a/vendor/serde_derive/Cargo.toml +++ b/vendor/serde_derive/Cargo.toml @@ -12,7 +12,7 @@ [package] rust-version = "1.31" name = "serde_derive" -version = "1.0.143" +version = "1.0.147" authors = [ "Erick Tryzelaar ", "David Tolnay ", @@ -38,7 +38,6 @@ keywords = [ categories = ["no-std"] license = "MIT OR Apache-2.0" repository = "https://github.com/serde-rs/serde" -resolver = "1" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/vendor/serde_derive/src/lib.rs b/vendor/serde_derive/src/lib.rs index edf7c4157..fc8529e40 100644 --- a/vendor/serde_derive/src/lib.rs +++ b/vendor/serde_derive/src/lib.rs @@ -13,7 +13,7 @@ //! //! [https://serde.rs/derive.html]: https://serde.rs/derive.html -#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.143")] +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.147")] #![allow(unknown_lints, bare_trait_objects)] // Ignored clippy lints #![allow( diff --git a/vendor/serde_json/.cargo-checksum.json b/vendor/serde_json/.cargo-checksum.json index 8174fa507..69f778237 100644 --- a/vendor/serde_json/.cargo-checksum.json +++ b/vendor/serde_json/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CONTRIBUTING.md":"f5270cafba66223a7b51ffc0d286075a17bb7cd88762fc80d333d3102629f4d8","Cargo.toml":"0b496503599dc9b1e962e41838c125db7d8811ad6f061ba6a865ed94ef43ffa0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7c6217e41b058880a37e01cf8caf205daa397d33cc2199f9fa1634048bc088c5","build.rs":"20e23e5bfe6fc8155fef0e0da036ebc1f81b34078fe86f929c8247b6f4317b99","src/de.rs":"0048bb57f39c7014a491c044d527598270fe417f1676ec7ba4529fea337746bc","src/error.rs":"abb92a9bf62cb7f47141a733a9fd66ec8c369615d7e6f633d3536fd2a5ac74a2","src/features_check/error.rs":"d7359f864afbfe105a38abea9f563dc423036ebc4c956a5695a4beef144dc7ec","src/features_check/mod.rs":"2209f8d5c46b50c8a3b8dc22338dcaf0135d192e8b05d2f456cbe6a73104e958","src/io/core.rs":"9a4146802391fd202a36bebbf3b14b715ae09d8828cbe8e06a01214c470ebf5c","src/io/mod.rs":"fd1ed5080495cab21117f6f7d3c2c9e3687cad0c69a0cd087b08a145a9e672da","src/iter.rs":"f832c469cd7999d26ba9b76baa69b257a212a7edb3dfdf9b1d1bb35e8da85fa9","src/lexical/algorithm.rs":"4fbeb1994049348d1fc388dd1a29e481f8abb8fe1e28bfebf50f3bbce5fa5fbe","src/lexical/bhcomp.rs":"b7c68d74c0055eb67ec2c1bcf27bbc28bef8f1bbc43db8eb94ba69892230add6","src/lexical/bignum.rs":"4230cde10dc8eae456a713cf90ec4e48dff4b1d0c542621ce7f00f39ade2645e","src/lexical/cached.rs":"0e127398691f8042c19cde209e7f4b0161f0f3150342430145929f711e6fdac8","src/lexical/cached_float80.rs":"0f8f74a22cb7d871322a9893bffd0255ca10bf9dffd13afb2462dd3d7f51805f","src/lexical/digit.rs":"a265b9072194a62a67dfc4df3c86d4213097cf3f82280d025e0012a5a262fd9d","src/lexical/errors.rs":"6bc993febceb7dd96ac1c8c5c53b5f5a30297016c0f813ed8ff8d7938d01534d","src/lexical/exponent.rs":"387e945b97dc7ba48a7091c50d228a0dde3a1c4145703d4ab9c31191a91693b0","src/lexical/float.rs":"fe356213c92a049f4bef2f58bc0e3a26866ca06b8c1d74d0f961c5b883852cad","src/lexical/large_powers.rs":"34537f5c701afce1ec2a1fd3c14950381b2e27c9ad74f002c91f3708e8da9ca5","src/lexical/large_powers32.rs":"d533037c6141e6671102aee490c9cdeaba81e667ddca781b2b99db2c455e4a1a","src/lexical/large_powers64.rs":"745dd7c0cbe499eec027ef586248881011d9df20c7efab7929c1807b59886ba1","src/lexical/math.rs":"27e22b724cdf990cdacd0ccfc3749e6e2eb7529d43ebf6e95b1999560b9e199a","src/lexical/mod.rs":"4b4c5228779c0f135a4cb018700e3bcd495da48b74421a86f6b8b304acdef924","src/lexical/num.rs":"cf705c62612e31d704f43d94a633ea1243c6befad7ef5792e2e881a7fd21e809","src/lexical/parse.rs":"c2bfac4c70a19938ced61e991f4ec606764887cf12bac1a0978b5b5318a56aac","src/lexical/rounding.rs":"697207248ba17b7f4965aedb11d276261ada5b06d9c6265d8fd6246664ff6e3c","src/lexical/shift.rs":"bc1ed053dd63d45ac9c35302f18de9f00d94027f28af4ab749c9248439de832a","src/lexical/small_powers.rs":"4608dd218b8002435db7e1ec79d2d0fef5f47ae257b93353326d52ecc80cccda","src/lib.rs":"25ae8f37112a5628b2919619d360dfea6d238e9089fe15cb1869fb70d01bf922","src/macros.rs":"c9f23156faec8d5216d72b6a97eebd768efb3f75870a6e2beed824308587b998","src/map.rs":"54e5e8ba63cf12a24f2c0257b1ace12f1935ca6d862e7b657209ee6634bb771f","src/number.rs":"e4e2ad248acbeed5a674f8823251387a2dbc9b3730bde831a88c8c10621e7a38","src/raw.rs":"ee2b4ed085d8488e72c5a19791aae9de569d6c1381e9e64ff71afa03d5cf902a","src/read.rs":"49b4b1d067b6485cbded28fb961666ab5df82c36661af722dbae756efb6b2891","src/ser.rs":"44a57aa347c2a3b234635622b675fa3b2c30b818212f5a5eef02027cf3406a84","src/value/de.rs":"64a86f6c14c2c04abc4b6f06b90bfcbda097b37b7f3e990576801f170d4af1e4","src/value/from.rs":"1968835c63dcd4058850162e3a8714b5a7e20eeec458fd4c200aa9ef0515f94c","src/value/index.rs":"8a99d8d50f5674181ced22f6e81dc529eaecb01e543e30346e51fe42cb4b8a5f","src/value/mod.rs":"47ff472a2426a135c7acdf59c4c83c7b7ce986269f10ec31c809a2b35152beda","src/value/partial_eq.rs":"95de799d57f7f4310b64a9488c0a7286dee76dba4329cb69a96298a887e58586","src/value/ser.rs":"185539665cf3ab2fb5499a8e8e069ec75afbc2f07a2fbed0f8f9bcffd7ab729b","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/debug.rs":"a8451217c1e127ad6e653ef11e0513525ee350e1e37dd575758a8ee9301b28fb","tests/lexical.rs":"383e06283e15e1db7c6b818da3c84a3afa0059f6e9fc994b069919d81346ab91","tests/lexical/algorithm.rs":"da378df9ee24bfa033968d5c94e91b58e52c39bf6c825dec51c3eb7250cc5874","tests/lexical/exponent.rs":"26ea92abc654a6a88a8281552bca2f76ea1fa4c17d66a1dd6defe14f7d89b666","tests/lexical/float.rs":"0440f2d85c993bcccd925096d7f4136bf624ffd66b3c7ee565d158390685eb11","tests/lexical/math.rs":"4874be2103be5fbe8b8015354414df271ffa00fd815546fc077f15fb4d7a5a37","tests/lexical/num.rs":"6e650c40de85ed72ac06b6bf1487ba161f3824e26d827df6cfdf2bbdb8d05a05","tests/lexical/parse.rs":"17c73e0a59d462716d974b8dd23a291eb6efdc3a933248874e5eab7e7209d67f","tests/lexical/rounding.rs":"6c56e39ba534616c1b2146e8efa6eb57aed322e683bf23183cd32a61fae6447e","tests/macros/mod.rs":"93aa1d54af20bc2c55b6ae8db73c1414cda2626eb9fa7bd57b9d613a3c6e6a19","tests/map.rs":"dcc5212242e4e93703c4335d54f5603b0211b33d6fb5ab410bb630cda6d46b09","tests/regression.rs":"86731134bfb9bb693d9a4fc62393027de80a8bf031109ea6c7ea475b1ebdde8d","tests/regression/issue520.rs":"d146be3472db902b48127d65fe83aa9f698143aca9074c83cd1a9d5dd28e3ec3","tests/regression/issue795.rs":"582e2e7c68113f05a4b1d2cb556a2df7cc77f2ce8164a32c5cc58ae68abb60ec","tests/regression/issue845.rs":"8bd64588fc344e119d0e9e5e7604236e7c168c574b0692033f15278e216a6b9c","tests/stream.rs":"c7d91014538ecd8f495b196d40e999ab2745f2e69fa2ff9e52521605dc6ce856","tests/test.rs":"6b0f60187c0a936dfe57686d334269863495a01446f75e1ed2e1d641861f232b","tests/ui/missing_colon.rs":"d07e0c34d98eb43465f0a0310f2c0b5d5b0d26d243b352a1c6bbe6ad3b27eda9","tests/ui/missing_colon.stderr":"8dd5c769f36ede610172f69140a3faf603cd4590cb4abc8eaa1b499fe3537ad9","tests/ui/missing_comma.rs":"b8a9662f99c3e6dd2b6417892c37640578ce91d3a8365bf10c1f686a3227aa87","tests/ui/missing_comma.stderr":"c6acd42b41ee78b197c77ff513fc77a9495423bb912b188ce6ea2963b65dd82c","tests/ui/missing_value.rs":"bca25d67127fb88e7c191c7b03af5a4ce8a9abb630f3d2e6a6c1e77e213dc9a4","tests/ui/missing_value.stderr":"15727519f300c64d6968cd99398227f7fbbf660825459a0768f2bf947eadf752","tests/ui/not_found.rs":"d0a7adb309879ff65aee115b52cc33d36f4bad353cf97c4effc34a6128c2bee3","tests/ui/not_found.stderr":"359b751c0c21fab6d460daef4d5f73a265f7769c9b578f98ea3cb6cbf2387643","tests/ui/parse_expr.rs":"32e6d51f528db3d1ab0ed1e24765b865be393565c26f77413c5aa39d601ac563","tests/ui/parse_expr.stderr":"edfbaa14fa52f6fdb319c1e1aeac4f8870258930850e669d56aa94ef59ce4432","tests/ui/parse_key.rs":"18829b2af320d5cf8a0a5cd3aaf84c7e92cc874651c30e45a3acafb76c2d8b93","tests/ui/parse_key.stderr":"fcb44e060b804a4762b7291e128c41d7010ffa8ab820b8828fd13fbe6d405ca6","tests/ui/unexpected_after_array_element.rs":"a343fc3104431720bdfcf330bcc3cfcd98c8dec3e951133b495242478b0b7eb3","tests/ui/unexpected_after_array_element.stderr":"e0547b280bcc006155c481c66b49fbe2df577e9e741b7f75fcf6ab21e9e20969","tests/ui/unexpected_after_map_entry.rs":"6e3bd2def435ca610e346bbc75cdbaf61963eb2ef1885bb5f76781ba1fac37ef","tests/ui/unexpected_after_map_entry.stderr":"57b7fc4fbff089dd5e5d76f4eba56a3357273c3f4b7ce93eea60891762cc4275","tests/ui/unexpected_colon.rs":"a313cff3fed4be4c33f1eda5d0c5c98147fb835a56d36470d9f367352c1d61ef","tests/ui/unexpected_colon.stderr":"41585758c8764f485e5c98b0cf6f5ad796f5482839f8644189d980ff422316cd","tests/ui/unexpected_comma.rs":"55a8b684bde1ce905837cce719fd457d8898b61cebc27e5b420d05cb6be97256","tests/ui/unexpected_comma.stderr":"847bb88d0db4d8a89b2a339d57eeb2d75af7670f31fcfdc687373a8681cc1653"},"package":"e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"} \ No newline at end of file +{"files":{"CONTRIBUTING.md":"f5270cafba66223a7b51ffc0d286075a17bb7cd88762fc80d333d3102629f4d8","Cargo.toml":"6b32727a214b53c295b1c7ae174cee020957e5c7439ef842e94b391797098cba","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7c6217e41b058880a37e01cf8caf205daa397d33cc2199f9fa1634048bc088c5","build.rs":"20e23e5bfe6fc8155fef0e0da036ebc1f81b34078fe86f929c8247b6f4317b99","src/de.rs":"0048bb57f39c7014a491c044d527598270fe417f1676ec7ba4529fea337746bc","src/error.rs":"abb92a9bf62cb7f47141a733a9fd66ec8c369615d7e6f633d3536fd2a5ac74a2","src/features_check/error.rs":"d7359f864afbfe105a38abea9f563dc423036ebc4c956a5695a4beef144dc7ec","src/features_check/mod.rs":"2209f8d5c46b50c8a3b8dc22338dcaf0135d192e8b05d2f456cbe6a73104e958","src/io/core.rs":"9a4146802391fd202a36bebbf3b14b715ae09d8828cbe8e06a01214c470ebf5c","src/io/mod.rs":"fd1ed5080495cab21117f6f7d3c2c9e3687cad0c69a0cd087b08a145a9e672da","src/iter.rs":"f832c469cd7999d26ba9b76baa69b257a212a7edb3dfdf9b1d1bb35e8da85fa9","src/lexical/algorithm.rs":"4fbeb1994049348d1fc388dd1a29e481f8abb8fe1e28bfebf50f3bbce5fa5fbe","src/lexical/bhcomp.rs":"b7c68d74c0055eb67ec2c1bcf27bbc28bef8f1bbc43db8eb94ba69892230add6","src/lexical/bignum.rs":"4230cde10dc8eae456a713cf90ec4e48dff4b1d0c542621ce7f00f39ade2645e","src/lexical/cached.rs":"0e127398691f8042c19cde209e7f4b0161f0f3150342430145929f711e6fdac8","src/lexical/cached_float80.rs":"0f8f74a22cb7d871322a9893bffd0255ca10bf9dffd13afb2462dd3d7f51805f","src/lexical/digit.rs":"a265b9072194a62a67dfc4df3c86d4213097cf3f82280d025e0012a5a262fd9d","src/lexical/errors.rs":"6bc993febceb7dd96ac1c8c5c53b5f5a30297016c0f813ed8ff8d7938d01534d","src/lexical/exponent.rs":"387e945b97dc7ba48a7091c50d228a0dde3a1c4145703d4ab9c31191a91693b0","src/lexical/float.rs":"fe356213c92a049f4bef2f58bc0e3a26866ca06b8c1d74d0f961c5b883852cad","src/lexical/large_powers.rs":"34537f5c701afce1ec2a1fd3c14950381b2e27c9ad74f002c91f3708e8da9ca5","src/lexical/large_powers32.rs":"d533037c6141e6671102aee490c9cdeaba81e667ddca781b2b99db2c455e4a1a","src/lexical/large_powers64.rs":"745dd7c0cbe499eec027ef586248881011d9df20c7efab7929c1807b59886ba1","src/lexical/math.rs":"27e22b724cdf990cdacd0ccfc3749e6e2eb7529d43ebf6e95b1999560b9e199a","src/lexical/mod.rs":"4b4c5228779c0f135a4cb018700e3bcd495da48b74421a86f6b8b304acdef924","src/lexical/num.rs":"cf705c62612e31d704f43d94a633ea1243c6befad7ef5792e2e881a7fd21e809","src/lexical/parse.rs":"c2bfac4c70a19938ced61e991f4ec606764887cf12bac1a0978b5b5318a56aac","src/lexical/rounding.rs":"697207248ba17b7f4965aedb11d276261ada5b06d9c6265d8fd6246664ff6e3c","src/lexical/shift.rs":"bc1ed053dd63d45ac9c35302f18de9f00d94027f28af4ab749c9248439de832a","src/lexical/small_powers.rs":"4608dd218b8002435db7e1ec79d2d0fef5f47ae257b93353326d52ecc80cccda","src/lib.rs":"3787fa7e66342e654359ae6aa81c0683a1260f819ad0e3a803363407122937cd","src/macros.rs":"c9f23156faec8d5216d72b6a97eebd768efb3f75870a6e2beed824308587b998","src/map.rs":"54e5e8ba63cf12a24f2c0257b1ace12f1935ca6d862e7b657209ee6634bb771f","src/number.rs":"157378ce0c01700b99839b8d5578fa46e4d525e6ec7d49e1920537618f51768f","src/raw.rs":"ee2b4ed085d8488e72c5a19791aae9de569d6c1381e9e64ff71afa03d5cf902a","src/read.rs":"49b4b1d067b6485cbded28fb961666ab5df82c36661af722dbae756efb6b2891","src/ser.rs":"44a57aa347c2a3b234635622b675fa3b2c30b818212f5a5eef02027cf3406a84","src/value/de.rs":"64a86f6c14c2c04abc4b6f06b90bfcbda097b37b7f3e990576801f170d4af1e4","src/value/from.rs":"1968835c63dcd4058850162e3a8714b5a7e20eeec458fd4c200aa9ef0515f94c","src/value/index.rs":"8a99d8d50f5674181ced22f6e81dc529eaecb01e543e30346e51fe42cb4b8a5f","src/value/mod.rs":"47ff472a2426a135c7acdf59c4c83c7b7ce986269f10ec31c809a2b35152beda","src/value/partial_eq.rs":"95de799d57f7f4310b64a9488c0a7286dee76dba4329cb69a96298a887e58586","src/value/ser.rs":"3dafa51d46fa7d742398863c4f3a0251afc6193dac75e6231655c9c1690dcd54","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/debug.rs":"a8451217c1e127ad6e653ef11e0513525ee350e1e37dd575758a8ee9301b28fb","tests/lexical.rs":"383e06283e15e1db7c6b818da3c84a3afa0059f6e9fc994b069919d81346ab91","tests/lexical/algorithm.rs":"da378df9ee24bfa033968d5c94e91b58e52c39bf6c825dec51c3eb7250cc5874","tests/lexical/exponent.rs":"26ea92abc654a6a88a8281552bca2f76ea1fa4c17d66a1dd6defe14f7d89b666","tests/lexical/float.rs":"0440f2d85c993bcccd925096d7f4136bf624ffd66b3c7ee565d158390685eb11","tests/lexical/math.rs":"4874be2103be5fbe8b8015354414df271ffa00fd815546fc077f15fb4d7a5a37","tests/lexical/num.rs":"6e650c40de85ed72ac06b6bf1487ba161f3824e26d827df6cfdf2bbdb8d05a05","tests/lexical/parse.rs":"17c73e0a59d462716d974b8dd23a291eb6efdc3a933248874e5eab7e7209d67f","tests/lexical/rounding.rs":"6c56e39ba534616c1b2146e8efa6eb57aed322e683bf23183cd32a61fae6447e","tests/macros/mod.rs":"93aa1d54af20bc2c55b6ae8db73c1414cda2626eb9fa7bd57b9d613a3c6e6a19","tests/map.rs":"dcc5212242e4e93703c4335d54f5603b0211b33d6fb5ab410bb630cda6d46b09","tests/regression.rs":"86731134bfb9bb693d9a4fc62393027de80a8bf031109ea6c7ea475b1ebdde8d","tests/regression/issue520.rs":"d146be3472db902b48127d65fe83aa9f698143aca9074c83cd1a9d5dd28e3ec3","tests/regression/issue795.rs":"582e2e7c68113f05a4b1d2cb556a2df7cc77f2ce8164a32c5cc58ae68abb60ec","tests/regression/issue845.rs":"8bd64588fc344e119d0e9e5e7604236e7c168c574b0692033f15278e216a6b9c","tests/stream.rs":"c7d91014538ecd8f495b196d40e999ab2745f2e69fa2ff9e52521605dc6ce856","tests/test.rs":"809b07b6990004a389780fc45d7e81539bf95003a3f410873ce924153ae01ae0","tests/ui/missing_colon.rs":"d07e0c34d98eb43465f0a0310f2c0b5d5b0d26d243b352a1c6bbe6ad3b27eda9","tests/ui/missing_colon.stderr":"8dd5c769f36ede610172f69140a3faf603cd4590cb4abc8eaa1b499fe3537ad9","tests/ui/missing_comma.rs":"b8a9662f99c3e6dd2b6417892c37640578ce91d3a8365bf10c1f686a3227aa87","tests/ui/missing_comma.stderr":"c6acd42b41ee78b197c77ff513fc77a9495423bb912b188ce6ea2963b65dd82c","tests/ui/missing_value.rs":"bca25d67127fb88e7c191c7b03af5a4ce8a9abb630f3d2e6a6c1e77e213dc9a4","tests/ui/missing_value.stderr":"15727519f300c64d6968cd99398227f7fbbf660825459a0768f2bf947eadf752","tests/ui/not_found.rs":"d0a7adb309879ff65aee115b52cc33d36f4bad353cf97c4effc34a6128c2bee3","tests/ui/not_found.stderr":"359b751c0c21fab6d460daef4d5f73a265f7769c9b578f98ea3cb6cbf2387643","tests/ui/parse_expr.rs":"32e6d51f528db3d1ab0ed1e24765b865be393565c26f77413c5aa39d601ac563","tests/ui/parse_expr.stderr":"edfbaa14fa52f6fdb319c1e1aeac4f8870258930850e669d56aa94ef59ce4432","tests/ui/parse_key.rs":"18829b2af320d5cf8a0a5cd3aaf84c7e92cc874651c30e45a3acafb76c2d8b93","tests/ui/parse_key.stderr":"fcb44e060b804a4762b7291e128c41d7010ffa8ab820b8828fd13fbe6d405ca6","tests/ui/unexpected_after_array_element.rs":"a343fc3104431720bdfcf330bcc3cfcd98c8dec3e951133b495242478b0b7eb3","tests/ui/unexpected_after_array_element.stderr":"e0547b280bcc006155c481c66b49fbe2df577e9e741b7f75fcf6ab21e9e20969","tests/ui/unexpected_after_map_entry.rs":"6e3bd2def435ca610e346bbc75cdbaf61963eb2ef1885bb5f76781ba1fac37ef","tests/ui/unexpected_after_map_entry.stderr":"57b7fc4fbff089dd5e5d76f4eba56a3357273c3f4b7ce93eea60891762cc4275","tests/ui/unexpected_colon.rs":"a313cff3fed4be4c33f1eda5d0c5c98147fb835a56d36470d9f367352c1d61ef","tests/ui/unexpected_colon.stderr":"41585758c8764f485e5c98b0cf6f5ad796f5482839f8644189d980ff422316cd","tests/ui/unexpected_comma.rs":"55a8b684bde1ce905837cce719fd457d8898b61cebc27e5b420d05cb6be97256","tests/ui/unexpected_comma.stderr":"847bb88d0db4d8a89b2a339d57eeb2d75af7670f31fcfdc687373a8681cc1653"},"package":"41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"} \ No newline at end of file diff --git a/vendor/serde_json/Cargo.toml b/vendor/serde_json/Cargo.toml index a79bb3b1c..1e1aebb8e 100644 --- a/vendor/serde_json/Cargo.toml +++ b/vendor/serde_json/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.36" name = "serde_json" -version = "1.0.85" +version = "1.0.86" authors = [ "Erick Tryzelaar ", "David Tolnay ", diff --git a/vendor/serde_json/src/lib.rs b/vendor/serde_json/src/lib.rs index cf4b83d19..3a1983c3f 100644 --- a/vendor/serde_json/src/lib.rs +++ b/vendor/serde_json/src/lib.rs @@ -300,7 +300,7 @@ //! [macro]: https://docs.serde.rs/serde_json/macro.json.html //! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core -#![doc(html_root_url = "https://docs.rs/serde_json/1.0.85")] +#![doc(html_root_url = "https://docs.rs/serde_json/1.0.86")] // Ignored clippy lints #![allow( clippy::collapsible_else_if, diff --git a/vendor/serde_json/src/number.rs b/vendor/serde_json/src/number.rs index df8819259..3c8f6f1bf 100644 --- a/vendor/serde_json/src/number.rs +++ b/vendor/serde_json/src/number.rs @@ -1,19 +1,22 @@ use crate::de::ParserNumber; use crate::error::Error; +#[cfg(feature = "arbitrary_precision")] +use crate::error::ErrorCode; +#[cfg(feature = "arbitrary_precision")] +use alloc::borrow::ToOwned; +#[cfg(feature = "arbitrary_precision")] +use alloc::string::{String, ToString}; use core::fmt::{self, Debug, Display}; #[cfg(not(feature = "arbitrary_precision"))] use core::hash::{Hash, Hasher}; use serde::de::{self, Unexpected, Visitor}; +#[cfg(feature = "arbitrary_precision")] +use serde::de::{IntoDeserializer, MapAccess}; use serde::{ forward_to_deserialize_any, serde_if_integer128, Deserialize, Deserializer, Serialize, Serializer, }; -#[cfg(feature = "arbitrary_precision")] -use crate::error::ErrorCode; -#[cfg(feature = "arbitrary_precision")] -use serde::de::{IntoDeserializer, MapAccess}; - #[cfg(feature = "arbitrary_precision")] pub(crate) const TOKEN: &str = "$serde_json::private::Number"; diff --git a/vendor/serde_json/src/value/ser.rs b/vendor/serde_json/src/value/ser.rs index c142dacbf..37e495f65 100644 --- a/vendor/serde_json/src/value/ser.rs +++ b/vendor/serde_json/src/value/ser.rs @@ -195,7 +195,7 @@ impl serde::Serializer for Serializer { T: ?Sized + Serialize, { let mut values = Map::new(); - values.insert(String::from(variant), tri!(to_value(&value))); + values.insert(String::from(variant), tri!(to_value(value))); Ok(Value::Object(values)) } @@ -314,7 +314,7 @@ impl serde::ser::SerializeSeq for SerializeVec { where T: ?Sized + Serialize, { - self.vec.push(tri!(to_value(&value))); + self.vec.push(tri!(to_value(value))); Ok(()) } @@ -363,7 +363,7 @@ impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { where T: ?Sized + Serialize, { - self.vec.push(tri!(to_value(&value))); + self.vec.push(tri!(to_value(value))); Ok(()) } @@ -406,7 +406,7 @@ impl serde::ser::SerializeMap for SerializeMap { // Panic because this indicates a bug in the program rather than an // expected failure. let key = key.expect("serialize_value called before serialize_key"); - map.insert(key, tri!(to_value(&value))); + map.insert(key, tri!(to_value(value))); Ok(()) } #[cfg(feature = "arbitrary_precision")] @@ -663,7 +663,7 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant { where T: ?Sized + Serialize, { - self.map.insert(String::from(key), tri!(to_value(&value))); + self.map.insert(String::from(key), tri!(to_value(value))); Ok(()) } diff --git a/vendor/serde_json/tests/test.rs b/vendor/serde_json/tests/test.rs index 0aeaff88d..aa5b5caa0 100644 --- a/vendor/serde_json/tests/test.rs +++ b/vendor/serde_json/tests/test.rs @@ -95,7 +95,7 @@ where let s = to_string(value).unwrap(); assert_eq!(s, out); - let v = to_value(&value).unwrap(); + let v = to_value(value).unwrap(); let s = to_string(&v).unwrap(); assert_eq!(s, out); } @@ -111,7 +111,7 @@ where let s = to_string_pretty(value).unwrap(); assert_eq!(s, out); - let v = to_value(&value).unwrap(); + let v = to_value(value).unwrap(); let s = to_string_pretty(&v).unwrap(); assert_eq!(s, out); } @@ -1107,7 +1107,7 @@ fn test_parse_string() { ]); test_parse_ok(vec![ - ("\"\"", "".to_string()), + ("\"\"", String::new()), ("\"foo\"", "foo".to_string()), (" \"foo\" ", "foo".to_string()), ("\"\\\"\"", "\"".to_string()), diff --git a/vendor/smallvec/.cargo-checksum.json b/vendor/smallvec/.cargo-checksum.json index 8f4d7bf91..e9fa9e1e6 100644 --- a/vendor/smallvec/.cargo-checksum.json +++ b/vendor/smallvec/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"03ae7e6a133c5fd1685687aee67bc841642a4fd0deeb0d4d88b9fe27af37ba9e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"e2a235d68be20996014c00468b369887d2041ce95486625de3cef35b8f2e4acd","scripts/run_miri.sh":"0d0b8c54c73fa9da1217d29ed0984f8328dd9fb61bb5a02db44458c360cdc3c4","src/arbitrary.rs":"22e55cfbf60374945b30e6d0855129eff67cd8b878cef6fa997e1f4be67b9e3d","src/lib.rs":"264a6e6863aeb21cd779588c2add8421ea1a5861a9bb8ef49e9dc529be8d3b20","src/specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471","src/tests.rs":"2bcf69dc0597e4e8a59a92566a3dd5c82ec3a1ea563aa006ea0f4a2722cb2d17","tests/macro.rs":"22ad4f6f104a599fdcba19cad8834105b8656b212fb6c7573a427d447f5db14f"},"package":"2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"} \ No newline at end of file +{"files":{"Cargo.toml":"e8b7e22c87fa34e053c12b3751ec0c7b25b37bd1285959710321a7a00861f392","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"e2a235d68be20996014c00468b369887d2041ce95486625de3cef35b8f2e4acd","debug_metadata/README.md":"dc8fbf896055359a94f7bfdfae7604e0bcfc8b10998a218d484d9fffdf83637c","debug_metadata/smallvec.natvis":"68aed2322bdc13ed6fa2021dc9625346174d73590929acbc2f95c98785c8dee4","scripts/run_miri.sh":"74a9f9adc43f986e81977b03846f7dd00122a0150bd8ec3fe4842a1a787e0f07","src/arbitrary.rs":"22e55cfbf60374945b30e6d0855129eff67cd8b878cef6fa997e1f4be67b9e3d","src/lib.rs":"35c60a9d9240853e9f6f84b7a44ff6a3197a87ab404f5ab1cd8ebeeeb72e54da","src/specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471","src/tests.rs":"2bcf69dc0597e4e8a59a92566a3dd5c82ec3a1ea563aa006ea0f4a2722cb2d17","tests/debugger_visualizer.rs":"87480900add8579e1285741d5a0041063b6d888328e11854ab2cdc2960d7ddb1","tests/macro.rs":"22ad4f6f104a599fdcba19cad8834105b8656b212fb6c7573a427d447f5db14f"},"package":"a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"} \ No newline at end of file diff --git a/vendor/smallvec/Cargo.toml b/vendor/smallvec/Cargo.toml index fd490da15..a365ca18e 100644 --- a/vendor/smallvec/Cargo.toml +++ b/vendor/smallvec/Cargo.toml @@ -12,18 +12,35 @@ [package] edition = "2018" name = "smallvec" -version = "1.9.0" +version = "1.10.0" authors = ["The Servo Project Developers"] description = "'Small vector' optimization: store up to a small number of items on the stack" documentation = "https://docs.rs/smallvec/" readme = "README.md" -keywords = ["small", "vec", "vector", "stack", "no_std"] +keywords = [ + "small", + "vec", + "vector", + "stack", + "no_std", +] categories = ["data-structures"] license = "MIT OR Apache-2.0" repository = "https://github.com/servo/rust-smallvec" + [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[[test]] +name = "debugger_visualizer" +path = "tests/debugger_visualizer.rs" +test = false +required-features = ["debugger_visualizer"] + [dependencies.arbitrary] version = "1" optional = true @@ -32,12 +49,20 @@ optional = true version = "1" optional = true default-features = false + [dev-dependencies.bincode] version = "1.0.1" +[dev-dependencies.debugger_test] +version = "0.1.0" + +[dev-dependencies.debugger_test_parser] +version = "0.1.0" + [features] const_generics = [] const_new = ["const_generics"] +debugger_visualizer = [] may_dangle = [] specialization = [] union = [] diff --git a/vendor/smallvec/debug_metadata/README.md b/vendor/smallvec/debug_metadata/README.md new file mode 100644 index 000000000..137500813 --- /dev/null +++ b/vendor/smallvec/debug_metadata/README.md @@ -0,0 +1,111 @@ +## Debugger Visualizers + +Many languages and debuggers enable developers to control how a type is +displayed in a debugger. These are called "debugger visualizations" or "debugger +views". + +The Windows debuggers (WinDbg\CDB) support defining custom debugger visualizations using +the `Natvis` framework. To use Natvis, developers write XML documents using the natvis +schema that describe how debugger types should be displayed with the `.natvis` extension. +(See: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) +The Natvis files provide patterns which match type names a description of how to display +those types. + +The Natvis schema can be found either online (See: https://code.visualstudio.com/docs/cpp/natvis#_schema) +or locally at `\Xml\Schemas\1033\natvis.xsd`. + +The GNU debugger (GDB) supports defining custom debugger views using Pretty Printers. +Pretty printers are written as python scripts that describe how a type should be displayed +when loaded up in GDB/LLDB. (See: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html#Pretty-Printing) +The pretty printers provide patterns, which match type names, and for matching +types, descibe how to display those types. (For writing a pretty printer, see: https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter). + +### Embedding Visualizers + +Through the use of the currently unstable `#[debugger_visualizer]` attribute, the `smallvec` +crate can embed debugger visualizers into the crate metadata. + +Currently the two types of visualizers supported are Natvis and Pretty printers. + +For Natvis files, when linking an executable with a crate that includes Natvis files, +the MSVC linker will embed the contents of all Natvis files into the generated `PDB`. + +For pretty printers, the compiler will encode the contents of the pretty printer +in the `.debug_gdb_scripts` section of the `ELF` generated. + +### Testing Visualizers + +The `smallvec` crate supports testing debugger visualizers defined for this crate. The entry point for +these tests are `tests/debugger_visualizer.rs`. These tests are defined using the `debugger_test` and +`debugger_test_parser` crates. The `debugger_test` crate is a proc macro crate which defines a +single proc macro attribute, `#[debugger_test]`. For more detailed information about this crate, +see https://crates.io/crates/debugger_test. The CI pipeline for the `smallvec` crate has been updated +to run the debugger visualizer tests to ensure debugger visualizers do not become broken/stale. + +The `#[debugger_test]` proc macro attribute may only be used on test functions and will run the +function under the debugger specified by the `debugger` meta item. + +This proc macro attribute has 3 required values: + +1. The first required meta item, `debugger`, takes a string value which specifies the debugger to launch. +2. The second required meta item, `commands`, takes a string of new line (`\n`) separated list of debugger +commands to run. +3. The third required meta item, `expected_statements`, takes a string of new line (`\n`) separated list of +statements that must exist in the debugger output. Pattern matching through regular expressions is also +supported by using the `pattern:` prefix for each expected statement. + +#### Example: + +```rust +#[debugger_test( + debugger = "cdb", + commands = "command1\ncommand2\ncommand3", + expected_statements = "statement1\nstatement2\nstatement3")] +fn test() { + +} +``` + +Using a multiline string is also supported, with a single debugger command/expected statement per line: + +```rust +#[debugger_test( + debugger = "cdb", + commands = " +command1 +command2 +command3", + expected_statements = " +statement1 +pattern:statement[0-9]+ +statement3")] +fn test() { + +} +``` + +In the example above, the second expected statement uses pattern matching through a regular expression +by using the `pattern:` prefix. + +#### Testing Locally + +Currently, only Natvis visualizations have been defined for the `smallvec` crate via `debug_metadata/smallvec.natvis`, +which means the `tests/debugger_visualizer.rs` tests need to be run on Windows using the `*-pc-windows-msvc` targets. +To run these tests locally, first ensure the debugging tools for Windows are installed or install them following +the steps listed here, [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). +Once the debugging tools have been installed, the tests can be run in the same manner as they are in the CI +pipeline. + +#### Note + +When running the debugger visualizer tests, `tests/debugger_visualizer.rs`, they need to be run consecutively +and not in parallel. This can be achieved by passing the flag `--test-threads=1` to rustc. This is due to +how the debugger tests are run. Each test marked with the `#[debugger_test]` attribute launches a debugger +and attaches it to the current test process. If tests are running in parallel, the test will try to attach +a debugger to the current process which may already have a debugger attached causing the test to fail. + +For example: + +``` +cargo test --test debugger_visualizer --features debugger_visualizer -- --test-threads=1 +``` diff --git a/vendor/smallvec/debug_metadata/smallvec.natvis b/vendor/smallvec/debug_metadata/smallvec.natvis new file mode 100644 index 000000000..b38d47cb7 --- /dev/null +++ b/vendor/smallvec/debug_metadata/smallvec.natvis @@ -0,0 +1,35 @@ + + + + + + + {{ len={len()} }} + + is_inline() ? $T2 : capacity + len() + + + len() + data_ptr() + + + + + + + + + + {{ len={len()} }} + + is_inline() ? $T2 : capacity + len() + + + len() + data_ptr() + + + + \ No newline at end of file diff --git a/vendor/smallvec/scripts/run_miri.sh b/vendor/smallvec/scripts/run_miri.sh index 817928a09..010ceb06e 100644 --- a/vendor/smallvec/scripts/run_miri.sh +++ b/vendor/smallvec/scripts/run_miri.sh @@ -11,6 +11,7 @@ cargo clean MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri) echo "Installing latest nightly with Miri: $MIRI_NIGHTLY" +rustup override unset rustup default "$MIRI_NIGHTLY" rustup component add miri @@ -19,3 +20,5 @@ cargo miri setup cargo miri test --verbose cargo miri test --verbose --features union cargo miri test --verbose --all-features + +rustup override set nightly diff --git a/vendor/smallvec/src/lib.rs b/vendor/smallvec/src/lib.rs index 921347af8..a335ca46c 100644 --- a/vendor/smallvec/src/lib.rs +++ b/vendor/smallvec/src/lib.rs @@ -81,6 +81,11 @@ #![cfg_attr(feature = "specialization", allow(incomplete_features))] #![cfg_attr(feature = "specialization", feature(specialization))] #![cfg_attr(feature = "may_dangle", feature(dropck_eyepatch))] +#![cfg_attr( + feature = "debugger_visualizer", + feature(debugger_visualizer), + debugger_visualizer(natvis_file = "../debug_metadata/smallvec.natvis") +)] #![deny(missing_docs)] #[doc(hidden)] @@ -2084,6 +2089,7 @@ impl SmallVec<[T; N]> { #[cfg_attr(docsrs, doc(cfg(feature = "const_generics")))] unsafe impl Array for [T; N] { type Item = T; + #[inline] fn size() -> usize { N } @@ -2095,6 +2101,7 @@ macro_rules! impl_array( $( unsafe impl Array for [T; $size] { type Item = T; + #[inline] fn size() -> usize { $size } } )+ diff --git a/vendor/smallvec/tests/debugger_visualizer.rs b/vendor/smallvec/tests/debugger_visualizer.rs new file mode 100644 index 000000000..210f539b6 --- /dev/null +++ b/vendor/smallvec/tests/debugger_visualizer.rs @@ -0,0 +1,68 @@ +use debugger_test::debugger_test; +use smallvec::{smallvec, SmallVec}; + +#[inline(never)] +fn __break() {} + +#[debugger_test( + debugger = "cdb", + commands = r#" +.nvlist +dx sv + +g + +dx sv + +g + +dx sv +"#, + expected_statements = r#" +sv : { len=0x2 } [Type: smallvec::SmallVec >] + [] [Type: smallvec::SmallVec >] + [capacity] : 4 + [len] : 0x2 [Type: unsigned __int64] + [0] : 1 [Type: int] + [1] : 2 [Type: int] + +sv : { len=0x5 } [Type: smallvec::SmallVec >] + [] [Type: smallvec::SmallVec >] + [capacity] : 0x8 [Type: unsigned __int64] + [len] : 0x5 [Type: unsigned __int64] + [0] : 5 [Type: int] + [1] : 2 [Type: int] + [2] : 3 [Type: int] + [3] : 4 [Type: int] + [4] : 5 [Type: int] + +sv : { len=0x5 } [Type: smallvec::SmallVec >] + [] [Type: smallvec::SmallVec >] + [capacity] : 0x8 [Type: unsigned __int64] + [len] : 0x5 [Type: unsigned __int64] + [0] : 2 [Type: int] + [1] : 3 [Type: int] + [2] : 4 [Type: int] + [3] : 5 [Type: int] + [4] : 5 [Type: int] +"# +)] +#[inline(never)] +fn test_debugger_visualizer() { + // This SmallVec can hold up to 4 items on the stack: + let mut sv: SmallVec<[i32; 4]> = smallvec![1, 2]; + __break(); + + // Overfill the SmallVec to move its contents to the heap + for i in 3..6 { + sv.push(i); + } + + // Update the contents of the first value of the SmallVec. + sv[0] = sv[1] + sv[2]; + __break(); + + // Sort the SmallVec in place. + sv.sort(); + __break(); +} diff --git a/vendor/syn/.cargo-checksum.json b/vendor/syn/.cargo-checksum.json index 691cc4e06..8b90dae0f 100644 --- a/vendor/syn/.cargo-checksum.json +++ b/vendor/syn/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"598185e9190166e7f3217ced440d8b3e555ae2a6a84b51ee5ea0a5c7f55bdd0b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"b1546652aefba564455c1ebbf0f276450d4fdb19755e08bfa03c13c8bab241fc","benches/file.rs":"39e124e8ebb7f7171af29e87debbcaeb87c1eb465ef1436cfd8f218b340ef580","benches/rust.rs":"22dfbffc39f8d091ef74cca849e7e7c69e9a47f2a06f7dec91c0382401055c14","build.rs":"b815649fd2929d3debd93a58f5da2fb8eba506047a6a5ba538347305828a87b0","src/attr.rs":"234d9cebe2c5e92cd0f5e1117bf5755037e2e905788a337000a65d4bd82b63aa","src/await.rs":"8aa22e3c201cb2bdb6b4817fa00901f308ab06817607aa7b884c58c957705969","src/bigint.rs":"efc7f64959980653d73fe4f8bc2a3a2904dc05f45b02c6dc15cd316fa3d7c338","src/buffer.rs":"bd5762429e5eb3c899167e820620e7e2a66b4573c48e17326ed12d7461962536","src/custom_keyword.rs":"5c706fc3611e73d16b8c019d7ecb848a86b1ccfcd9e556f80bb6e6a4abe058a8","src/custom_punctuation.rs":"8a666298e774b0d326642f0f73284f6677d0d0a7c9e4a712c9c98d010b4d8a2c","src/data.rs":"75d2c2b5d6a01bf8a6fa2845e41663d8045a78b4b191f1a1bd7c93619d20017a","src/derive.rs":"ee24a202be2d36ccdff576dd9cd765e94b33ef2286946e6725d75b08e777d462","src/discouraged.rs":"6c6a9298f8d24f578da119557bc588f3bd928f7b79fca27d6bdfe3e786dd005f","src/error.rs":"e548cc5b7c6f742ab6c19788755980594c4cb8086f99e6709f1cbc982961102d","src/export.rs":"0cf50d70c32d5fddba8b1193032df62e560237c113df3e86ba26b565cc82838e","src/expr.rs":"0d441100457567b7b18372fdcbbe833d7516b5a43f17f1cfc4d7f354141b8206","src/ext.rs":"1f648cff1d705a1cea64b32b77482b97a82d2fe0aaf63b40cade91e5c02dc969","src/file.rs":"f86697655222ae294215114f4eae8e6b0b5e2a935d6c479ff8f8f889c4efd2e2","src/gen/clone.rs":"c43199af10b9963476a1ef6b9e0540363a8383c611f8999463235a0939817da8","src/gen/debug.rs":"12e07500a09d1d15b7a148d9155af357c7ac9b65ac100906cf0fac604403274e","src/gen/eq.rs":"e0928a9f4e81a7ede04853d1837abccaf29dd4ffb56d864fad2f4c3a4c76f1b4","src/gen/fold.rs":"43b34e7a951c180b65c6dd97c380f067ea91776f52e70f61555bd8a4120170b1","src/gen/hash.rs":"b66425846386e2168990b3bee2461f5c01695acd8c4b6360619a07108b260f3d","src/gen/visit.rs":"d559f661ab4a4c5b058af91ef244f30f906b6be82d1dd61bf0d058236f8c6a35","src/gen/visit_mut.rs":"fe384074919cdb1a6f54b93f8a9c768da7d3751e5bbfaf8c6c7133a7ebd390ae","src/gen_helper.rs":"ea6c66388365971db6a2fc86cbb208f7eacde77e245bc8623f27a3642a3d7741","src/generics.rs":"46ed41bf116448822ddfefcb62e803fd33264ca8ba672efc0612674d85b6dd11","src/group.rs":"166f0fbb365471ffa3e4f554b72c2b460cbf7e3a1f9bec6c01ef6bbbcd751041","src/ident.rs":"2443e43561abea7eea577b141422258237a663499c839923d8a5ca6fea2470db","src/item.rs":"2745d8bc068f821fc7dc8f480aceac1d10adc578a0b8b7317eb78f5c9048c68c","src/lib.rs":"143cbfa606d88ed75d3f80a27ca582c4b5285e2e60b78991bec02393ffebf334","src/lifetime.rs":"b18862ef1e690037a4f308ea897debad7bc5038584e3b26c6d8809752ea0e3c2","src/lit.rs":"9134ff103d943cfabdbfae56e78881680f91f9902172b890884a05c58131602a","src/lookahead.rs":"e2c2b6d55906421e83dab51463b58bc6dcb582f1bff9303c8b62afefb8d71e5f","src/mac.rs":"004cb89f9697564f6c9ee837e08ead68463ef946fb4c13c6c105adf2ba364b2b","src/macros.rs":"936f503c2fcde602f05220954ecaf87625c6138d0af13d33d56c7b6530110084","src/op.rs":"9d499022902743a6a0a19223b356449a979b90e60552d0446497d72750e646a4","src/parse.rs":"7b2f8caddf25a5734cbcdf7cbf043cbf9afbc07b484966cd59ddfcec9f970fb3","src/parse_macro_input.rs":"88929a1a7e5e72aa2d0b3459e52d8975afea856d159047ba4ab02ecbc5878a9c","src/parse_quote.rs":"d7d996f1382c68b5fbfd4b7327ce1d389cd43c3bb3c4f382a35994d0bb79d8ab","src/pat.rs":"1e0223ca92c160e07b17a593bb93dd5d451fc9b7014012b403377a4f0f21bfce","src/path.rs":"1ad8b8335628f67a013b7ce2f662aa2feab4583ff67bc959a9dea1dcb51be8a3","src/print.rs":"da6529c1d9d21aaf6c835f66b4e67eacb7cf91a10eb5e9a2143b49bf99b3b5e1","src/punctuated.rs":"f687c23bd3ae512e7412c28ac68030d3bc7a384d1ca8b3da6620e364b0cbbb78","src/reserved.rs":"e70e028bd55cfa43e23cab4ba29e4dc53a3d91eff685ef2b6e57efc2b87a3428","src/sealed.rs":"896a495a5340eec898527f18bd4ddca408ea03ea0ee3af30074ff48deace778d","src/span.rs":"748c51c6feb223c26d3b1701f5bb98aee823666c775c98106cfa24fe29d8cec1","src/spanned.rs":"3ca016a943637653ab98e373dfb826a120f3c159867346fa38a844439944eb39","src/stmt.rs":"8115bc96090022baad91660d7e5e986664c3f1fbd2f112d1c5d1d77e5c3f227e","src/thread.rs":"815eca6bd64f4eef7c447f0809e84108f5428ff50225224b373efd8fbb696874","src/token.rs":"5e423a696f80e281c322f37c87577f9fdc28607e9c007e24896a2b12da62d5ad","src/tt.rs":"32402645b6e82ef1e882945721b59b5fb7b0ee337d1972876362ecacef643d0f","src/ty.rs":"5c05b000d4884334bed729c3345732fbbb4136a75df9dd5002c493ebb6cd091b","src/verbatim.rs":"802a97df997432f18cac6e6200ff6ea29fb2474986005e0fcdbc2b65197f87f7","src/whitespace.rs":"e63dd0aa3d34029f17766a8b09c1a6e4479e36c552c8b7023d710a399333aace","tests/.gitignore":"22e782449a3c216db3f7215d5fb8882e316768e40beeec3833aae419ad8941db","tests/common/eq.rs":"529ae94214c0666045a4c16d9beab6c71eedb40e100be8f990674d44480b5ba6","tests/common/mod.rs":"432ad35577f836a20b517d8c26ed994ac25fe73ef2f461c67688b61b99762015","tests/common/parse.rs":"81580f23583723f7a2a337c4d13ebc021057cd825562fb4e474caa7cc641fed9","tests/debug/gen.rs":"4937074a11fe8266431d05177435bad28340763d408d0a4c45bd0c0acc90a86a","tests/debug/mod.rs":"3a6bb799f478101f71c84c6f1a854a58afe2f9db43c39017909346ca20262d94","tests/macros/mod.rs":"aff805b35cfd55aef6a1359ff747e4023afcb08d69d86aff4c19465d29dda088","tests/regression.rs":"f962ebf24007f631f7e702e34e142d07581da7c9a36321ac142cafed1a0afc69","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/repo/mod.rs":"947b678f50df8716ef5c946885a3096e91ab2ec4ce2251cea83d6e6d2ab82eb5","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"cff01db49d28ab23b0b258bc6c0a5cc4071be4fe7248eef344a5d79d2fb649b7","tests/test_attribute.rs":"0ffd99384e1a52ae17d9fed5c4053e411e8f9018decef07ffa621d1faa7329d8","tests/test_derive_input.rs":"62bb86aaaaf730187a46ff700a8e3b2d1a163039b109b6a483aa44ed2b6806fe","tests/test_expr.rs":"a639728866a063b590430965a4840c01755e398b89be12d8d09b0aa97837ecac","tests/test_generics.rs":"54b7d2afc19aa6e9049585f4c8f7d3f0c29ac3bd11a2c769e9df76f18a4f5ecb","tests/test_grouping.rs":"6276c3c73bba649dec5c97904ad2492879f918bc887a2c425d095c654ca0d925","tests/test_ident.rs":"9eb53d1e21edf23e7c9e14dc74dcc2b2538e9221e19dbcc0a44e3acc2e90f3f6","tests/test_item.rs":"a3642c80066f1e7787becfd0278af90a6b7968d6c1249e25e81663aa454cfb2a","tests/test_iterators.rs":"53ed6078d37550bd6765d2411e3660be401aef8a31a407350cc064a7d08c7c33","tests/test_lit.rs":"19740ea9cd4a980bcab9b0dcaa4b032bb6ebb137fa5e4237140b97da1d9679fa","tests/test_meta.rs":"65d4586d131f6cac66694ca5e936748ec4e7f7423af6d8da509240e6be14800b","tests/test_parse_buffer.rs":"68d857f776396d064fcc0023c37093c2fbf75ee68e8241d4014d00d1423c18e9","tests/test_parse_stream.rs":"2f449a2c41a3dee6fd14bee24e1666a453cb808eda17332fd91afd127fcdd2a6","tests/test_pat.rs":"d4465f4fc3fd5d6e534ba8efabe1e0ed6da89de4ac7c96effa6bfb880c4287cf","tests/test_path.rs":"71092a5ae2c9143b92a8fe15a92d39958b3c28bd4d4275cfb2d22cbdd53ada07","tests/test_precedence.rs":"1069d979cec0e6c650bebb58be272d23080ce89e83d194dfa2718d22912e481d","tests/test_receiver.rs":"084eca59984b9a18651da52f2c4407355da3de1335916a12477652999e2d01cc","tests/test_round_trip.rs":"b47662e35be2729f28bacdbbea20f1879c111889430e735a7bcb5f2a5c0b9e5c","tests/test_shebang.rs":"f5772cadad5b56e3112cb16308b779f92bce1c3a48091fc9933deb2276a69331","tests/test_should_parse.rs":"1d3535698a446e2755bfc360676bdb161841a1f454cdef6e7556c6d06a95c89d","tests/test_size.rs":"1aa0dd489bd844a4a9cf32a5310abd66dad1dae3ffb24fe1288b62a26bfdd8dc","tests/test_stmt.rs":"0601fc32131b5501dfcdc4b4248d46bf21e0a98a49eb19439e1a46869dfb30b7","tests/test_token_trees.rs":"43e56a701817e3c3bfd0cae54a457dd7a38ccb3ca19da41e2b995fdf20e6ed18","tests/test_ty.rs":"f71d7f7f1c038aaabea8dd4c03c0d5752c76d570f8b4885a81659825bbb4d576","tests/test_visibility.rs":"7456fcb3a6634db509748aededff9c2d8b242d511a3e5ee3022e40b232892704","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"} \ No newline at end of file +{"files":{"Cargo.toml":"8366f3b0e0c3a589f43424b1837bb43aa8b4dd224184d355ad38a63bac915210","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"b1546652aefba564455c1ebbf0f276450d4fdb19755e08bfa03c13c8bab241fc","benches/file.rs":"3d737ef3878f6e242b003af9bd539e565f98439a12ee44d9548d84e3fdd7af0c","benches/rust.rs":"11ac9fe898a7bf1bd63e8a8cc9c08bd795b01f0248215cff99afaaf28ce87fab","build.rs":"b815649fd2929d3debd93a58f5da2fb8eba506047a6a5ba538347305828a87b0","src/attr.rs":"234d9cebe2c5e92cd0f5e1117bf5755037e2e905788a337000a65d4bd82b63aa","src/await.rs":"8aa22e3c201cb2bdb6b4817fa00901f308ab06817607aa7b884c58c957705969","src/bigint.rs":"efc7f64959980653d73fe4f8bc2a3a2904dc05f45b02c6dc15cd316fa3d7c338","src/buffer.rs":"2b48296087f096c9630e1e4b03a00ae703407d1b352902b3197370b2f56c62ff","src/custom_keyword.rs":"5c706fc3611e73d16b8c019d7ecb848a86b1ccfcd9e556f80bb6e6a4abe058a8","src/custom_punctuation.rs":"8a666298e774b0d326642f0f73284f6677d0d0a7c9e4a712c9c98d010b4d8a2c","src/data.rs":"75d2c2b5d6a01bf8a6fa2845e41663d8045a78b4b191f1a1bd7c93619d20017a","src/derive.rs":"ee24a202be2d36ccdff576dd9cd765e94b33ef2286946e6725d75b08e777d462","src/discouraged.rs":"6c6a9298f8d24f578da119557bc588f3bd928f7b79fca27d6bdfe3e786dd005f","src/error.rs":"e548cc5b7c6f742ab6c19788755980594c4cb8086f99e6709f1cbc982961102d","src/export.rs":"0cf50d70c32d5fddba8b1193032df62e560237c113df3e86ba26b565cc82838e","src/expr.rs":"5eea3828f3291b0ce5463ed5f0c23fc8a39aeceae68a3247ae02ae467dd35a98","src/ext.rs":"1f648cff1d705a1cea64b32b77482b97a82d2fe0aaf63b40cade91e5c02dc969","src/file.rs":"f86697655222ae294215114f4eae8e6b0b5e2a935d6c479ff8f8f889c4efd2e2","src/gen/clone.rs":"76e89fe155fedf43bc4a252af7e35319b82ce455f584bad8698fdc3f9b7f5d4e","src/gen/debug.rs":"4b05e474e864ce6bf1a5a6ab48ee6c0ecdf41a0d750237990cf2e31963bc1208","src/gen/eq.rs":"79f84836fdcd5cfa352f38055dab7c3246c7757650946c1c701234b11021652a","src/gen/fold.rs":"fcd6a05c8c8e0c36e7ede8593002528b553c8b648fbed452106fd6a8a8c9212a","src/gen/hash.rs":"575e8beae303c1eabda12bf76cbd82672268c502a8ebb8517aab18b40fdbc44e","src/gen/visit.rs":"ced9f6c17d2b3eb3553faab710cb2b3d44d6bca7d1862c8c5da09c3d45debecb","src/gen/visit_mut.rs":"966ea340c53461bf8a1c6bed3c882e4ab8b8907fd18ac35531266f7891ae5f46","src/gen_helper.rs":"ea6c66388365971db6a2fc86cbb208f7eacde77e245bc8623f27a3642a3d7741","src/generics.rs":"46ed41bf116448822ddfefcb62e803fd33264ca8ba672efc0612674d85b6dd11","src/group.rs":"166f0fbb365471ffa3e4f554b72c2b460cbf7e3a1f9bec6c01ef6bbbcd751041","src/ident.rs":"2443e43561abea7eea577b141422258237a663499c839923d8a5ca6fea2470db","src/item.rs":"419c4d6135a7ca7b8f94b5ba038b6af8fcb3939ae807153a19e3c82e9b01e0b7","src/lib.rs":"7875551b227d19f083115d48a83e8c35e3e6d31dbd749bdd03556e2762f7d4fd","src/lifetime.rs":"b18862ef1e690037a4f308ea897debad7bc5038584e3b26c6d8809752ea0e3c2","src/lit.rs":"fc06ddd523f7f9971d8abdb4c8d5d51030ffb3d6810615d5575ae210a7800695","src/lookahead.rs":"e2c2b6d55906421e83dab51463b58bc6dcb582f1bff9303c8b62afefb8d71e5f","src/mac.rs":"004cb89f9697564f6c9ee837e08ead68463ef946fb4c13c6c105adf2ba364b2b","src/macros.rs":"936f503c2fcde602f05220954ecaf87625c6138d0af13d33d56c7b6530110084","src/op.rs":"9d499022902743a6a0a19223b356449a979b90e60552d0446497d72750e646a4","src/parse.rs":"7b2f8caddf25a5734cbcdf7cbf043cbf9afbc07b484966cd59ddfcec9f970fb3","src/parse_macro_input.rs":"a5d16859b782bb6a2754c1066468a2f1ea05b57390caa32175bb84064973be7b","src/parse_quote.rs":"d7d996f1382c68b5fbfd4b7327ce1d389cd43c3bb3c4f382a35994d0bb79d8ab","src/pat.rs":"b2de04ae6c01df50eab9d1c3908287aca8424adc2007b926c7bcf74d1f64d40a","src/path.rs":"269d5d8b0c21eaf96e1c49bcb1ec2a03175a8adcc103c142e550b3f5e79825d8","src/print.rs":"da6529c1d9d21aaf6c835f66b4e67eacb7cf91a10eb5e9a2143b49bf99b3b5e1","src/punctuated.rs":"f687c23bd3ae512e7412c28ac68030d3bc7a384d1ca8b3da6620e364b0cbbb78","src/reserved.rs":"e70e028bd55cfa43e23cab4ba29e4dc53a3d91eff685ef2b6e57efc2b87a3428","src/sealed.rs":"896a495a5340eec898527f18bd4ddca408ea03ea0ee3af30074ff48deace778d","src/span.rs":"748c51c6feb223c26d3b1701f5bb98aee823666c775c98106cfa24fe29d8cec1","src/spanned.rs":"3ca016a943637653ab98e373dfb826a120f3c159867346fa38a844439944eb39","src/stmt.rs":"601a6914f1e0bf97ae0d31d474a531d195b8c251a4ded11aa8746ac0018d367b","src/thread.rs":"815eca6bd64f4eef7c447f0809e84108f5428ff50225224b373efd8fbb696874","src/token.rs":"5e423a696f80e281c322f37c87577f9fdc28607e9c007e24896a2b12da62d5ad","src/tt.rs":"32402645b6e82ef1e882945721b59b5fb7b0ee337d1972876362ecacef643d0f","src/ty.rs":"7e678749af18fc84ae9220435e467e520de05eea66adeeed3b5d634cd744561c","src/verbatim.rs":"802a97df997432f18cac6e6200ff6ea29fb2474986005e0fcdbc2b65197f87f7","src/whitespace.rs":"e63dd0aa3d34029f17766a8b09c1a6e4479e36c552c8b7023d710a399333aace","tests/common/eq.rs":"953f5db261a3334eba1d37df4247463e9234c7988da04f43028b5273d24bf2da","tests/common/mod.rs":"432ad35577f836a20b517d8c26ed994ac25fe73ef2f461c67688b61b99762015","tests/common/parse.rs":"81580f23583723f7a2a337c4d13ebc021057cd825562fb4e474caa7cc641fed9","tests/debug/gen.rs":"1b7f875344cb04a7dd3df62deac2f410a9d107c097986e68006d87465f5f5306","tests/debug/mod.rs":"3a6bb799f478101f71c84c6f1a854a58afe2f9db43c39017909346ca20262d94","tests/macros/mod.rs":"aff805b35cfd55aef6a1359ff747e4023afcb08d69d86aff4c19465d29dda088","tests/regression.rs":"f962ebf24007f631f7e702e34e142d07581da7c9a36321ac142cafed1a0afc69","tests/regression/issue1108.rs":"adcc55a42239d344da74216ed85fc14153ddd6ca4dec4872d8339604ba78c185","tests/repo/mod.rs":"1ea18f9430e75cabc4b23b826544c2bf2f950b679a04b237a11e17aabc16e2e9","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"cff01db49d28ab23b0b258bc6c0a5cc4071be4fe7248eef344a5d79d2fb649b7","tests/test_attribute.rs":"0ffd99384e1a52ae17d9fed5c4053e411e8f9018decef07ffa621d1faa7329d8","tests/test_derive_input.rs":"62bb86aaaaf730187a46ff700a8e3b2d1a163039b109b6a483aa44ed2b6806fe","tests/test_expr.rs":"a639728866a063b590430965a4840c01755e398b89be12d8d09b0aa97837ecac","tests/test_generics.rs":"54b7d2afc19aa6e9049585f4c8f7d3f0c29ac3bd11a2c769e9df76f18a4f5ecb","tests/test_grouping.rs":"6276c3c73bba649dec5c97904ad2492879f918bc887a2c425d095c654ca0d925","tests/test_ident.rs":"9eb53d1e21edf23e7c9e14dc74dcc2b2538e9221e19dbcc0a44e3acc2e90f3f6","tests/test_item.rs":"a3642c80066f1e7787becfd0278af90a6b7968d6c1249e25e81663aa454cfb2a","tests/test_iterators.rs":"53ed6078d37550bd6765d2411e3660be401aef8a31a407350cc064a7d08c7c33","tests/test_lit.rs":"19740ea9cd4a980bcab9b0dcaa4b032bb6ebb137fa5e4237140b97da1d9679fa","tests/test_meta.rs":"65d4586d131f6cac66694ca5e936748ec4e7f7423af6d8da509240e6be14800b","tests/test_parse_buffer.rs":"68d857f776396d064fcc0023c37093c2fbf75ee68e8241d4014d00d1423c18e9","tests/test_parse_stream.rs":"bf1db6fab7ac396fa61012faccbe6ffbc9c3d795ed2900be75e91c5b09b0c62f","tests/test_pat.rs":"d4465f4fc3fd5d6e534ba8efabe1e0ed6da89de4ac7c96effa6bfb880c4287cf","tests/test_path.rs":"71092a5ae2c9143b92a8fe15a92d39958b3c28bd4d4275cfb2d22cbdd53ada07","tests/test_precedence.rs":"736eee861c4c7a3d7d4387d2fb1b5eced1541790d34974f72b0a5532797e73c3","tests/test_receiver.rs":"084eca59984b9a18651da52f2c4407355da3de1335916a12477652999e2d01cc","tests/test_round_trip.rs":"b47662e35be2729f28bacdbbea20f1879c111889430e735a7bcb5f2a5c0b9e5c","tests/test_shebang.rs":"f5772cadad5b56e3112cb16308b779f92bce1c3a48091fc9933deb2276a69331","tests/test_should_parse.rs":"1d3535698a446e2755bfc360676bdb161841a1f454cdef6e7556c6d06a95c89d","tests/test_size.rs":"697906d892ab8186eebdf6bc7696fde7a42376d50bee846ba69f031bdb847e01","tests/test_stmt.rs":"0601fc32131b5501dfcdc4b4248d46bf21e0a98a49eb19439e1a46869dfb30b7","tests/test_token_trees.rs":"43e56a701817e3c3bfd0cae54a457dd7a38ccb3ca19da41e2b995fdf20e6ed18","tests/test_ty.rs":"f71d7f7f1c038aaabea8dd4c03c0d5752c76d570f8b4885a81659825bbb4d576","tests/test_visibility.rs":"7456fcb3a6634db509748aededff9c2d8b242d511a3e5ee3022e40b232892704","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"} \ No newline at end of file diff --git a/vendor/syn/Cargo.toml b/vendor/syn/Cargo.toml index d03ee2e31..7b1412593 100644 --- a/vendor/syn/Cargo.toml +++ b/vendor/syn/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "syn" -version = "1.0.99" +version = "1.0.102" authors = ["David Tolnay "] include = [ "/benches/**", @@ -72,7 +72,7 @@ required-features = [ ] [dependencies.proc-macro2] -version = "1.0.39" +version = "1.0.46" default-features = false [dependencies.quote] diff --git a/vendor/syn/benches/file.rs b/vendor/syn/benches/file.rs index c500dc24a..bd4a247df 100644 --- a/vendor/syn/benches/file.rs +++ b/vendor/syn/benches/file.rs @@ -1,4 +1,4 @@ -// $ cargo bench --features full --bench file +// $ cargo bench --features full,test --bench file #![feature(rustc_private, test)] #![recursion_limit = "1024"] diff --git a/vendor/syn/benches/rust.rs b/vendor/syn/benches/rust.rs index 5e4fba182..e3f8f550a 100644 --- a/vendor/syn/benches/rust.rs +++ b/vendor/syn/benches/rust.rs @@ -1,7 +1,7 @@ -// $ cargo bench --features full --bench rust +// $ cargo bench --features full,test --bench rust // // Syn only, useful for profiling: -// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full --bench rust +// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full,test --bench rust #![cfg_attr(not(syn_only), feature(rustc_private))] #![recursion_limit = "1024"] @@ -46,7 +46,7 @@ mod librustc_parse { use rustc_data_structures::sync::Lrc; use rustc_error_messages::FluentBundle; - use rustc_errors::{emitter::Emitter, Diagnostic, Handler}; + use rustc_errors::{emitter::Emitter, translation::Translate, Diagnostic, Handler}; use rustc_session::parse::ParseSess; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{edition::Edition, FileName}; @@ -59,6 +59,9 @@ mod librustc_parse { fn source_map(&self) -> Option<&Lrc> { None } + } + + impl Translate for SilentEmitter { fn fluent_bundle(&self) -> Option<&Lrc> { None } @@ -88,7 +91,7 @@ mod librustc_parse { #[cfg(not(syn_only))] mod read_from_disk { pub fn bench(content: &str) -> Result<(), ()> { - let _ = content; + _ = content; Ok(()) } } diff --git a/vendor/syn/src/buffer.rs b/vendor/syn/src/buffer.rs index 2c8e21bdb..161b614c8 100644 --- a/vendor/syn/src/buffer.rs +++ b/vendor/syn/src/buffer.rs @@ -14,23 +14,18 @@ use crate::proc_macro as pm; use crate::Lifetime; use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; -use std::hint; use std::marker::PhantomData; -use std::mem; -use std::ptr; -use std::slice; /// Internal type which is used instead of `TokenTree` to represent a token tree /// within a `TokenBuffer`. enum Entry { // Mimicking types from proc-macro. - Group(Group, TokenBuffer), + // Group entries contain the offset to the matching End entry. + Group(Group, usize), Ident(Ident), Punct(Punct), Literal(Literal), - // End entries contain a raw pointer to the entry from the containing - // token tree, or null if this is the outermost level. - End(*const Entry), + End, } /// A buffer that can be efficiently traversed multiple times, unlike @@ -39,102 +34,29 @@ enum Entry { /// /// *This type is available only if Syn is built with the `"parsing"` feature.* pub struct TokenBuffer { - // NOTE: Do not implement clone on this - there are raw pointers inside - // these entries which will be messed up. Moving the `TokenBuffer` itself is - // safe as the data pointed to won't be moved. - ptr: *const Entry, - len: usize, -} - -impl Drop for TokenBuffer { - fn drop(&mut self) { - unsafe { - let slice = slice::from_raw_parts_mut(self.ptr as *mut Entry, self.len); - let _ = Box::from_raw(slice); - } - } + // NOTE: Do not implement clone on this - while the current design could be + // cloned, other designs which could be desirable may not be cloneable. + entries: Box<[Entry]>, } impl TokenBuffer { - // NOTE: Do not mutate the Vec returned from this function once it returns; - // the address of its backing memory must remain stable. - fn inner_new(stream: TokenStream, up: *const Entry) -> TokenBuffer { - let iterator = stream.into_iter(); - let mut entries = Vec::with_capacity(iterator.size_hint().0 + 1); - let mut next_index_after_last_group = 0; - for tt in iterator { + fn recursive_new(entries: &mut Vec, stream: TokenStream) { + for tt in stream { match tt { - TokenTree::Ident(ident) => { - entries.push(Entry::Ident(ident)); - } - TokenTree::Punct(punct) => { - entries.push(Entry::Punct(punct)); - } - TokenTree::Literal(literal) => { - entries.push(Entry::Literal(literal)); - } + TokenTree::Ident(ident) => entries.push(Entry::Ident(ident)), + TokenTree::Punct(punct) => entries.push(Entry::Punct(punct)), + TokenTree::Literal(literal) => entries.push(Entry::Literal(literal)), TokenTree::Group(group) => { - // We cannot fill in a real `End` pointer until `entries` is - // finished growing and getting potentially reallocated. - // Instead, we temporarily coopt the spot where the end - // pointer would go, and use it to string together an - // intrusive linked list of all the Entry::Group entries in - // the vector. Later after `entries` is done growing, we'll - // traverse the linked list and fill in all the end - // pointers with a correct value. - let group_up = - ptr::null::().wrapping_add(next_index_after_last_group) as *const Entry; - - let inner = Self::inner_new(group.stream(), group_up); - entries.push(Entry::Group(group, inner)); - next_index_after_last_group = entries.len(); + let group_start_index = entries.len(); + entries.push(Entry::End); // we replace this below + Self::recursive_new(entries, group.stream()); + let group_end_index = entries.len(); + entries.push(Entry::End); + let group_end_offset = group_end_index - group_start_index; + entries[group_start_index] = Entry::Group(group, group_end_offset); } } } - - // Add an `End` entry to the end with a reference to the enclosing token - // stream which was passed in. - entries.push(Entry::End(up)); - - // NOTE: This is done to ensure that we don't accidentally modify the - // length of the backing buffer. The backing buffer must remain at a - // constant address after this point, as we are going to store a raw - // pointer into it. - let entries = entries.into_boxed_slice(); - let len = entries.len(); - - // Convert boxed slice into a pointer to the first element early, to - // avoid invalidating pointers into this slice when we move the Box. - // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326 - let entries = Box::into_raw(entries) as *mut Entry; - - // Traverse intrusive linked list of Entry::Group entries and fill in - // correct End pointers. - while let Some(idx) = next_index_after_last_group.checked_sub(1) { - // We know that idx refers to one of the Entry::Group entries, and - // that the very last entry is an Entry::End, so the next index - // after any group entry is a valid index. - let group_up = unsafe { entries.add(next_index_after_last_group) }; - - // Linked list only takes us to entries which are of type Group. - let token_buffer = match unsafe { &*entries.add(idx) } { - Entry::Group(_group, token_buffer) => token_buffer, - _ => unsafe { hint::unreachable_unchecked() }, - }; - - // Last entry in any TokenBuffer is of type End. - let buffer_ptr = token_buffer.ptr as *mut Entry; - let last_entry = unsafe { &mut *buffer_ptr.add(token_buffer.len - 1) }; - let end_ptr_slot = match last_entry { - Entry::End(end_ptr_slot) => end_ptr_slot, - _ => unsafe { hint::unreachable_unchecked() }, - }; - - // Step to next element in linked list. - next_index_after_last_group = mem::replace(end_ptr_slot, group_up) as usize; - } - - TokenBuffer { ptr: entries, len } } /// Creates a `TokenBuffer` containing all the tokens from the input @@ -153,13 +75,19 @@ impl TokenBuffer { /// Creates a `TokenBuffer` containing all the tokens from the input /// `proc_macro2::TokenStream`. pub fn new2(stream: TokenStream) -> Self { - Self::inner_new(stream, ptr::null()) + let mut entries = Vec::new(); + Self::recursive_new(&mut entries, stream); + entries.push(Entry::End); + Self { + entries: entries.into_boxed_slice(), + } } /// Creates a cursor referencing the first token in the buffer and able to /// traverse until the end of the buffer. pub fn begin(&self) -> Cursor { - unsafe { Cursor::create(self.ptr, self.ptr.add(self.len - 1)) } + let ptr = self.entries.as_ptr(); + unsafe { Cursor::create(ptr, ptr.add(self.entries.len() - 1)) } } } @@ -179,7 +107,7 @@ impl TokenBuffer { pub struct Cursor<'a> { // The current entry which the `Cursor` is pointing at. ptr: *const Entry, - // This is the only `Entry::End(..)` object which this cursor is allowed to + // This is the only `Entry::End` object which this cursor is allowed to // point at. All other `End` objects are skipped over in `Cursor::create`. scope: *const Entry, // Cursor is covariant in 'a. This field ensures that our pointers are still @@ -199,7 +127,7 @@ impl<'a> Cursor<'a> { // object in global storage. struct UnsafeSyncEntry(Entry); unsafe impl Sync for UnsafeSyncEntry {} - static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End(0 as *const Entry)); + static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End); Cursor { ptr: &EMPTY_ENTRY.0, @@ -212,15 +140,15 @@ impl<'a> Cursor<'a> { /// `None`-delimited scopes when the cursor reaches the end of them, /// allowing for them to be treated transparently. unsafe fn create(mut ptr: *const Entry, scope: *const Entry) -> Self { - // NOTE: If we're looking at a `End(..)`, we want to advance the cursor + // NOTE: If we're looking at a `End`, we want to advance the cursor // past it, unless `ptr == scope`, which means that we're at the edge of // our cursor's scope. We should only have `ptr != scope` at the exit // from None-delimited groups entered with `ignore_none`. - while let Entry::End(exit) = *ptr { + while let Entry::End = *ptr { if ptr == scope { break; } - ptr = exit; + ptr = ptr.add(1); } Cursor { @@ -238,7 +166,10 @@ impl<'a> Cursor<'a> { /// Bump the cursor to point at the next token after the current one. This /// is undefined behavior if the cursor is currently looking at an /// `Entry::End`. - unsafe fn bump(self) -> Cursor<'a> { + /// + /// If the cursor is looking at an `Entry::Group`, the bumped cursor will + /// point at the first token in the group (with the same scope end). + unsafe fn bump_ignore_group(self) -> Cursor<'a> { Cursor::create(self.ptr.offset(1), self.scope) } @@ -248,14 +179,9 @@ impl<'a> Cursor<'a> { /// /// WARNING: This mutates its argument. fn ignore_none(&mut self) { - while let Entry::Group(group, buf) = self.entry() { + while let Entry::Group(group, _) = self.entry() { if group.delimiter() == Delimiter::None { - // NOTE: We call `Cursor::create` here to make sure that - // situations where we should immediately exit the span after - // entering it are handled correctly. - unsafe { - *self = Cursor::create(buf.ptr, self.scope); - } + unsafe { *self = self.bump_ignore_group() }; } else { break; } @@ -279,9 +205,12 @@ impl<'a> Cursor<'a> { self.ignore_none(); } - if let Entry::Group(group, buf) = self.entry() { + if let Entry::Group(group, end_offset) = self.entry() { if group.delimiter() == delim { - return Some((buf.begin(), group.span(), unsafe { self.bump() })); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, group.span(), after_group)); } } @@ -293,7 +222,7 @@ impl<'a> Cursor<'a> { pub fn ident(mut self) -> Option<(Ident, Cursor<'a>)> { self.ignore_none(); match self.entry() { - Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump() })), + Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump_ignore_group() })), _ => None, } } @@ -304,7 +233,7 @@ impl<'a> Cursor<'a> { self.ignore_none(); match self.entry() { Entry::Punct(punct) if punct.as_char() != '\'' => { - Some((punct.clone(), unsafe { self.bump() })) + Some((punct.clone(), unsafe { self.bump_ignore_group() })) } _ => None, } @@ -315,7 +244,7 @@ impl<'a> Cursor<'a> { pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> { self.ignore_none(); match self.entry() { - Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump() })), + Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump_ignore_group() })), _ => None, } } @@ -326,17 +255,13 @@ impl<'a> Cursor<'a> { self.ignore_none(); match self.entry() { Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { - let next = unsafe { self.bump() }; - match next.ident() { - Some((ident, rest)) => { - let lifetime = Lifetime { - apostrophe: punct.span(), - ident, - }; - Some((lifetime, rest)) - } - None => None, - } + let next = unsafe { self.bump_ignore_group() }; + let (ident, rest) = next.ident()?; + let lifetime = Lifetime { + apostrophe: punct.span(), + ident, + }; + Some((lifetime, rest)) } _ => None, } @@ -362,15 +287,16 @@ impl<'a> Cursor<'a> { /// This method does not treat `None`-delimited groups as transparent, and /// will return a `Group(None, ..)` if the cursor is looking at one. pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> { - let tree = match self.entry() { - Entry::Group(group, _) => group.clone().into(), - Entry::Literal(literal) => literal.clone().into(), - Entry::Ident(ident) => ident.clone().into(), - Entry::Punct(punct) => punct.clone().into(), - Entry::End(..) => return None, + let (tree, len) = match self.entry() { + Entry::Group(group, end_offset) => (group.clone().into(), *end_offset), + Entry::Literal(literal) => (literal.clone().into(), 1), + Entry::Ident(ident) => (ident.clone().into(), 1), + Entry::Punct(punct) => (punct.clone().into(), 1), + Entry::End => return None, }; - Some((tree, unsafe { self.bump() })) + let rest = unsafe { Cursor::create(self.ptr.add(len), self.scope) }; + Some((tree, rest)) } /// Returns the `Span` of the current token, or `Span::call_site()` if this @@ -381,7 +307,7 @@ impl<'a> Cursor<'a> { Entry::Literal(literal) => literal.span(), Entry::Ident(ident) => ident.span(), Entry::Punct(punct) => punct.span(), - Entry::End(..) => Span::call_site(), + Entry::End => Span::call_site(), } } @@ -390,19 +316,22 @@ impl<'a> Cursor<'a> { /// /// This method treats `'lifetimes` as a single token. pub(crate) fn skip(self) -> Option> { - match self.entry() { - Entry::End(..) => None, + let len = match self.entry() { + Entry::End => return None, // Treat lifetimes as a single tt for the purposes of 'skip'. Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { - let next = unsafe { self.bump() }; - match next.entry() { - Entry::Ident(_) => Some(unsafe { next.bump() }), - _ => Some(next), + match unsafe { &*self.ptr.add(1) } { + Entry::Ident(_) => 2, + _ => 1, } } - _ => Some(unsafe { self.bump() }), - } + + Entry::Group(_, end_offset) => *end_offset, + _ => 1, + }; + + Some(unsafe { Cursor::create(self.ptr.add(len), self.scope) }) } } diff --git a/vendor/syn/src/expr.rs b/vendor/syn/src/expr.rs index cf0fa0af9..93a59b0e2 100644 --- a/vendor/syn/src/expr.rs +++ b/vendor/syn/src/expr.rs @@ -1371,7 +1371,9 @@ pub(crate) mod parsing { }); } else if Precedence::Cast >= base && input.peek(Token![as]) { let as_token: Token![as] = input.parse()?; - let ty = input.call(Type::without_plus)?; + let allow_plus = false; + let allow_group_generic = false; + let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?; check_cast(input)?; lhs = Expr::Cast(ExprCast { attrs: Vec::new(), @@ -1381,7 +1383,9 @@ pub(crate) mod parsing { }); } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) { let colon_token: Token![:] = input.parse()?; - let ty = input.call(Type::without_plus)?; + let allow_plus = false; + let allow_group_generic = false; + let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?; check_cast(input)?; lhs = Expr::Type(ExprType { attrs: Vec::new(), @@ -1429,7 +1433,9 @@ pub(crate) mod parsing { }); } else if Precedence::Cast >= base && input.peek(Token![as]) { let as_token: Token![as] = input.parse()?; - let ty = input.call(Type::without_plus)?; + let allow_plus = false; + let allow_group_generic = false; + let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?; check_cast(input)?; lhs = Expr::Cast(ExprCast { attrs: Vec::new(), @@ -1727,7 +1733,10 @@ pub(crate) mod parsing { || input.peek(Token![move]) { expr_closure(input, allow_struct).map(Expr::Closure) - } else if input.peek(Token![for]) && input.peek2(Token![<]) && input.peek3(Lifetime) { + } else if input.peek(Token![for]) + && input.peek2(Token![<]) + && (input.peek3(Lifetime) || input.peek3(Token![>])) + { let begin = input.fork(); input.parse::()?; expr_closure(input, allow_struct)?; @@ -2010,7 +2019,9 @@ pub(crate) mod parsing { Expr::If(input.parse()?) } else if input.peek(Token![while]) { Expr::While(input.parse()?) - } else if input.peek(Token![for]) { + } else if input.peek(Token![for]) + && !(input.peek2(Token![<]) && (input.peek3(Lifetime) || input.peek3(Token![>]))) + { Expr::ForLoop(input.parse()?) } else if input.peek(Token![loop]) { Expr::Loop(input.parse()?) diff --git a/vendor/syn/src/gen/clone.rs b/vendor/syn/src/gen/clone.rs index 8de1cd8c9..a413e3ec7 100644 --- a/vendor/syn/src/gen/clone.rs +++ b/vendor/syn/src/gen/clone.rs @@ -910,9 +910,9 @@ impl Clone for GenericArgument { match self { GenericArgument::Lifetime(v0) => GenericArgument::Lifetime(v0.clone()), GenericArgument::Type(v0) => GenericArgument::Type(v0.clone()), + GenericArgument::Const(v0) => GenericArgument::Const(v0.clone()), GenericArgument::Binding(v0) => GenericArgument::Binding(v0.clone()), GenericArgument::Constraint(v0) => GenericArgument::Constraint(v0.clone()), - GenericArgument::Const(v0) => GenericArgument::Const(v0.clone()), } } } diff --git a/vendor/syn/src/gen/debug.rs b/vendor/syn/src/gen/debug.rs index 4adf8c593..a1f0afa79 100644 --- a/vendor/syn/src/gen/debug.rs +++ b/vendor/syn/src/gen/debug.rs @@ -1268,6 +1268,11 @@ impl Debug for GenericArgument { formatter.field(v0); formatter.finish() } + GenericArgument::Const(v0) => { + let mut formatter = formatter.debug_tuple("Const"); + formatter.field(v0); + formatter.finish() + } GenericArgument::Binding(v0) => { let mut formatter = formatter.debug_tuple("Binding"); formatter.field(v0); @@ -1278,11 +1283,6 @@ impl Debug for GenericArgument { formatter.field(v0); formatter.finish() } - GenericArgument::Const(v0) => { - let mut formatter = formatter.debug_tuple("Const"); - formatter.field(v0); - formatter.finish() - } } } } diff --git a/vendor/syn/src/gen/eq.rs b/vendor/syn/src/gen/eq.rs index 40fed0b89..20acb809d 100644 --- a/vendor/syn/src/gen/eq.rs +++ b/vendor/syn/src/gen/eq.rs @@ -878,13 +878,13 @@ impl PartialEq for GenericArgument { (GenericArgument::Type(self0), GenericArgument::Type(other0)) => { self0 == other0 } - (GenericArgument::Binding(self0), GenericArgument::Binding(other0)) => { + (GenericArgument::Const(self0), GenericArgument::Const(other0)) => { self0 == other0 } - (GenericArgument::Constraint(self0), GenericArgument::Constraint(other0)) => { + (GenericArgument::Binding(self0), GenericArgument::Binding(other0)) => { self0 == other0 } - (GenericArgument::Const(self0), GenericArgument::Const(other0)) => { + (GenericArgument::Constraint(self0), GenericArgument::Constraint(other0)) => { self0 == other0 } _ => false, diff --git a/vendor/syn/src/gen/fold.rs b/vendor/syn/src/gen/fold.rs index 6e19e6f3a..98bb5794a 100644 --- a/vendor/syn/src/gen/fold.rs +++ b/vendor/syn/src/gen/fold.rs @@ -1787,15 +1787,15 @@ where GenericArgument::Type(_binding_0) => { GenericArgument::Type(f.fold_type(_binding_0)) } + GenericArgument::Const(_binding_0) => { + GenericArgument::Const(f.fold_expr(_binding_0)) + } GenericArgument::Binding(_binding_0) => { GenericArgument::Binding(f.fold_binding(_binding_0)) } GenericArgument::Constraint(_binding_0) => { GenericArgument::Constraint(f.fold_constraint(_binding_0)) } - GenericArgument::Const(_binding_0) => { - GenericArgument::Const(f.fold_expr(_binding_0)) - } } } #[cfg(feature = "full")] diff --git a/vendor/syn/src/gen/hash.rs b/vendor/syn/src/gen/hash.rs index f68a7630e..d0400e19d 100644 --- a/vendor/syn/src/gen/hash.rs +++ b/vendor/syn/src/gen/hash.rs @@ -1184,15 +1184,15 @@ impl Hash for GenericArgument { state.write_u8(1u8); v0.hash(state); } - GenericArgument::Binding(v0) => { + GenericArgument::Const(v0) => { state.write_u8(2u8); v0.hash(state); } - GenericArgument::Constraint(v0) => { + GenericArgument::Binding(v0) => { state.write_u8(3u8); v0.hash(state); } - GenericArgument::Const(v0) => { + GenericArgument::Constraint(v0) => { state.write_u8(4u8); v0.hash(state); } diff --git a/vendor/syn/src/gen/visit.rs b/vendor/syn/src/gen/visit.rs index 051b65936..19ddd2e72 100644 --- a/vendor/syn/src/gen/visit.rs +++ b/vendor/syn/src/gen/visit.rs @@ -1974,15 +1974,15 @@ where GenericArgument::Type(_binding_0) => { v.visit_type(_binding_0); } + GenericArgument::Const(_binding_0) => { + v.visit_expr(_binding_0); + } GenericArgument::Binding(_binding_0) => { v.visit_binding(_binding_0); } GenericArgument::Constraint(_binding_0) => { v.visit_constraint(_binding_0); } - GenericArgument::Const(_binding_0) => { - v.visit_expr(_binding_0); - } } } #[cfg(feature = "full")] diff --git a/vendor/syn/src/gen/visit_mut.rs b/vendor/syn/src/gen/visit_mut.rs index 3ddbe9c06..239709d19 100644 --- a/vendor/syn/src/gen/visit_mut.rs +++ b/vendor/syn/src/gen/visit_mut.rs @@ -1975,15 +1975,15 @@ where GenericArgument::Type(_binding_0) => { v.visit_type_mut(_binding_0); } + GenericArgument::Const(_binding_0) => { + v.visit_expr_mut(_binding_0); + } GenericArgument::Binding(_binding_0) => { v.visit_binding_mut(_binding_0); } GenericArgument::Constraint(_binding_0) => { v.visit_constraint_mut(_binding_0); } - GenericArgument::Const(_binding_0) => { - v.visit_expr_mut(_binding_0); - } } } #[cfg(feature = "full")] diff --git a/vendor/syn/src/item.rs b/vendor/syn/src/item.rs index 1ce970ee2..a1ef7ab43 100644 --- a/vendor/syn/src/item.rs +++ b/vendor/syn/src/item.rs @@ -2765,7 +2765,6 @@ mod printing { use super::*; use crate::attr::FilterAttrs; use crate::print::TokensOrDefault; - use crate::punctuated::Pair; use proc_macro2::TokenStream; use quote::{ToTokens, TokenStreamExt}; @@ -3283,16 +3282,9 @@ mod printing { self.generics.to_tokens(tokens); self.paren_token.surround(tokens, |tokens| { let mut last_is_variadic = false; - for input in self.inputs.pairs() { - match input { - Pair::Punctuated(input, comma) => { - maybe_variadic_to_tokens(input, tokens); - comma.to_tokens(tokens); - } - Pair::End(input) => { - last_is_variadic = maybe_variadic_to_tokens(input, tokens); - } - } + for pair in self.inputs.pairs() { + last_is_variadic = maybe_variadic_to_tokens(pair.value(), tokens); + pair.punct().to_tokens(tokens); } if self.variadic.is_some() && !last_is_variadic { if !self.inputs.empty_or_trailing() { diff --git a/vendor/syn/src/lib.rs b/vendor/syn/src/lib.rs index 09addd3a6..81f03e1b5 100644 --- a/vendor/syn/src/lib.rs +++ b/vendor/syn/src/lib.rs @@ -250,10 +250,11 @@ //! dynamic library libproc_macro from rustc toolchain. // Syn types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/syn/1.0.99")] +#![doc(html_root_url = "https://docs.rs/syn/1.0.102")] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![allow(non_camel_case_types)] #![allow( + clippy::bool_to_int_with_if, clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_ptr_alignment, @@ -812,14 +813,6 @@ mod print; //////////////////////////////////////////////////////////////////////////////// -// https://github.com/rust-lang/rust/issues/62830 -#[cfg(feature = "parsing")] -mod rustdoc_workaround { - pub use crate::parse::{self as parse_module}; -} - -//////////////////////////////////////////////////////////////////////////////// - mod error; pub use crate::error::{Error, Result}; diff --git a/vendor/syn/src/lit.rs b/vendor/syn/src/lit.rs index 2600dc801..130b40ed1 100644 --- a/vendor/syn/src/lit.rs +++ b/vendor/syn/src/lit.rs @@ -224,7 +224,7 @@ impl LitStr { // Parse string literal into a token stream with every span equal to the // original literal's span. - let mut tokens = crate::parse_str(&self.value())?; + let mut tokens = TokenStream::from_str(&self.value())?; tokens = respan_token_stream(tokens, self.span()); parser.parse2(tokens) diff --git a/vendor/syn/src/parse_macro_input.rs b/vendor/syn/src/parse_macro_input.rs index 8e1a5ec6b..6163cd70a 100644 --- a/vendor/syn/src/parse_macro_input.rs +++ b/vendor/syn/src/parse_macro_input.rs @@ -4,7 +4,7 @@ /// Refer to the [`parse` module] documentation for more details about parsing /// in Syn. /// -/// [`parse` module]: crate::rustdoc_workaround::parse_module +/// [`parse` module]: mod@crate::parse /// ///
/// @@ -51,7 +51,7 @@ /// This macro can also be used with the [`Parser` trait] for types that have /// multiple ways that they can be parsed. /// -/// [`Parser` trait]: crate::rustdoc_workaround::parse_module::Parser +/// [`Parser` trait]: crate::parse::Parser /// /// ``` /// # extern crate proc_macro; diff --git a/vendor/syn/src/pat.rs b/vendor/syn/src/pat.rs index fa0818c16..b279186aa 100644 --- a/vendor/syn/src/pat.rs +++ b/vendor/syn/src/pat.rs @@ -400,11 +400,11 @@ pub mod parsing { } if input.peek(token::Brace) { - let pat = pat_struct(input, path)?; + let pat = pat_struct(begin.fork(), input, path)?; if qself.is_some() { Ok(Pat::Verbatim(verbatim::between(begin, input))) } else { - Ok(Pat::Struct(pat)) + Ok(pat) } } else if input.peek(token::Paren) { let pat = pat_tuple_struct(input, path)?; @@ -465,13 +465,23 @@ pub mod parsing { }) } - fn pat_struct(input: ParseStream, path: Path) -> Result { + fn pat_struct(begin: ParseBuffer, input: ParseStream, path: Path) -> Result { let content; let brace_token = braced!(content in input); let mut fields = Punctuated::new(); - while !content.is_empty() && !content.peek(Token![..]) { - let value = content.call(field_pat)?; + let mut dot2_token = None; + while !content.is_empty() { + let attrs = content.call(Attribute::parse_outer)?; + if content.peek(Token![..]) { + dot2_token = Some(content.parse()?); + if !attrs.is_empty() { + return Ok(Pat::Verbatim(verbatim::between(begin, input))); + } + break; + } + let mut value = content.call(field_pat)?; + value.attrs = attrs; fields.push_value(value); if content.is_empty() { break; @@ -480,19 +490,13 @@ pub mod parsing { fields.push_punct(punct); } - let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) { - Some(content.parse()?) - } else { - None - }; - - Ok(PatStruct { + Ok(Pat::Struct(PatStruct { attrs: Vec::new(), path, brace_token, fields, dot2_token, - }) + })) } impl Member { @@ -505,7 +509,6 @@ pub mod parsing { } fn field_pat(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; let boxed: Option = input.parse()?; let by_ref: Option = input.parse()?; let mutability: Option = input.parse()?; @@ -515,7 +518,7 @@ pub mod parsing { || member.is_unnamed() { return Ok(FieldPat { - attrs, + attrs: Vec::new(), member, colon_token: input.parse()?, pat: Box::new(multi_pat_with_leading_vert(input)?), @@ -544,7 +547,7 @@ pub mod parsing { } Ok(FieldPat { - attrs, + attrs: Vec::new(), member: Member::Named(ident), colon_token: None, pat: Box::new(pat), diff --git a/vendor/syn/src/path.rs b/vendor/syn/src/path.rs index 00be352b1..742273afd 100644 --- a/vendor/syn/src/path.rs +++ b/vendor/syn/src/path.rs @@ -109,16 +109,16 @@ ast_enum! { Lifetime(Lifetime), /// A type argument. Type(Type), - /// A binding (equality constraint) on an associated type: the `Item = - /// u8` in `Iterator`. - Binding(Binding), - /// An associated type bound: `Iterator`. - Constraint(Constraint), /// A const expression. Must be inside of a block. /// /// NOTE: Identity expressions are represented as Type arguments, as /// they are indistinguishable syntactically. Const(Expr), + /// A binding (equality constraint) on an associated type: the `Item = + /// u8` in `Iterator`. + Binding(Binding), + /// An associated type bound: `Iterator`. + Constraint(Constraint), } } @@ -729,8 +729,6 @@ pub(crate) mod printing { match self { GenericArgument::Lifetime(lt) => lt.to_tokens(tokens), GenericArgument::Type(ty) => ty.to_tokens(tokens), - GenericArgument::Binding(tb) => tb.to_tokens(tokens), - GenericArgument::Constraint(tc) => tc.to_tokens(tokens), GenericArgument::Const(e) => match *e { Expr::Lit(_) => e.to_tokens(tokens), @@ -746,6 +744,8 @@ pub(crate) mod printing { e.to_tokens(tokens); }), }, + GenericArgument::Binding(tb) => tb.to_tokens(tokens), + GenericArgument::Constraint(tc) => tc.to_tokens(tokens), } } } @@ -756,11 +756,8 @@ pub(crate) mod printing { self.colon2_token.to_tokens(tokens); self.lt_token.to_tokens(tokens); - // Print lifetimes before types and consts, all before bindings, - // regardless of their order in self.args. - // - // TODO: ordering rules for const arguments vs type arguments have - // not been settled yet. https://github.com/rust-lang/rust/issues/44580 + // Print lifetimes before types/consts/bindings, regardless of their + // order in self.args. let mut trailing_or_empty = true; for param in self.args.pairs() { match **param.value() { @@ -769,37 +766,24 @@ pub(crate) mod printing { trailing_or_empty = param.punct().is_some(); } GenericArgument::Type(_) - | GenericArgument::Binding(_) - | GenericArgument::Constraint(_) - | GenericArgument::Const(_) => {} - } - } - for param in self.args.pairs() { - match **param.value() { - GenericArgument::Type(_) | GenericArgument::Const(_) => { - if !trailing_or_empty { - ::default().to_tokens(tokens); - } - param.to_tokens(tokens); - trailing_or_empty = param.punct().is_some(); - } - GenericArgument::Lifetime(_) + | GenericArgument::Const(_) | GenericArgument::Binding(_) | GenericArgument::Constraint(_) => {} } } for param in self.args.pairs() { match **param.value() { - GenericArgument::Binding(_) | GenericArgument::Constraint(_) => { + GenericArgument::Type(_) + | GenericArgument::Const(_) + | GenericArgument::Binding(_) + | GenericArgument::Constraint(_) => { if !trailing_or_empty { ::default().to_tokens(tokens); } param.to_tokens(tokens); trailing_or_empty = param.punct().is_some(); } - GenericArgument::Lifetime(_) - | GenericArgument::Type(_) - | GenericArgument::Const(_) => {} + GenericArgument::Lifetime(_) => {} } } diff --git a/vendor/syn/src/stmt.rs b/vendor/syn/src/stmt.rs index 3e2c71bdd..58bd013ec 100644 --- a/vendor/syn/src/stmt.rs +++ b/vendor/syn/src/stmt.rs @@ -175,7 +175,11 @@ pub mod parsing { || input.peek(Token![crate]) && !input.peek2(Token![::]) || input.peek(Token![extern]) || input.peek(Token![use]) - || input.peek(Token![static]) && (input.peek2(Token![mut]) || input.peek2(Ident)) + || input.peek(Token![static]) + && (input.peek2(Token![mut]) + || input.peek2(Ident) + && !(input.peek2(Token![async]) + && (input.peek3(Token![move]) || input.peek3(Token![|])))) || input.peek(Token![const]) && !input.peek2(token::Brace) || input.peek(Token![unsafe]) && !input.peek2(token::Brace) || input.peek(Token![async]) diff --git a/vendor/syn/src/ty.rs b/vendor/syn/src/ty.rs index 0f1341fdd..4068be3c7 100644 --- a/vendor/syn/src/ty.rs +++ b/vendor/syn/src/ty.rs @@ -343,7 +343,8 @@ pub mod parsing { impl Parse for Type { fn parse(input: ParseStream) -> Result { let allow_plus = true; - ambig_ty(input, allow_plus) + let allow_group_generic = true; + ambig_ty(input, allow_plus, allow_group_generic) } } @@ -356,11 +357,16 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn without_plus(input: ParseStream) -> Result { let allow_plus = false; - ambig_ty(input, allow_plus) + let allow_group_generic = true; + ambig_ty(input, allow_plus, allow_group_generic) } } - fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result { + pub(crate) fn ambig_ty( + input: ParseStream, + allow_plus: bool, + allow_group_generic: bool, + ) -> Result { let begin = input.fork(); if input.peek(token::Group) { @@ -381,7 +387,9 @@ pub mod parsing { path: Path::parse_helper(input, false)?, })); } - } else if input.peek(Token![<]) || input.peek(Token![::]) && input.peek3(Token![<]) { + } else if input.peek(Token![<]) && allow_group_generic + || input.peek(Token![::]) && input.peek3(Token![<]) + { if let Type::Path(mut ty) = *group.elem { let arguments = &mut ty.path.segments.last_mut().unwrap().arguments; if let PathArguments::None = arguments { @@ -537,9 +545,15 @@ pub mod parsing { || lookahead.peek(Token![::]) || lookahead.peek(Token![<]) { - if input.peek(Token![dyn]) { - let trait_object = TypeTraitObject::parse(input, allow_plus)?; - return Ok(Type::TraitObject(trait_object)); + let dyn_token: Option = input.parse()?; + if dyn_token.is_some() { + let star_token: Option = input.parse()?; + let bounds = TypeTraitObject::parse_bounds(input, allow_plus)?; + return Ok(if star_token.is_some() { + Type::Verbatim(verbatim::between(begin, input)) + } else { + Type::TraitObject(TypeTraitObject { dyn_token, bounds }) + }); } let ty: TypePath = input.parse()?; @@ -819,15 +833,28 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for TypePath { fn parse(input: ParseStream) -> Result { - let (qself, mut path) = path::parsing::qpath(input, false)?; + let expr_style = false; + let (qself, mut path) = path::parsing::qpath(input, expr_style)?; - if path.segments.last().unwrap().arguments.is_empty() + while path.segments.last().unwrap().arguments.is_empty() && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren)) { input.parse::>()?; let args: ParenthesizedGenericArguments = input.parse()?; + let allow_associated_type = cfg!(feature = "full") + && match &args.output { + ReturnType::Default => true, + ReturnType::Type(_, ty) => match **ty { + // TODO: probably some of the other kinds allow this too. + Type::Paren(_) => true, + _ => false, + }, + }; let parenthesized = PathArguments::Parenthesized(args); path.segments.last_mut().unwrap().arguments = parenthesized; + if allow_associated_type { + Path::parse_rest(input, &mut path, expr_style)?; + } } Ok(TypePath { qself, path }) @@ -844,7 +871,8 @@ pub mod parsing { pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result { if input.peek(Token![->]) { let arrow = input.parse()?; - let ty = ambig_ty(input, allow_plus)?; + let allow_group_generic = true; + let ty = ambig_ty(input, allow_plus, allow_group_generic)?; Ok(ReturnType::Type(arrow, Box::new(ty))) } else { Ok(ReturnType::Default) @@ -967,7 +995,10 @@ pub mod parsing { let content; Ok(TypeParen { paren_token: parenthesized!(content in input), - elem: Box::new(ambig_ty(&content, allow_plus)?), + elem: Box::new({ + let allow_group_generic = true; + ambig_ty(&content, allow_plus, allow_group_generic)? + }), }) } } diff --git a/vendor/syn/tests/.gitignore b/vendor/syn/tests/.gitignore deleted file mode 100644 index 291ed43a2..000000000 --- a/vendor/syn/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pending-snap diff --git a/vendor/syn/tests/common/eq.rs b/vendor/syn/tests/common/eq.rs index ff100aa41..a53146241 100644 --- a/vendor/syn/tests/common/eq.rs +++ b/vendor/syn/tests/common/eq.rs @@ -3,6 +3,7 @@ extern crate rustc_ast; extern crate rustc_data_structures; extern crate rustc_span; +extern crate thin_vec; use rustc_ast::ast::AngleBracketedArg; use rustc_ast::ast::AngleBracketedArgs; @@ -19,10 +20,11 @@ use rustc_ast::ast::AttrStyle; use rustc_ast::ast::Attribute; use rustc_ast::ast::BareFnTy; use rustc_ast::ast::BinOpKind; -use rustc_ast::ast::BindingMode; +use rustc_ast::ast::BindingAnnotation; use rustc_ast::ast::Block; use rustc_ast::ast::BlockCheckMode; use rustc_ast::ast::BorrowKind; +use rustc_ast::ast::ByRef; use rustc_ast::ast::CaptureBy; use rustc_ast::ast::ClosureBinder; use rustc_ast::ast::Const; @@ -82,6 +84,7 @@ use rustc_ast::ast::Movability; use rustc_ast::ast::MutTy; use rustc_ast::ast::Mutability; use rustc_ast::ast::NodeId; +use rustc_ast::ast::NormalAttr; use rustc_ast::ast::Param; use rustc_ast::ast::ParenthesizedArgs; use rustc_ast::ast::Pat; @@ -127,14 +130,14 @@ use rustc_ast::ast::WhereRegionPredicate; use rustc_ast::ptr::P; use rustc_ast::token::{self, CommentKind, Delimiter, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{ - AttrAnnotatedTokenStream, AttrAnnotatedTokenTree, AttributesData, DelimSpan, LazyTokenStream, - Spacing, TokenStream, TokenTree, + AttrTokenStream, AttrTokenTree, AttributesData, DelimSpan, LazyAttrTokenStream, Spacing, + TokenStream, TokenTree, }; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::thin_vec::ThinVec; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, Symbol, SyntaxContext, DUMMY_SP}; +use thin_vec::ThinVec; pub trait SpanlessEq { fn eq(&self, other: &Self) -> bool; @@ -401,11 +404,12 @@ spanless_eq_struct!(AngleBracketedArgs; span args); spanless_eq_struct!(AnonConst; id value); spanless_eq_struct!(Arm; attrs pat guard body span id is_placeholder); spanless_eq_struct!(AssocConstraint; id ident gen_args kind span); -spanless_eq_struct!(AttrAnnotatedTokenStream; 0); spanless_eq_struct!(AttrItem; path args tokens); +spanless_eq_struct!(AttrTokenStream; 0); spanless_eq_struct!(Attribute; kind id style span); spanless_eq_struct!(AttributesData; attrs tokens); spanless_eq_struct!(BareFnTy; unsafety ext generic_params decl decl_span); +spanless_eq_struct!(BindingAnnotation; 0 1); spanless_eq_struct!(Block; stmts id rules span tokens could_be_bare_literal); spanless_eq_struct!(Crate; attrs items spans id is_placeholder); spanless_eq_struct!(EnumDef; variants); @@ -425,13 +429,14 @@ spanless_eq_struct!(InlineAsmSym; id qself path); spanless_eq_struct!(Item; attrs id span vis ident kind !tokens); spanless_eq_struct!(Label; ident); spanless_eq_struct!(Lifetime; id ident); -spanless_eq_struct!(Lit; token kind span); +spanless_eq_struct!(Lit; token_lit kind span); spanless_eq_struct!(Local; pat ty kind id span attrs !tokens); spanless_eq_struct!(MacCall; path args prior_type_ascription); spanless_eq_struct!(MacCallStmt; mac style attrs tokens); spanless_eq_struct!(MacroDef; body macro_rules); spanless_eq_struct!(ModSpans; !inner_span !inject_use_span); spanless_eq_struct!(MutTy; ty mutbl); +spanless_eq_struct!(NormalAttr; item tokens); spanless_eq_struct!(ParenthesizedArgs; span inputs inputs_span output); spanless_eq_struct!(Pat; id kind span tokens); spanless_eq_struct!(PatField; ident pat is_shorthand attrs id span is_placeholder); @@ -453,19 +458,19 @@ spanless_eq_struct!(Variant; attrs id span !vis ident data disr_expr is_placehol spanless_eq_struct!(Visibility; kind span tokens); spanless_eq_struct!(WhereBoundPredicate; span bound_generic_params bounded_ty bounds); spanless_eq_struct!(WhereClause; has_where_token predicates span); -spanless_eq_struct!(WhereEqPredicate; id span lhs_ty rhs_ty); +spanless_eq_struct!(WhereEqPredicate; span lhs_ty rhs_ty); spanless_eq_struct!(WhereRegionPredicate; span lifetime bounds); spanless_eq_struct!(token::Lit; kind symbol suffix); spanless_eq_enum!(AngleBracketedArg; Arg(0) Constraint(0)); spanless_eq_enum!(AssocItemKind; Const(0 1 2) Fn(0) TyAlias(0) MacCall(0)); spanless_eq_enum!(AssocConstraintKind; Equality(term) Bound(bounds)); spanless_eq_enum!(Async; Yes(span closure_id return_impl_trait_id) No); -spanless_eq_enum!(AttrAnnotatedTokenTree; Token(0) Delimited(0 1 2) Attributes(0)); spanless_eq_enum!(AttrStyle; Outer Inner); +spanless_eq_enum!(AttrTokenTree; Token(0 1) Delimited(0 1 2) Attributes(0)); spanless_eq_enum!(BinOpKind; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt); -spanless_eq_enum!(BindingMode; ByRef(0) ByValue(0)); spanless_eq_enum!(BlockCheckMode; Default Unsafe(0)); spanless_eq_enum!(BorrowKind; Ref Raw); +spanless_eq_enum!(ByRef; Yes No); spanless_eq_enum!(CaptureBy; Value Ref); spanless_eq_enum!(ClosureBinder; NotPresent For(span generic_params)); spanless_eq_enum!(Const; Yes(0) No); @@ -502,22 +507,23 @@ spanless_eq_enum!(StructRest; Base(0) Rest(0) None); spanless_eq_enum!(Term; Ty(0) Const(0)); spanless_eq_enum!(TokenTree; Token(0 1) Delimited(0 1 2)); spanless_eq_enum!(TraitBoundModifier; None Maybe MaybeConst MaybeConstMaybe); -spanless_eq_enum!(TraitObjectSyntax; Dyn None); +spanless_eq_enum!(TraitObjectSyntax; Dyn DynStar None); spanless_eq_enum!(UintTy; Usize U8 U16 U32 U64 U128); spanless_eq_enum!(UnOp; Deref Not Neg); spanless_eq_enum!(Unsafe; Yes(0) No); spanless_eq_enum!(UnsafeSource; CompilerGenerated UserProvided); spanless_eq_enum!(UseTreeKind; Simple(0 1 2) Nested(0) Glob); spanless_eq_enum!(VariantData; Struct(0 1) Tuple(0 1) Unit(0)); -spanless_eq_enum!(VisibilityKind; Public Restricted(path id) Inherited); +spanless_eq_enum!(VisibilityKind; Public Restricted(path id shorthand) Inherited); spanless_eq_enum!(WherePredicate; BoundPredicate(0) RegionPredicate(0) EqPredicate(0)); spanless_eq_enum!(ExprKind; Box(0) Array(0) ConstBlock(0) Call(0 1) - MethodCall(0 1 2) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1) - Let(0 1 2) If(0 1 2) While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) Match(0 1) - Closure(0 1 2 3 4 5 6) Block(0 1) Async(0 1 2) Await(0) TryBlock(0) - Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore Range(0 1 2) - Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) InlineAsm(0) - MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0) Yield(0) Yeet(0) Err); + MethodCall(0 1 2 3) Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) + Type(0 1) Let(0 1 2) If(0 1 2) While(0 1 2) ForLoop(0 1 2 3) Loop(0 1) + Match(0 1) Closure(0 1 2 3 4 5 6) Block(0 1) Async(0 1 2) Await(0) + TryBlock(0) Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1) Underscore + Range(0 1 2) Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0) + InlineAsm(0) MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0) Yield(0) + Yeet(0) Err); spanless_eq_enum!(InlineAsmOperand; In(reg expr) Out(reg late expr) InOut(reg late expr) SplitInOut(reg late in_expr out_expr) Const(anon_const) Sym(sym)); @@ -525,7 +531,7 @@ spanless_eq_enum!(ItemKind; ExternCrate(0) Use(0) Static(0 1 2) Const(0 1 2) Fn(0) Mod(0 1) ForeignMod(0) GlobalAsm(0) TyAlias(0) Enum(0 1) Struct(0 1) Union(0 1) Trait(0) TraitAlias(0 1) Impl(0) MacCall(0) MacroDef(0)); spanless_eq_enum!(LitKind; Str(0 1) ByteStr(0) Byte(0) Char(0) Int(0 1) - Float(0 1) Bool(0) Err(0)); + Float(0 1) Bool(0) Err); spanless_eq_enum!(PatKind; Wild Ident(0 1 2) Struct(0 1 2 3) TupleStruct(0 1 2) Or(0) Path(0 1) Tuple(0) Box(0) Ref(0 1) Lit(0) Range(0 1 2) Slice(0) Rest Paren(0) MacCall(0)); @@ -691,7 +697,7 @@ fn is_escaped_literal_token(token: &Token, unescaped: Symbol) -> bool { Token { kind: TokenKind::Literal(lit), span: _, - } => match Lit::from_lit_token(*lit, DUMMY_SP) { + } => match Lit::from_token_lit(*lit, DUMMY_SP) { Ok(lit) => is_escaped_literal(&lit, unescaped), Err(_) => false, }, @@ -722,7 +728,7 @@ fn is_escaped_literal_macro_arg(arg: &MacArgsEq, unescaped: Symbol) -> bool { fn is_escaped_literal(lit: &Lit, unescaped: Symbol) -> bool { match lit { Lit { - token: + token_lit: token::Lit { kind: token::LitKind::Str, symbol: _, @@ -735,10 +741,10 @@ fn is_escaped_literal(lit: &Lit, unescaped: Symbol) -> bool { } } -impl SpanlessEq for LazyTokenStream { +impl SpanlessEq for LazyAttrTokenStream { fn eq(&self, other: &Self) -> bool { - let this = self.create_token_stream(); - let other = other.create_token_stream(); + let this = self.to_attr_token_stream(); + let other = other.to_attr_token_stream(); SpanlessEq::eq(&this, &other) } } @@ -746,26 +752,26 @@ impl SpanlessEq for LazyTokenStream { impl SpanlessEq for AttrKind { fn eq(&self, other: &Self) -> bool { match (self, other) { - (AttrKind::Normal(item, tokens), AttrKind::Normal(item2, tokens2)) => { - SpanlessEq::eq(item, item2) && SpanlessEq::eq(tokens, tokens2) + (AttrKind::Normal(normal), AttrKind::Normal(normal2)) => { + SpanlessEq::eq(normal, normal2) } (AttrKind::DocComment(kind, symbol), AttrKind::DocComment(kind2, symbol2)) => { SpanlessEq::eq(kind, kind2) && SpanlessEq::eq(symbol, symbol2) } - (AttrKind::DocComment(kind, unescaped), AttrKind::Normal(item2, _tokens)) => { + (AttrKind::DocComment(kind, unescaped), AttrKind::Normal(normal2)) => { match kind { CommentKind::Line | CommentKind::Block => {} } let path = Path::from_ident(Ident::with_dummy_span(sym::doc)); - SpanlessEq::eq(&path, &item2.path) - && match &item2.args { + SpanlessEq::eq(&path, &normal2.item.path) + && match &normal2.item.args { MacArgs::Empty | MacArgs::Delimited(..) => false, MacArgs::Eq(_span, token) => { is_escaped_literal_macro_arg(token, *unescaped) } } } - (AttrKind::Normal(..), AttrKind::DocComment(..)) => SpanlessEq::eq(other, self), + (AttrKind::Normal(_), AttrKind::DocComment(..)) => SpanlessEq::eq(other, self), } } } diff --git a/vendor/syn/tests/debug/gen.rs b/vendor/syn/tests/debug/gen.rs index a49ee6c92..cfd63d117 100644 --- a/vendor/syn/tests/debug/gen.rs +++ b/vendor/syn/tests/debug/gen.rs @@ -2215,22 +2215,22 @@ impl Debug for Lite { formatter.write_str(")")?; Ok(()) } - syn::GenericArgument::Binding(_val) => { - formatter.write_str("Binding")?; + syn::GenericArgument::Const(_val) => { + formatter.write_str("Const")?; formatter.write_str("(")?; Debug::fmt(Lite(_val), formatter)?; formatter.write_str(")")?; Ok(()) } - syn::GenericArgument::Constraint(_val) => { - formatter.write_str("Constraint")?; + syn::GenericArgument::Binding(_val) => { + formatter.write_str("Binding")?; formatter.write_str("(")?; Debug::fmt(Lite(_val), formatter)?; formatter.write_str(")")?; Ok(()) } - syn::GenericArgument::Const(_val) => { - formatter.write_str("Const")?; + syn::GenericArgument::Constraint(_val) => { + formatter.write_str("Constraint")?; formatter.write_str("(")?; Debug::fmt(Lite(_val), formatter)?; formatter.write_str(")")?; diff --git a/vendor/syn/tests/regression/issue1108.rs b/vendor/syn/tests/regression/issue1108.rs index 11a82adaa..4fd30c0c7 100644 --- a/vendor/syn/tests/regression/issue1108.rs +++ b/vendor/syn/tests/regression/issue1108.rs @@ -1,5 +1,5 @@ #[test] fn issue1108() { let data = "impl>::x for"; - let _ = syn::parse_file(data); + _ = syn::parse_file(data); } diff --git a/vendor/syn/tests/repo/mod.rs b/vendor/syn/tests/repo/mod.rs index 0bafe6714..4c7be853b 100644 --- a/vendor/syn/tests/repo/mod.rs +++ b/vendor/syn/tests/repo/mod.rs @@ -10,10 +10,10 @@ use std::path::Path; use tar::Archive; use walkdir::DirEntry; -const REVISION: &str = "ee160f2f5e73b6f5954bc33f059c316d9e8582c4"; +const REVISION: &str = "98ad6a5519651af36e246c0335c964dd52c554ba"; #[rustfmt::skip] -static EXCLUDE: &[&str] = &[ +static EXCLUDE_FILES: &[&str] = &[ // TODO: impl ~const T {} // https://github.com/dtolnay/syn/issues/1051 "src/test/ui/rfc-2632-const-trait-impl/syntax.rs", @@ -33,6 +33,21 @@ static EXCLUDE: &[&str] = &[ "src/tools/rustfmt/tests/source/trait.rs", "src/tools/rustfmt/tests/target/trait.rs", + // Various extensions to Rust syntax made up by rust-analyzer + "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0015_use_tree.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0029_range_forms.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs", + "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0068_item_modifiers.rs", + "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs", + "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs", + "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs", + // Placeholder syntax for "throw expressions" "src/test/pretty/yeet-expr.rs", "src/test/ui/try-trait/yeet-for-option.rs", @@ -41,7 +56,9 @@ static EXCLUDE: &[&str] = &[ // Excessive nesting "src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs", - // Testing rustfmt on invalid syntax + // Testing tools on invalid syntax + "src/test/run-make/translation/test.rs", + "src/test/ui/generics/issue-94432-garbage-ice.rs", "src/tools/rustfmt/tests/coverage/target/comments.rs", "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs", "src/tools/rustfmt/tests/parser/issue_4418.rs", @@ -54,8 +71,8 @@ static EXCLUDE: &[&str] = &[ "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs", "src/tools/rustfmt/tests/target/type.rs", - // Testing compiler diagnostic localization on invalid syntax - "src/test/run-make/translation/basic-translation.rs", + // Generated file containing a top-level expression, used with `include!` + "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs", // Clippy lint lists represented as expressions "src/tools/clippy/clippy_lints/src/lib.deprecated.rs", @@ -73,9 +90,6 @@ static EXCLUDE: &[&str] = &[ "src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs", // Not actually test cases - "src/test/rustdoc-ui/test-compile-fail2.rs", - "src/test/rustdoc-ui/test-compile-fail3.rs", - "src/test/ui/json-bom-plus-crlf-multifile-aux.rs", "src/test/ui/lint/expansion-time-include.rs", "src/test/ui/macros/auxiliary/macro-comma-support.rs", "src/test/ui/macros/auxiliary/macro-include-items-expr.rs", @@ -84,38 +98,52 @@ static EXCLUDE: &[&str] = &[ "src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs", ]; +#[rustfmt::skip] +static EXCLUDE_DIRS: &[&str] = &[ + // Inputs that intentionally do not parse + "src/tools/rust-analyzer/crates/parser/test_data/parser/err", + "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err", + + // Inputs that lex but do not necessarily parse + "src/tools/rust-analyzer/crates/parser/test_data/lexer", + + // Inputs that used to crash rust-analyzer, but aren't necessarily supposed to parse + "src/tools/rust-analyzer/crates/syntax/test_data/parser/fuzz-failures", + "src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures", +]; + pub fn base_dir_filter(entry: &DirEntry) -> bool { let path = entry.path(); - if path.is_dir() { - return true; // otherwise walkdir does not visit the files - } - if path.extension().map_or(true, |e| e != "rs") { - return false; - } let mut path_string = path.to_string_lossy(); if cfg!(windows) { path_string = path_string.replace('\\', "/").into(); } - let path = if let Some(path) = path_string.strip_prefix("tests/rust/") { + let path_string = if path_string == "tests/rust" { + return true; + } else if let Some(path) = path_string.strip_prefix("tests/rust/") { path } else { panic!("unexpected path in Rust dist: {}", path_string); }; - if path.starts_with("src/test/compile-fail") || path.starts_with("src/test/rustfix") { + if path.is_dir() { + return !EXCLUDE_DIRS.contains(&path_string); + } + + if path.extension().map_or(true, |e| e != "rs") { return false; } - if path.starts_with("src/test/ui") { - let stderr_path = entry.path().with_extension("stderr"); + if path_string.starts_with("src/test/ui") || path_string.starts_with("src/test/rustdoc-ui") { + let stderr_path = path.with_extension("stderr"); if stderr_path.exists() { // Expected to fail in some way return false; } } - !EXCLUDE.contains(&path) + !EXCLUDE_FILES.contains(&path_string) } #[allow(dead_code)] @@ -137,10 +165,17 @@ pub fn clone_rust() { } let mut missing = String::new(); let test_src = Path::new("tests/rust"); - for exclude in EXCLUDE { - if !test_src.join(exclude).exists() { + for exclude in EXCLUDE_FILES { + if !test_src.join(exclude).is_file() { + missing += "\ntests/rust/"; + missing += exclude; + } + } + for exclude in EXCLUDE_DIRS { + if !test_src.join(exclude).is_dir() { missing += "\ntests/rust/"; missing += exclude; + missing += "/"; } } if !missing.is_empty() { diff --git a/vendor/syn/tests/test_parse_stream.rs b/vendor/syn/tests/test_parse_stream.rs index 76bd06577..cc14fa032 100644 --- a/vendor/syn/tests/test_parse_stream.rs +++ b/vendor/syn/tests/test_parse_stream.rs @@ -4,9 +4,9 @@ use syn::{Ident, Token}; #[test] fn test_peek() { - let _ = |input: ParseStream| { - let _ = input.peek(Ident); - let _ = input.peek(Ident::peek_any); - let _ = input.peek(Token![::]); + _ = |input: ParseStream| { + _ = input.peek(Ident); + _ = input.peek(Ident::peek_any); + _ = input.peek(Token![::]); }; } diff --git a/vendor/syn/tests/test_precedence.rs b/vendor/syn/tests/test_precedence.rs index bd273a565..dbcd74f16 100644 --- a/vendor/syn/tests/test_precedence.rs +++ b/vendor/syn/tests/test_precedence.rs @@ -24,6 +24,7 @@ extern crate rustc_ast; extern crate rustc_data_structures; extern crate rustc_span; +extern crate thin_vec; use crate::common::eq::SpanlessEq; use crate::common::parse; @@ -207,10 +208,10 @@ fn librustc_brackets(mut librustc_expr: P) -> Option> { }; use rustc_ast::mut_visit::{noop_visit_generic_arg, noop_visit_local, MutVisitor}; use rustc_data_structures::map_in_place::MapInPlace; - use rustc_data_structures::thin_vec::ThinVec; use rustc_span::DUMMY_SP; use std::mem; use std::ops::DerefMut; + use thin_vec::ThinVec; struct BracketsVisitor { failed: bool, @@ -243,7 +244,7 @@ fn librustc_brackets(mut librustc_expr: P) -> Option> { } fn noop_visit_expr(e: &mut Expr, vis: &mut T) { - use rustc_ast::mut_visit::{noop_visit_expr, visit_thin_attrs}; + use rustc_ast::mut_visit::{noop_visit_expr, visit_attrs}; match &mut e.kind { ExprKind::AddrOf(BorrowKind::Raw, ..) => {} ExprKind::Struct(expr) => { @@ -261,7 +262,7 @@ fn librustc_brackets(mut librustc_expr: P) -> Option> { } vis.visit_id(&mut e.id); vis.visit_span(&mut e.span); - visit_thin_attrs(&mut e.attrs, vis); + visit_attrs(&mut e.attrs, vis); } _ => noop_visit_expr(e, vis), } @@ -322,15 +323,15 @@ fn librustc_brackets(mut librustc_expr: P) -> Option> { // types yet. We'll look into comparing those in the future. For now // focus on expressions appearing in other places. fn visit_pat(&mut self, pat: &mut P) { - let _ = pat; + _ = pat; } fn visit_ty(&mut self, ty: &mut P) { - let _ = ty; + _ = ty; } fn visit_attribute(&mut self, attr: &mut Attribute) { - let _ = attr; + _ = attr; } } @@ -426,7 +427,7 @@ fn syn_brackets(syn_expr: syn::Expr) -> syn::Expr { fn collect_exprs(file: syn::File) -> Vec { use syn::fold::Fold; use syn::punctuated::Punctuated; - use syn::{token, Expr, ExprTuple, Path}; + use syn::{token, ConstParam, Expr, ExprTuple, Path}; struct CollectExprs(Vec); impl Fold for CollectExprs { @@ -447,6 +448,10 @@ fn collect_exprs(file: syn::File) -> Vec { // Skip traversing into const generic path arguments path } + + fn fold_const_param(&mut self, const_param: ConstParam) -> ConstParam { + const_param + } } let mut folder = CollectExprs(vec![]); diff --git a/vendor/syn/tests/test_size.rs b/vendor/syn/tests/test_size.rs index e172df2bc..02b0700f0 100644 --- a/vendor/syn/tests/test_size.rs +++ b/vendor/syn/tests/test_size.rs @@ -5,17 +5,17 @@ use syn::{Expr, Item, Lit, Pat, Type}; #[test] fn test_expr_size() { - assert_eq!(mem::size_of::(), 280); + assert_eq!(mem::size_of::(), 264); } #[test] fn test_item_size() { - assert_eq!(mem::size_of::(), 344); + assert_eq!(mem::size_of::(), 320); } #[test] fn test_type_size() { - assert_eq!(mem::size_of::(), 304); + assert_eq!(mem::size_of::(), 280); } #[test] @@ -25,5 +25,5 @@ fn test_pat_size() { #[test] fn test_lit_size() { - assert_eq!(mem::size_of::(), 40); + assert_eq!(mem::size_of::(), 32); } diff --git a/vendor/thiserror-impl/.cargo-checksum.json b/vendor/thiserror-impl/.cargo-checksum.json index 002cf212c..e398ffbb5 100644 --- a/vendor/thiserror-impl/.cargo-checksum.json +++ b/vendor/thiserror-impl/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"3171e8d362ab2f3958292eb1862426b9206637c2941edbc482460f5e0b04c9d0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/ast.rs":"c7601e8394f5ee304365c520181f0dbeaa807ddaa71ce4a8618ea1a70f81b3b2","src/attr.rs":"d1fe75dde04cb8df6da4e1aaec5b38c2b0f634fa3432877993b3fec4cc08b6b5","src/expand.rs":"791000b41cc09250c04dbf2f7adc06f1254922986c86633471e934621ce31940","src/fmt.rs":"d63d39120c18712596f9f2a1715821148c2becd4d8bad5bc1b307210a84dbe98","src/generics.rs":"2076cde22271be355a8131a77add4b93f83ab0af4317cd2df5471fffa4f95c66","src/lib.rs":"7d023310cd3db670554ce108a6afd94e1ae3c55c83661d4b9fcebdf1865b9e4b","src/prop.rs":"6709932aee8f9d217f40cd644629c0ecb2f46d333ae8a1398e8d745534f4e028","src/valid.rs":"ac95253944fd360d3578d0643a7baabb2cfa6bf9fbced7a6ce1f7b0529a3bb98"},"package":"c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09"} \ No newline at end of file +{"files":{"Cargo.toml":"af63bbe7a8ec50e29f44aa648a65afd05486852589b467030d28bbd7e0c878f4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/ast.rs":"c7601e8394f5ee304365c520181f0dbeaa807ddaa71ce4a8618ea1a70f81b3b2","src/attr.rs":"d1fe75dde04cb8df6da4e1aaec5b38c2b0f634fa3432877993b3fec4cc08b6b5","src/expand.rs":"8e2bc7ca24e8f8d9b179b792e772d3699154b750a08dcb942be298b7cc032563","src/fmt.rs":"d63d39120c18712596f9f2a1715821148c2becd4d8bad5bc1b307210a84dbe98","src/generics.rs":"2076cde22271be355a8131a77add4b93f83ab0af4317cd2df5471fffa4f95c66","src/lib.rs":"7d023310cd3db670554ce108a6afd94e1ae3c55c83661d4b9fcebdf1865b9e4b","src/prop.rs":"6709932aee8f9d217f40cd644629c0ecb2f46d333ae8a1398e8d745534f4e028","src/valid.rs":"ac95253944fd360d3578d0643a7baabb2cfa6bf9fbced7a6ce1f7b0529a3bb98"},"package":"982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"} \ No newline at end of file diff --git a/vendor/thiserror-impl/Cargo.toml b/vendor/thiserror-impl/Cargo.toml index c377ae01b..9f832394e 100644 --- a/vendor/thiserror-impl/Cargo.toml +++ b/vendor/thiserror-impl/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "thiserror-impl" -version = "1.0.33" +version = "1.0.37" authors = ["David Tolnay "] description = "Implementation detail of the `thiserror` crate" license = "MIT OR Apache-2.0" diff --git a/vendor/thiserror-impl/src/expand.rs b/vendor/thiserror-impl/src/expand.rs index f2f7116f2..43522096a 100644 --- a/vendor/thiserror-impl/src/expand.rs +++ b/vendor/thiserror-impl/src/expand.rs @@ -67,12 +67,12 @@ fn impl_struct(input: Struct) -> TokenStream { let source_provide = if type_is_option(source_field.ty) { quote_spanned! {source.span()=> if let std::option::Option::Some(source) = &self.#source { - source.as_dyn_error().provide(#demand); + source.thiserror_provide(#demand); } } } else { quote_spanned! {source.span()=> - self.#source.as_dyn_error().provide(#demand); + self.#source.thiserror_provide(#demand); } }; let self_provide = if source == backtrace { @@ -89,7 +89,7 @@ fn impl_struct(input: Struct) -> TokenStream { }) }; quote! { - use thiserror::__private::AsDynError; + use thiserror::__private::ThiserrorProvide; #source_provide #self_provide } @@ -259,12 +259,12 @@ fn impl_enum(input: Enum) -> TokenStream { let source_provide = if type_is_option(source_field.ty) { quote_spanned! {source.span()=> if let std::option::Option::Some(source) = #varsource { - source.as_dyn_error().provide(#demand); + source.thiserror_provide(#demand); } } } else { quote_spanned! {source.span()=> - #varsource.as_dyn_error().provide(#demand); + #varsource.thiserror_provide(#demand); } }; let self_provide = if type_is_option(backtrace_field.ty) { @@ -284,7 +284,7 @@ fn impl_enum(input: Enum) -> TokenStream { #source: #varsource, .. } => { - use thiserror::__private::AsDynError; + use thiserror::__private::ThiserrorProvide; #source_provide #self_provide } @@ -298,17 +298,17 @@ fn impl_enum(input: Enum) -> TokenStream { let source_provide = if type_is_option(source_field.ty) { quote_spanned! {backtrace.span()=> if let std::option::Option::Some(source) = #varsource { - source.as_dyn_error().provide(#demand); + source.thiserror_provide(#demand); } } } else { quote_spanned! {backtrace.span()=> - #varsource.as_dyn_error().provide(#demand); + #varsource.thiserror_provide(#demand); } }; quote! { #ty::#ident {#backtrace: #varsource, ..} => { - use thiserror::__private::AsDynError; + use thiserror::__private::ThiserrorProvide; #source_provide } } diff --git a/vendor/thiserror/.cargo-checksum.json b/vendor/thiserror/.cargo-checksum.json index f62a31345..b82148e8f 100644 --- a/vendor/thiserror/.cargo-checksum.json +++ b/vendor/thiserror/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"0de812f611be41d9b1962bdcb235479fed9d9d48eed22033fdb0c2cadbb0e602","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f774d4cb12047fef7c65a86e00eb7299f9250e0bc1aa445d16f63162ec942551","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/aserror.rs":"3dd14cfcfe4a0ab8b1dd774e4ea0a0197989afe84e0687e73873b61cfa4347fa","src/display.rs":"63c492bfa8b8e9180ad5abcbe63c1173b4ad490c47ec33cac9a338f96c8f8e42","src/lib.rs":"62b459b2bf9b53647570511189ed4980a0aed10a9f49abec7c34cef53178a6b2","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test_backtrace.rs":"43323a073ca464b16e213869d3f459f07a0f9601f1516ec81371c825fb1ec8f2","tests/test_display.rs":"20fdc8903f06da3a698ef4377cccca26a71138ca6de67310c5bdb8a9fcb39d83","tests/test_error.rs":"d06dca3c38f22d7ce4e27dadd6c0f78e5cefe3a2ebbc5fe44abc9ddd5ee1985f","tests/test_expr.rs":"388402702a3be4ffcd0574d66733e8932bf7d5de37544a00ecb0e4f8d8246da4","tests/test_from.rs":"de1347e62069f826d8616b9e45ce6cccc3a8a8049cb51bd22d6763efe6118b0c","tests/test_generics.rs":"4f33747e3f62550d5af94687679af230ef92fbb3247ae4b41df46792a040e4dc","tests/test_lints.rs":"c17d79d77edfcdd4b8f6dcdcd1c70ad065cfbc747e1a618ac6343315d0b59ea4","tests/test_option.rs":"3a82af1ad206444b9955e3f2fda508d70f887ad0b7f7986bafc17496f63b07ab","tests/test_path.rs":"ef5452c7e828a0179f5ace7e19f95b9762aa887caf10244adbfe36ded712c090","tests/test_source.rs":"f2f04f11bf8a709eddb1c68f113cda0c2be87e56800d6b9d991bedd545b4642f","tests/test_transparent.rs":"cd8d5be14d00d610a1782104bea6c013618501dab5c3625178ecfcf66e31f939","tests/ui/bad-field-attr.rs":"c5b567e3091969a01061843fb2d95c5e1aa3fa81edfeecdf416a84a6fba40aa8","tests/ui/bad-field-attr.stderr":"78f576d5ec66464a77f1cdf0f5bb7dcdf18f7f04f1165983a6239ec59d908ea3","tests/ui/concat-display.rs":"3995bd6b3bdd67df7bb16499775d89600c0dd20895633fe807396a64c117078d","tests/ui/concat-display.stderr":"256dfde61ee689ebe51588b135e2e030bdf95ba5adef1cb59f588c797bbdeef2","tests/ui/duplicate-enum-source.rs":"bfe28ce18042d446a76c7411aa233598211ce1157fdd3cb87bff3b3fa7c33131","tests/ui/duplicate-enum-source.stderr":"3d32fead420b27b4497be49080bc3b78f7f0ba339ead3de6c94e5dc20302c18f","tests/ui/duplicate-fmt.rs":"af53b66445bcce076a114376747f176b42c060a156563a41ccb638ae14c451fd","tests/ui/duplicate-fmt.stderr":"998bb121ce6f1595fd99529a7a1b06451b6bf476924337dce5524a83a7a5f1a1","tests/ui/duplicate-struct-source.rs":"f3d5f8e3d6fccfcdbb630db291353709583a920c6bf46f9f9de9966b67ea4c0f","tests/ui/duplicate-struct-source.stderr":"fb761d76668ac42357cf37b03c0abdbae5de0a828034990850291c9cb6ab766d","tests/ui/duplicate-transparent.rs":"41a9447e85f1a47027023442acde55c3d8610ec46d91b39bd43a42d7a004d747","tests/ui/duplicate-transparent.stderr":"4975abad43e973df158f18098d9bcb9dc39f8e75d3e733ed5d6620d1ee065c11","tests/ui/from-backtrace-backtrace.rs":"1fd51c5a1f7f6b6ee676d9fc798b6276ef2ce75def33d07f0e4b7bbde3291859","tests/ui/from-backtrace-backtrace.stderr":"f9774e9dad51374501ef4a55fa2dacece4d1c70e29ca18761394bdb80a9a74da","tests/ui/from-not-source.rs":"744a55aeffe11066830159ac023c33aaa5576e313b341fa24440ee13dfe3ac98","tests/ui/from-not-source.stderr":"525038e8b841707b927434cca4549168f73bd305faca17552a0d1fffa542ccc4","tests/ui/lifetime.rs":"e72e0391695e47fcd07edbf3819f114e468e2097086ec687781c7c8d6b4b7da7","tests/ui/lifetime.stderr":"d889a23f71324afe95dafc5f9d15337fbdbc9977cb8924f0cafe3a3becf4ced7","tests/ui/missing-fmt.rs":"bc9e2830e54c2474ff6c27a766ed3dee88d29e40f93f30e8d64d63233866c17d","tests/ui/missing-fmt.stderr":"9a20ccee9b660fe31a5b3199307b48580bb8305cb9ce33d97d3fc767a0cfc614","tests/ui/no-display.rs":"962245372272d23e9833311c15e73221b3c7da822a2ff90189613af56ffb5c2e","tests/ui/no-display.stderr":"40f47b286b770808a7dc5ec7970bc5cd501c9400f2e50049cf3258174929a9c1","tests/ui/source-enum-not-error.rs":"7c57c63b3ec37bc456738acea2e1038de5b0f32fe7e83984037d7ad1ed921737","tests/ui/source-enum-not-error.stderr":"44c974bf0b87431af78ccc7b4e18ebdc45135ca584a254960dff3f908ed862a8","tests/ui/source-struct-not-error.rs":"09fb7713637242dca9192585a6daeb8d732dc1c1d0fa522b74f1c98618e6d949","tests/ui/source-struct-not-error.stderr":"8e087a059c6b69de44e149ab3b5bffc4f4c6c3cbbb13c235c9a3c7c264be3245","tests/ui/transparent-display.rs":"b3c59583eb64b0b5a246444456d03cf52d51bcdc08885023600dbb44fd87e5f2","tests/ui/transparent-display.stderr":"16d538914e0d92026bde4b4bec75660217da9ecc6b621d12d2eb81d33ed1d1da","tests/ui/transparent-enum-many.rs":"2a40a764fb4683bff57973eec61507a6c00f7d4d7a32da6e7bd0190c2e445434","tests/ui/transparent-enum-many.stderr":"f1d78c1d6d8edbef153420db4fb9ca3dc6076fa043b5b1bc0cd291daa417a3ea","tests/ui/transparent-enum-source.rs":"18f606a98ac0a53f08dc56f5f923b9cbe75d25ed34479c777b48dac305d5968c","tests/ui/transparent-enum-source.stderr":"1b2e0ac53951034575d43ec0396c4e2b3cfb272db2aef8d6baa13a7e1632cc84","tests/ui/transparent-struct-many.rs":"72c6b6c1a44c203d3bc68989b2f1ec092531ef75b745432824c3776c290326f6","tests/ui/transparent-struct-many.stderr":"7bd0536dbb54a0ce7d4a8e66ca7624a1b132d8a1d1e4fecca642ec77494ac01c","tests/ui/transparent-struct-source.rs":"863fa691ed7d27e8767da58d9ee11fd40d6642274b36338ca1074c07964ea2b3","tests/ui/transparent-struct-source.stderr":"267dab65929e67d32347fb467a00b43af931f8205d727d7671938580217fc70e","tests/ui/unexpected-field-fmt.rs":"29fba7b4d81c642ec8e47cfe053aa515acf9080a86d65e685363a48993becfe3","tests/ui/unexpected-field-fmt.stderr":"20731c4a08af04bed3ff513903adadd690b6bc532b15604557e7f25575a8338f","tests/ui/unexpected-struct-source.rs":"c6cbe882d622635c216feb8290b1bd536ce0ec4feee16bc087667a21b3641d5c","tests/ui/unexpected-struct-source.stderr":"7c8227513478f6cc09e8a28be337c8a0e758a06ca5978d774c91bd43c4a54043","tests/ui/union.rs":"331adff27cebd8b95b03b6742cc8247331fda1f961e1590ed39c8d39f50cf1d8","tests/ui/union.stderr":"5f67ad29753d6fb14bc03aef7d4a1f660ee7796e469c037efbf8b13456934ad3"},"package":"3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57"} \ No newline at end of file +{"files":{"Cargo.toml":"1d01528e44c86dd86ee07557c6cd89bd3cf37a2456e6f3430af299d84f304035","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"959ac4d4dc43ce39235613d853db8df4a0cfd79e262fc38aba43a98331643952","build.rs":"8b8d9cbf84b9a2fd108b49ecb4bae327da688d80b818acda9ee17170c788e193","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/aserror.rs":"c93bd9191f26a7599043b397e26822564d9bafaa339a19861182a9909e8a3811","src/display.rs":"63c492bfa8b8e9180ad5abcbe63c1173b4ad490c47ec33cac9a338f96c8f8e42","src/lib.rs":"3fcc3c1ab31a64215978b92e68c1421ec8c5fcb942e57eb35adb9cc07a865730","src/provide.rs":"b2f7a33f44f44a03e94f54cc4b79ba2dcc5fcf0fdf64b07cdd9588a6544c8d8e","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test_backtrace.rs":"fd1f326bc23e6c1611a51bc43c1d5092b32ee18a1613abe20da0818e5729c0ed","tests/test_deprecated.rs":"7b80a10f090a3982da017556d3d71398abcead59afd8278c7b9d9b1f7b66c7b3","tests/test_display.rs":"20fdc8903f06da3a698ef4377cccca26a71138ca6de67310c5bdb8a9fcb39d83","tests/test_error.rs":"d06dca3c38f22d7ce4e27dadd6c0f78e5cefe3a2ebbc5fe44abc9ddd5ee1985f","tests/test_expr.rs":"388402702a3be4ffcd0574d66733e8932bf7d5de37544a00ecb0e4f8d8246da4","tests/test_from.rs":"de1347e62069f826d8616b9e45ce6cccc3a8a8049cb51bd22d6763efe6118b0c","tests/test_generics.rs":"4f33747e3f62550d5af94687679af230ef92fbb3247ae4b41df46792a040e4dc","tests/test_lints.rs":"c17d79d77edfcdd4b8f6dcdcd1c70ad065cfbc747e1a618ac6343315d0b59ea4","tests/test_option.rs":"3a82af1ad206444b9955e3f2fda508d70f887ad0b7f7986bafc17496f63b07ab","tests/test_path.rs":"ef5452c7e828a0179f5ace7e19f95b9762aa887caf10244adbfe36ded712c090","tests/test_source.rs":"f2f04f11bf8a709eddb1c68f113cda0c2be87e56800d6b9d991bedd545b4642f","tests/test_transparent.rs":"cd8d5be14d00d610a1782104bea6c013618501dab5c3625178ecfcf66e31f939","tests/ui/bad-field-attr.rs":"c5b567e3091969a01061843fb2d95c5e1aa3fa81edfeecdf416a84a6fba40aa8","tests/ui/bad-field-attr.stderr":"78f576d5ec66464a77f1cdf0f5bb7dcdf18f7f04f1165983a6239ec59d908ea3","tests/ui/concat-display.rs":"3995bd6b3bdd67df7bb16499775d89600c0dd20895633fe807396a64c117078d","tests/ui/concat-display.stderr":"256dfde61ee689ebe51588b135e2e030bdf95ba5adef1cb59f588c797bbdeef2","tests/ui/duplicate-enum-source.rs":"bfe28ce18042d446a76c7411aa233598211ce1157fdd3cb87bff3b3fa7c33131","tests/ui/duplicate-enum-source.stderr":"3d32fead420b27b4497be49080bc3b78f7f0ba339ead3de6c94e5dc20302c18f","tests/ui/duplicate-fmt.rs":"af53b66445bcce076a114376747f176b42c060a156563a41ccb638ae14c451fd","tests/ui/duplicate-fmt.stderr":"998bb121ce6f1595fd99529a7a1b06451b6bf476924337dce5524a83a7a5f1a1","tests/ui/duplicate-struct-source.rs":"f3d5f8e3d6fccfcdbb630db291353709583a920c6bf46f9f9de9966b67ea4c0f","tests/ui/duplicate-struct-source.stderr":"fb761d76668ac42357cf37b03c0abdbae5de0a828034990850291c9cb6ab766d","tests/ui/duplicate-transparent.rs":"41a9447e85f1a47027023442acde55c3d8610ec46d91b39bd43a42d7a004d747","tests/ui/duplicate-transparent.stderr":"4975abad43e973df158f18098d9bcb9dc39f8e75d3e733ed5d6620d1ee065c11","tests/ui/from-backtrace-backtrace.rs":"1fd51c5a1f7f6b6ee676d9fc798b6276ef2ce75def33d07f0e4b7bbde3291859","tests/ui/from-backtrace-backtrace.stderr":"f9774e9dad51374501ef4a55fa2dacece4d1c70e29ca18761394bdb80a9a74da","tests/ui/from-not-source.rs":"744a55aeffe11066830159ac023c33aaa5576e313b341fa24440ee13dfe3ac98","tests/ui/from-not-source.stderr":"525038e8b841707b927434cca4549168f73bd305faca17552a0d1fffa542ccc4","tests/ui/lifetime.rs":"e72e0391695e47fcd07edbf3819f114e468e2097086ec687781c7c8d6b4b7da7","tests/ui/lifetime.stderr":"d889a23f71324afe95dafc5f9d15337fbdbc9977cb8924f0cafe3a3becf4ced7","tests/ui/missing-fmt.rs":"bc9e2830e54c2474ff6c27a766ed3dee88d29e40f93f30e8d64d63233866c17d","tests/ui/missing-fmt.stderr":"9a20ccee9b660fe31a5b3199307b48580bb8305cb9ce33d97d3fc767a0cfc614","tests/ui/no-display.rs":"962245372272d23e9833311c15e73221b3c7da822a2ff90189613af56ffb5c2e","tests/ui/no-display.stderr":"40f47b286b770808a7dc5ec7970bc5cd501c9400f2e50049cf3258174929a9c1","tests/ui/source-enum-not-error.rs":"7c57c63b3ec37bc456738acea2e1038de5b0f32fe7e83984037d7ad1ed921737","tests/ui/source-enum-not-error.stderr":"1bb601243ff11d5de08c70edf3fd89d52b4a89fcd2a5c7775d1bc11d056ced1e","tests/ui/source-struct-not-error.rs":"09fb7713637242dca9192585a6daeb8d732dc1c1d0fa522b74f1c98618e6d949","tests/ui/source-struct-not-error.stderr":"9a1a04d606309c82eea59d1745c833189f0b4f237f0741a17dd62c11ce16642d","tests/ui/transparent-display.rs":"b3c59583eb64b0b5a246444456d03cf52d51bcdc08885023600dbb44fd87e5f2","tests/ui/transparent-display.stderr":"16d538914e0d92026bde4b4bec75660217da9ecc6b621d12d2eb81d33ed1d1da","tests/ui/transparent-enum-many.rs":"2a40a764fb4683bff57973eec61507a6c00f7d4d7a32da6e7bd0190c2e445434","tests/ui/transparent-enum-many.stderr":"f1d78c1d6d8edbef153420db4fb9ca3dc6076fa043b5b1bc0cd291daa417a3ea","tests/ui/transparent-enum-source.rs":"18f606a98ac0a53f08dc56f5f923b9cbe75d25ed34479c777b48dac305d5968c","tests/ui/transparent-enum-source.stderr":"1b2e0ac53951034575d43ec0396c4e2b3cfb272db2aef8d6baa13a7e1632cc84","tests/ui/transparent-struct-many.rs":"72c6b6c1a44c203d3bc68989b2f1ec092531ef75b745432824c3776c290326f6","tests/ui/transparent-struct-many.stderr":"7bd0536dbb54a0ce7d4a8e66ca7624a1b132d8a1d1e4fecca642ec77494ac01c","tests/ui/transparent-struct-source.rs":"863fa691ed7d27e8767da58d9ee11fd40d6642274b36338ca1074c07964ea2b3","tests/ui/transparent-struct-source.stderr":"267dab65929e67d32347fb467a00b43af931f8205d727d7671938580217fc70e","tests/ui/unexpected-field-fmt.rs":"29fba7b4d81c642ec8e47cfe053aa515acf9080a86d65e685363a48993becfe3","tests/ui/unexpected-field-fmt.stderr":"20731c4a08af04bed3ff513903adadd690b6bc532b15604557e7f25575a8338f","tests/ui/unexpected-struct-source.rs":"c6cbe882d622635c216feb8290b1bd536ce0ec4feee16bc087667a21b3641d5c","tests/ui/unexpected-struct-source.stderr":"7c8227513478f6cc09e8a28be337c8a0e758a06ca5978d774c91bd43c4a54043","tests/ui/union.rs":"331adff27cebd8b95b03b6742cc8247331fda1f961e1590ed39c8d39f50cf1d8","tests/ui/union.stderr":"5f67ad29753d6fb14bc03aef7d4a1f660ee7796e469c037efbf8b13456934ad3"},"package":"10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"} \ No newline at end of file diff --git a/vendor/thiserror/Cargo.toml b/vendor/thiserror/Cargo.toml index 5926572e3..2f060d6d8 100644 --- a/vendor/thiserror/Cargo.toml +++ b/vendor/thiserror/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "thiserror" -version = "1.0.33" +version = "1.0.37" authors = ["David Tolnay "] description = "derive(Error)" documentation = "https://docs.rs/thiserror" @@ -31,10 +31,10 @@ repository = "https://github.com/dtolnay/thiserror" targets = ["x86_64-unknown-linux-gnu"] [dependencies.thiserror-impl] -version = "=1.0.33" +version = "=1.0.37" [dev-dependencies.anyhow] -version = "1.0" +version = "1.0.65" [dev-dependencies.ref-cast] version = "1.0" diff --git a/vendor/thiserror/README.md b/vendor/thiserror/README.md index 387a56e46..8f6b896de 100644 --- a/vendor/thiserror/README.md +++ b/vendor/thiserror/README.md @@ -124,8 +124,8 @@ pub enum DataStoreError { } ``` -- The Error trait's `backtrace()` method is implemented to return whichever - field has a type named `Backtrace`, if any. +- The Error trait's `provide()` method is implemented to provide whichever field + has a type named `Backtrace`, if any, as a `std::backtrace::Backtrace`. ```rust use std::backtrace::Backtrace; @@ -138,8 +138,9 @@ pub enum DataStoreError { ``` - If a field is both a source (named `source`, or has `#[source]` or `#[from]` - attribute) *and* is marked `#[backtrace]`, then the Error trait's - `backtrace()` method is forwarded to the source's backtrace. + attribute) *and* is marked `#[backtrace]`, then the Error trait's `provide()` + method is forwarded to the source's `provide` so that both layers of the error + share the same backtrace. ```rust #[derive(Error, Debug)] @@ -165,6 +166,27 @@ pub enum DataStoreError { } ``` + Another use case is hiding implementation details of an error representation + behind an opaque error type, so that the representation is able to evolve + without breaking the crate's public API. + + ```rust + // PublicError is public, but opaque and easy to keep compatible. + #[derive(Error, Debug)] + #[error(transparent)] + pub struct PublicError(#[from] ErrorRepr); + + impl PublicError { + // Accessors for anything we do want to expose publicly. + } + + // Private and free to change across minor version of the crate. + #[derive(Error, Debug)] + enum ErrorRepr { + ... + } + ``` + - See also the [`anyhow`] library for a convenient single error type to use in application code. diff --git a/vendor/thiserror/build.rs b/vendor/thiserror/build.rs new file mode 100644 index 000000000..004dfb015 --- /dev/null +++ b/vendor/thiserror/build.rs @@ -0,0 +1,66 @@ +use std::env; +use std::fs; +use std::path::Path; +use std::process::{Command, ExitStatus, Stdio}; +use std::str; + +// This code exercises the surface area that we expect of the Provider API. If +// the current toolchain is able to compile it, then thiserror is able to use +// providers for backtrace support. +const PROBE: &str = r#" + #![feature(provide_any)] + + use std::any::{Demand, Provider}; + + fn _f<'a, P: Provider>(p: &'a P, demand: &mut Demand<'a>) { + p.provide(demand); + } +"#; + +fn main() { + match compile_probe() { + Some(status) if status.success() => println!("cargo:rustc-cfg=provide_any"), + _ => {} + } +} + +fn compile_probe() -> Option { + let rustc = env::var_os("RUSTC")?; + let out_dir = env::var_os("OUT_DIR")?; + let probefile = Path::new(&out_dir).join("probe.rs"); + fs::write(&probefile, PROBE).ok()?; + + // Make sure to pick up Cargo rustc configuration. + let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") { + let mut cmd = Command::new(wrapper); + // The wrapper's first argument is supposed to be the path to rustc. + cmd.arg(rustc); + cmd + } else { + Command::new(rustc) + }; + + cmd.stderr(Stdio::null()) + .arg("--edition=2018") + .arg("--crate-name=thiserror_build") + .arg("--crate-type=lib") + .arg("--emit=metadata") + .arg("--out-dir") + .arg(out_dir) + .arg(probefile); + + if let Some(target) = env::var_os("TARGET") { + cmd.arg("--target").arg(target); + } + + // If Cargo wants to set RUSTFLAGS, use that. + if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { + if !rustflags.is_empty() { + for arg in rustflags.split('\x1f') { + cmd.arg(arg); + } + } + } + + cmd.status().ok() +} diff --git a/vendor/thiserror/src/aserror.rs b/vendor/thiserror/src/aserror.rs index c036b7b09..5fea84ef8 100644 --- a/vendor/thiserror/src/aserror.rs +++ b/vendor/thiserror/src/aserror.rs @@ -1,7 +1,7 @@ use std::error::Error; use std::panic::UnwindSafe; -pub trait AsDynError<'a> { +pub trait AsDynError<'a>: Sealed { fn as_dyn_error(&self) -> &(dyn Error + 'a); } @@ -39,3 +39,10 @@ impl<'a> AsDynError<'a> for dyn Error + Send + Sync + UnwindSafe + 'a { self } } + +pub trait Sealed {} +impl<'a, T: Error + 'a> Sealed for T {} +impl<'a> Sealed for dyn Error + 'a {} +impl<'a> Sealed for dyn Error + Send + 'a {} +impl<'a> Sealed for dyn Error + Send + Sync + 'a {} +impl<'a> Sealed for dyn Error + Send + Sync + UnwindSafe + 'a {} diff --git a/vendor/thiserror/src/lib.rs b/vendor/thiserror/src/lib.rs index 247199ffd..aae6552d0 100644 --- a/vendor/thiserror/src/lib.rs +++ b/vendor/thiserror/src/lib.rs @@ -146,8 +146,9 @@ //! # } //! ``` //! -//! - The Error trait's `backtrace()` method is implemented to return whichever -//! field has a type named `Backtrace`, if any. +//! - The Error trait's `provide()` method is implemented to provide whichever +//! field has a type named `Backtrace`, if any, as a +//! `std::backtrace::Backtrace`. //! //! ```rust //! # const IGNORE: &str = stringify! { @@ -163,7 +164,8 @@ //! //! - If a field is both a source (named `source`, or has `#[source]` or //! `#[from]` attribute) *and* is marked `#[backtrace]`, then the Error -//! trait's `backtrace()` method is forwarded to the source's backtrace. +//! trait's `provide()` method is forwarded to the source's `provide` so that +//! both layers of the error share the same backtrace. //! //! ```rust //! # const IGNORE: &str = stringify! { @@ -196,6 +198,31 @@ //! } //! ``` //! +//! Another use case is hiding implementation details of an error +//! representation behind an opaque error type, so that the representation is +//! able to evolve without breaking the crate's public API. +//! +//! ``` +//! # use thiserror::Error; +//! # +//! // PublicError is public, but opaque and easy to keep compatible. +//! #[derive(Error, Debug)] +//! #[error(transparent)] +//! pub struct PublicError(#[from] ErrorRepr); +//! +//! impl PublicError { +//! // Accessors for anything we do want to expose publicly. +//! } +//! +//! // Private and free to change across minor version of the crate. +//! #[derive(Error, Debug)] +//! enum ErrorRepr { +//! # /* +//! ... +//! # */ +//! } +//! ``` +//! //! - See also the [`anyhow`] library for a convenient single error type to use //! in application code. //! @@ -206,10 +233,14 @@ clippy::doc_markdown, clippy::module_name_repetitions, clippy::return_self_not_must_use, + clippy::wildcard_imports, )] +#![cfg_attr(provide_any, feature(provide_any))] mod aserror; mod display; +#[cfg(provide_any)] +mod provide; pub use thiserror_impl::*; @@ -218,4 +249,6 @@ pub use thiserror_impl::*; pub mod __private { pub use crate::aserror::AsDynError; pub use crate::display::{DisplayAsDisplay, PathAsDisplay}; + #[cfg(provide_any)] + pub use crate::provide::ThiserrorProvide; } diff --git a/vendor/thiserror/src/provide.rs b/vendor/thiserror/src/provide.rs new file mode 100644 index 000000000..524e7435d --- /dev/null +++ b/vendor/thiserror/src/provide.rs @@ -0,0 +1,15 @@ +use std::any::{Demand, Provider}; + +pub trait ThiserrorProvide: Sealed { + fn thiserror_provide<'a>(&'a self, demand: &mut Demand<'a>); +} + +impl ThiserrorProvide for T { + #[inline] + fn thiserror_provide<'a>(&'a self, demand: &mut Demand<'a>) { + self.provide(demand); + } +} + +pub trait Sealed {} +impl Sealed for T {} diff --git a/vendor/thiserror/tests/test_backtrace.rs b/vendor/thiserror/tests/test_backtrace.rs index 052c6f481..43f68b8b7 100644 --- a/vendor/thiserror/tests/test_backtrace.rs +++ b/vendor/thiserror/tests/test_backtrace.rs @@ -21,6 +21,7 @@ pub mod structs { use super::{Inner, InnerBacktrace}; use std::any; use std::backtrace::Backtrace; + use std::error::Error; use std::sync::Arc; use thiserror::Error; @@ -86,6 +87,20 @@ pub mod structs { backtrace: Arc, } + #[derive(Error, Debug)] + #[error("...")] + pub struct AnyhowBacktrace { + #[backtrace] + source: anyhow::Error, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct BoxDynErrorBacktrace { + #[backtrace] + source: Box, + } + #[test] fn test_backtrace() { let error = PlainBacktrace { @@ -121,6 +136,37 @@ pub mod structs { let error = ArcBacktraceFrom::from(Inner); assert!(any::request_ref::(&error).is_some()); + + let error = AnyhowBacktrace { + source: anyhow::Error::msg("..."), + }; + assert!(any::request_ref::(&error).is_some()); + + let error = BoxDynErrorBacktrace { + source: Box::new(PlainBacktrace { + backtrace: Backtrace::capture(), + }), + }; + assert!(any::request_ref::(&error).is_some()); + } + + // https://github.com/dtolnay/thiserror/issues/185 -- std::error::Error and + // std::any::Provide both have a method called 'provide', so directly + // calling it from generated code could be ambiguous. + #[test] + fn test_provide_name_collision() { + use std::any::Provider; + + #[derive(Error, Debug)] + #[error("...")] + struct MyError { + #[source] + #[backtrace] + x: std::io::Error, + } + + let _: dyn Error; + let _: dyn Provider; } } diff --git a/vendor/thiserror/tests/test_deprecated.rs b/vendor/thiserror/tests/test_deprecated.rs new file mode 100644 index 000000000..5524666ab --- /dev/null +++ b/vendor/thiserror/tests/test_deprecated.rs @@ -0,0 +1,10 @@ +#![deny(deprecated, clippy::all, clippy::pedantic)] + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[deprecated] + #[error("...")] + Deprecated, +} diff --git a/vendor/thiserror/tests/ui/source-enum-not-error.stderr b/vendor/thiserror/tests/ui/source-enum-not-error.stderr index da10c6e77..29ee54600 100644 --- a/vendor/thiserror/tests/ui/source-enum-not-error.stderr +++ b/vendor/thiserror/tests/ui/source-enum-not-error.stderr @@ -4,7 +4,7 @@ error[E0599]: the method `as_dyn_error` exists for reference `&NotError`, but it 4 | pub struct NotError; | ------------------- | | - | doesn't satisfy `NotError: AsDynError` + | doesn't satisfy `NotError: AsDynError<'_>` | doesn't satisfy `NotError: std::error::Error` ... 10 | source: NotError, @@ -12,9 +12,9 @@ error[E0599]: the method `as_dyn_error` exists for reference `&NotError`, but it | = note: the following trait bounds were not satisfied: `NotError: std::error::Error` - which is required by `NotError: AsDynError` + which is required by `NotError: AsDynError<'_>` `&NotError: std::error::Error` - which is required by `&NotError: AsDynError` + which is required by `&NotError: AsDynError<'_>` note: the following trait must be implemented --> $RUST/core/src/error.rs | diff --git a/vendor/thiserror/tests/ui/source-struct-not-error.stderr b/vendor/thiserror/tests/ui/source-struct-not-error.stderr index cc0e67aca..efa40281d 100644 --- a/vendor/thiserror/tests/ui/source-struct-not-error.stderr +++ b/vendor/thiserror/tests/ui/source-struct-not-error.stderr @@ -5,7 +5,7 @@ error[E0599]: the method `as_dyn_error` exists for struct `NotError`, but its tr | --------------- | | | method `as_dyn_error` not found for this struct - | doesn't satisfy `NotError: AsDynError` + | doesn't satisfy `NotError: AsDynError<'_>` | doesn't satisfy `NotError: std::error::Error` ... 9 | source: NotError, @@ -13,7 +13,7 @@ error[E0599]: the method `as_dyn_error` exists for struct `NotError`, but its tr | = note: the following trait bounds were not satisfied: `NotError: std::error::Error` - which is required by `NotError: AsDynError` + which is required by `NotError: AsDynError<'_>` note: the following trait must be implemented --> $RUST/core/src/error.rs | diff --git a/vendor/tracing-attributes/.cargo-checksum.json b/vendor/tracing-attributes/.cargo-checksum.json index 995155f68..e29c0854b 100644 --- a/vendor/tracing-attributes/.cargo-checksum.json +++ b/vendor/tracing-attributes/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"daa6621db253ddaaa095d297d0de2be41b03831a3992f2f9a5107749a689983e","Cargo.toml":"70c8c7dba6890f42c7830651ec9847c0e22b4c0987024d076d4abb3801f26bc8","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"7484033338a94e5ce23f1b281e1bdef1bae590c2329bd9b4d192ce66702e3a31","src/attr.rs":"4d26dad70c765fff3d4677ebe8e71b63599d67ceba5c48dbcb204d247b5394ce","src/expand.rs":"e6b81defa4ed98d71466ede6eb5a8f613cd0d33750b2e1274265467b85756362","src/lib.rs":"4400f3c00b7b4daf9cd61bec3e1f5d794c3d4b131667252a43c95a40041b6711","tests/async_fn.rs":"74126e6027bc9cb6e5e3d5d0e3b2debd5c808c737d25b90303b8e3ca878a3667","tests/destructuring.rs":"26b9800678bad09e06512a113a54556e2fac3ecb15a18dcccefe105fb8911c26","tests/err.rs":"3beb5f065e57a578825c383a56b9d64fb89794a508018bf36e16f113557909b8","tests/fields.rs":"3882bd4e744d6b492f59beac7475e8bf4ff4ca8ad85c6951c305a22c78e75fae","tests/follows_from.rs":"5bc856923e87b34e0558959149118238fe668ac621f1748cc444c21c90a86647","tests/instrument.rs":"9118eb6971d19a6b8d301bb4512b0fda909404a21e14edbef6b01db094cd8aaf","tests/levels.rs":"80ffb684163a4d28c69c40e31a82609ac02daf922086bab8247bca125aec3c69","tests/names.rs":"5afd6c4d526588bcea3141c130a45a21872956495b6868a01b44ddff57749827","tests/parents.rs":"673d3f81eed6ba433f685ec53fd007c5dd957b97d32499d7ea1537e1f289cb2e","tests/ret.rs":"083b4ca456d766c469b2fff7608b59524b422941e5c5e84f07c1ce0d7b345c7a","tests/targets.rs":"95ce1ce1e2d29794062c5b3429d91c1bfaba5813251d5d8440c12cb2db6e11bf"},"package":"11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"} \ No newline at end of file +{"files":{"CHANGELOG.md":"7c292985e41b0fd9c89d32bd15594b76bb3109ff96177af7461d1a0d3ea48574","Cargo.toml":"1c272401b940ef2fd88638a6228af02c14e3d47d4b592ee5c445f7470a0d1763","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"aae710a2c0c4ade929a84f8f3d9f98fcb9ad1c1e9e52ae0b0393db9f353f6248","src/attr.rs":"4d26dad70c765fff3d4677ebe8e71b63599d67ceba5c48dbcb204d247b5394ce","src/expand.rs":"f070e38eb3526c4c50e98cfafb2c26e50c7170f27d0bd716838a29777c1174cd","src/lib.rs":"14803c868525f6ae95b846ce2f369a47d50b2befba336335354867cf2a1b2455","tests/async_fn.rs":"6ae845ab6c508f9f2d1ea7ec3855971e8cff85afdae326593089d0a53c9c6dcf","tests/destructuring.rs":"26b9800678bad09e06512a113a54556e2fac3ecb15a18dcccefe105fb8911c26","tests/err.rs":"3beb5f065e57a578825c383a56b9d64fb89794a508018bf36e16f113557909b8","tests/fields.rs":"3882bd4e744d6b492f59beac7475e8bf4ff4ca8ad85c6951c305a22c78e75fae","tests/follows_from.rs":"5bc856923e87b34e0558959149118238fe668ac621f1748cc444c21c90a86647","tests/instrument.rs":"e3a90f2aef0d2f56c2c25018e2fbacf518e90ef6810930941f86740279252d03","tests/levels.rs":"80ffb684163a4d28c69c40e31a82609ac02daf922086bab8247bca125aec3c69","tests/names.rs":"5afd6c4d526588bcea3141c130a45a21872956495b6868a01b44ddff57749827","tests/parents.rs":"673d3f81eed6ba433f685ec53fd007c5dd957b97d32499d7ea1537e1f289cb2e","tests/ret.rs":"083b4ca456d766c469b2fff7608b59524b422941e5c5e84f07c1ce0d7b345c7a","tests/targets.rs":"95ce1ce1e2d29794062c5b3429d91c1bfaba5813251d5d8440c12cb2db6e11bf","tests/ui.rs":"c73c70fe7371998df077862092f40df7210b13496e119ab4e657a1848e42ab30","tests/ui/async_instrument.rs":"00fcde05841e8f9f6cc6f9434f8cc4baed5cf6e3ca73e8faddccbdace14e9485","tests/ui/async_instrument.stderr":"6f0457b5cd035a9bc82f5e98fb6d3a74177336ec6a19ba2e7cb9dbf3e67c3aff"},"package":"4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"} \ No newline at end of file diff --git a/vendor/tracing-attributes/CHANGELOG.md b/vendor/tracing-attributes/CHANGELOG.md index 4fcc81f29..42cb09b6a 100644 --- a/vendor/tracing-attributes/CHANGELOG.md +++ b/vendor/tracing-attributes/CHANGELOG.md @@ -1,3 +1,24 @@ +# 0.1.23 (October 6, 2022) + +This release of `tracing-attributes` fixes a bug where compiler diagnostic spans +for type errors in `#[instrument]`ed `async fn`s have the location of the +`#[instrument]` attribute rather than the location of the actual error, and a +bug where inner attributes in `#[instrument]`ed functions would cause a compiler +error. +### Fixed + +- Fix incorrect handling of inner attributes in `#[instrument]`ed functions ([#2307]) +- Add fake return to improve spans generated for type errors in `async fn`s ([#2270]) +- Updated `syn` dependency to fix compilation with `-Z minimal-versions` + ([#2246]) + +Thanks to new contributors @compiler-errors and @e-nomem, as well as @CAD97, for +contributing to this release! + +[#2307]: https://github.com/tokio-rs/tracing/pull/2307 +[#2270]: https://github.com/tokio-rs/tracing/pull/2270 +[#2246]: https://github.com/tokio-rs/tracing/pull/2246 + # 0.1.22 (July 1, 2022) This release fixes an issue where using the `err` or `ret` arguments to diff --git a/vendor/tracing-attributes/Cargo.toml b/vendor/tracing-attributes/Cargo.toml index 3ecaba6fc..5639de0b3 100644 --- a/vendor/tracing-attributes/Cargo.toml +++ b/vendor/tracing-attributes/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.49.0" name = "tracing-attributes" -version = "0.1.22" +version = "0.1.23" authors = [ "Tokio Contributors ", "Eliza Weisman ", @@ -49,7 +49,7 @@ version = "1" version = "1" [dependencies.syn] -version = "1.0.43" +version = "1.0.98" features = [ "full", "parsing", @@ -63,21 +63,27 @@ features = [ default-features = false [dev-dependencies.async-trait] -version = "0.1.44" +version = "0.1.56" + +[dev-dependencies.rustversion] +version = "1.0.9" [dev-dependencies.tokio-test] version = "0.3.0" [dev-dependencies.tracing] -version = "0.1" +version = "0.1.35" [dev-dependencies.tracing-core] -version = "0.1" +version = "0.1.28" [dev-dependencies.tracing-subscriber] -version = "0.3" +version = "0.3.0" features = ["env-filter"] +[dev-dependencies.trybuild] +version = "1.0.64" + [features] async-await = [] diff --git a/vendor/tracing-attributes/README.md b/vendor/tracing-attributes/README.md index 636179468..356b511f2 100644 --- a/vendor/tracing-attributes/README.md +++ b/vendor/tracing-attributes/README.md @@ -18,7 +18,7 @@ Macro attributes for application-level tracing. [crates-badge]: https://img.shields.io/crates/v/tracing-attributes.svg [crates-url]: https://crates.io/crates/tracing-attributes [docs-badge]: https://docs.rs/tracing-attributes/badge.svg -[docs-url]: https://docs.rs/tracing-attributes/0.1.22 +[docs-url]: https://docs.rs/tracing-attributes/0.1.23 [docs-master-badge]: https://img.shields.io/badge/docs-master-blue [docs-master-url]: https://tracing-rs.netlify.com/tracing_attributes [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg @@ -47,7 +47,7 @@ First, add this to your `Cargo.toml`: ```toml [dependencies] -tracing-attributes = "0.1.22" +tracing-attributes = "0.1.23" ``` diff --git a/vendor/tracing-attributes/src/expand.rs b/vendor/tracing-attributes/src/expand.rs index 81ee6ed90..7005b4423 100644 --- a/vendor/tracing-attributes/src/expand.rs +++ b/vendor/tracing-attributes/src/expand.rs @@ -2,15 +2,16 @@ use std::iter; use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; +use syn::visit_mut::VisitMut; use syn::{ punctuated::Punctuated, spanned::Spanned, Block, Expr, ExprAsync, ExprCall, FieldPat, FnArg, Ident, Item, ItemFn, Pat, PatIdent, PatReference, PatStruct, PatTuple, PatTupleStruct, PatType, - Path, Signature, Stmt, Token, TypePath, + Path, ReturnType, Signature, Stmt, Token, Type, TypePath, }; use crate::{ attr::{Field, Fields, FormatMode, InstrumentArgs}, - MaybeItemFnRef, + MaybeItemFn, MaybeItemFnRef, }; /// Given an existing function, generate an instrumented version of that function @@ -18,20 +19,21 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>( input: MaybeItemFnRef<'a, B>, args: InstrumentArgs, instrumented_function_name: &str, - self_type: Option<&syn::TypePath>, + self_type: Option<&TypePath>, ) -> proc_macro2::TokenStream { // these are needed ahead of time, as ItemFn contains the function body _and_ // isn't representable inside a quote!/quote_spanned! macro // (Syn's ToTokens isn't implemented for ItemFn) let MaybeItemFnRef { - attrs, + outer_attrs, + inner_attrs, vis, sig, block, } = input; let Signature { - output: return_type, + output, inputs: params, unsafety, asyncness, @@ -49,8 +51,35 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>( let warnings = args.warnings(); + let (return_type, return_span) = if let ReturnType::Type(_, return_type) = &output { + (erase_impl_trait(return_type), return_type.span()) + } else { + // Point at function name if we don't have an explicit return type + (syn::parse_quote! { () }, ident.span()) + }; + // Install a fake return statement as the first thing in the function + // body, so that we eagerly infer that the return type is what we + // declared in the async fn signature. + // The `#[allow(..)]` is given because the return statement is + // unreachable, but does affect inference, so it needs to be written + // exactly that way for it to do its magic. + let fake_return_edge = quote_spanned! {return_span=> + #[allow(unreachable_code, clippy::diverging_sub_expression, clippy::let_unit_value)] + if false { + let __tracing_attr_fake_return: #return_type = + unreachable!("this is just for type inference, and is unreachable code"); + return __tracing_attr_fake_return; + } + }; + let block = quote! { + { + #fake_return_edge + #block + } + }; + let body = gen_block( - block, + &block, params, asyncness.is_some(), args, @@ -59,10 +88,11 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>( ); quote!( - #(#attrs) * - #vis #constness #unsafety #asyncness #abi fn #ident<#gen_params>(#params) #return_type + #(#outer_attrs) * + #vis #constness #unsafety #asyncness #abi fn #ident<#gen_params>(#params) #output #where_clause { + #(#inner_attrs) * #warnings #body } @@ -76,7 +106,7 @@ fn gen_block( async_context: bool, mut args: InstrumentArgs, instrumented_function_name: &str, - self_type: Option<&syn::TypePath>, + self_type: Option<&TypePath>, ) -> proc_macro2::TokenStream { // generate the span's name let span_name = args @@ -393,11 +423,11 @@ impl RecordType { "Wrapping", ]; - /// Parse `RecordType` from [syn::Type] by looking up + /// Parse `RecordType` from [Type] by looking up /// the [RecordType::TYPES_FOR_VALUE] array. - fn parse_from_ty(ty: &syn::Type) -> Self { + fn parse_from_ty(ty: &Type) -> Self { match ty { - syn::Type::Path(syn::TypePath { path, .. }) + Type::Path(TypePath { path, .. }) if path .segments .iter() @@ -410,9 +440,7 @@ impl RecordType { { RecordType::Value } - syn::Type::Reference(syn::TypeReference { elem, .. }) => { - RecordType::parse_from_ty(&*elem) - } + Type::Reference(syn::TypeReference { elem, .. }) => RecordType::parse_from_ty(elem), _ => RecordType::Debug, } } @@ -471,7 +499,7 @@ pub(crate) struct AsyncInfo<'block> { // statement that must be patched source_stmt: &'block Stmt, kind: AsyncKind<'block>, - self_type: Option, + self_type: Option, input: &'block ItemFn, } @@ -606,11 +634,11 @@ impl<'block> AsyncInfo<'block> { if ident == "_self" { let mut ty = *ty.ty.clone(); // extract the inner type if the argument is "&self" or "&mut self" - if let syn::Type::Reference(syn::TypeReference { elem, .. }) = ty { + if let Type::Reference(syn::TypeReference { elem, .. }) = ty { ty = *elem; } - if let syn::Type::Path(tp) = ty { + if let Type::Path(tp) = ty { self_type = Some(tp); break; } @@ -631,7 +659,7 @@ impl<'block> AsyncInfo<'block> { self, args: InstrumentArgs, instrumented_function_name: &str, - ) -> proc_macro::TokenStream { + ) -> Result { // let's rewrite some statements! let mut out_stmts: Vec = self .input @@ -652,12 +680,15 @@ impl<'block> AsyncInfo<'block> { // instrument the future by rewriting the corresponding statement out_stmts[iter] = match self.kind { // `Box::pin(immediately_invoked_async_fn())` - AsyncKind::Function(fun) => gen_function( - fun.into(), - args, - instrumented_function_name, - self.self_type.as_ref(), - ), + AsyncKind::Function(fun) => { + let fun = MaybeItemFn::from(fun.clone()); + gen_function( + fun.as_ref(), + args, + instrumented_function_name, + self.self_type.as_ref(), + ) + } // `async move { ... }`, optionally pinned AsyncKind::Async { async_expr, @@ -688,13 +719,13 @@ impl<'block> AsyncInfo<'block> { let vis = &self.input.vis; let sig = &self.input.sig; let attrs = &self.input.attrs; - quote!( + Ok(quote!( #(#attrs) * #vis #sig { #(#out_stmts) * } ) - .into() + .into()) } } @@ -722,7 +753,7 @@ struct IdentAndTypesRenamer<'a> { idents: Vec<(Ident, Ident)>, } -impl<'a> syn::visit_mut::VisitMut for IdentAndTypesRenamer<'a> { +impl<'a> VisitMut for IdentAndTypesRenamer<'a> { // we deliberately compare strings because we want to ignore the spans // If we apply clippy's lint, the behavior changes #[allow(clippy::cmp_owned)] @@ -734,11 +765,11 @@ impl<'a> syn::visit_mut::VisitMut for IdentAndTypesRenamer<'a> { } } - fn visit_type_mut(&mut self, ty: &mut syn::Type) { + fn visit_type_mut(&mut self, ty: &mut Type) { for (type_name, new_type) in &self.types { - if let syn::Type::Path(TypePath { path, .. }) = ty { + if let Type::Path(TypePath { path, .. }) = ty { if path_to_string(path) == *type_name { - *ty = syn::Type::Path(new_type.clone()); + *ty = Type::Path(new_type.clone()); } } } @@ -751,10 +782,33 @@ struct AsyncTraitBlockReplacer<'a> { patched_block: Block, } -impl<'a> syn::visit_mut::VisitMut for AsyncTraitBlockReplacer<'a> { +impl<'a> VisitMut for AsyncTraitBlockReplacer<'a> { fn visit_block_mut(&mut self, i: &mut Block) { if i == self.block { *i = self.patched_block.clone(); } } } + +// Replaces any `impl Trait` with `_` so it can be used as the type in +// a `let` statement's LHS. +struct ImplTraitEraser; + +impl VisitMut for ImplTraitEraser { + fn visit_type_mut(&mut self, t: &mut Type) { + if let Type::ImplTrait(..) = t { + *t = syn::TypeInfer { + underscore_token: Token![_](t.span()), + } + .into(); + } else { + syn::visit_mut::visit_type_mut(self, t); + } + } +} + +fn erase_impl_trait(ty: &Type) -> Type { + let mut ty = ty.clone(); + ImplTraitEraser.visit_type_mut(&mut ty); + ty +} diff --git a/vendor/tracing-attributes/src/lib.rs b/vendor/tracing-attributes/src/lib.rs index 49b3c794a..f5974e4e5 100644 --- a/vendor/tracing-attributes/src/lib.rs +++ b/vendor/tracing-attributes/src/lib.rs @@ -16,7 +16,7 @@ //! //! ```toml //! [dependencies] -//! tracing-attributes = "0.1.22" +//! tracing-attributes = "0.1.23" //! ``` //! //! The [`#[instrument]`][instrument] attribute can now be added to a function @@ -52,7 +52,7 @@ //! supported compiler version is not considered a semver breaking change as //! long as doing so complies with this policy. //! -#![doc(html_root_url = "https://docs.rs/tracing-attributes/0.1.22")] +#![doc(html_root_url = "https://docs.rs/tracing-attributes/0.1.23")] #![doc( html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png", issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/" @@ -86,7 +86,7 @@ extern crate proc_macro; use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse::{Parse, ParseStream}; -use syn::{Attribute, Block, ItemFn, Signature, Visibility}; +use syn::{Attribute, ItemFn, Signature, Visibility}; mod attr; mod expand; @@ -587,11 +587,13 @@ fn instrument_precise( // check for async_trait-like patterns in the block, and instrument // the future instead of the wrapper if let Some(async_like) = expand::AsyncInfo::from_fn(&input) { - return Ok(async_like.gen_async(args, instrumented_function_name.as_str())); + return async_like.gen_async(args, instrumented_function_name.as_str()); } + let input = MaybeItemFn::from(input); + Ok(expand::gen_function( - (&input).into(), + input.as_ref(), args, instrumented_function_name.as_str(), None, @@ -603,7 +605,8 @@ fn instrument_precise( /// which's block is just a `TokenStream` (it may contain invalid code). #[derive(Debug, Clone)] struct MaybeItemFn { - attrs: Vec, + outer_attrs: Vec, + inner_attrs: Vec, vis: Visibility, sig: Signature, block: TokenStream, @@ -612,7 +615,8 @@ struct MaybeItemFn { impl MaybeItemFn { fn as_ref(&self) -> MaybeItemFnRef<'_, TokenStream> { MaybeItemFnRef { - attrs: &self.attrs, + outer_attrs: &self.outer_attrs, + inner_attrs: &self.inner_attrs, vis: &self.vis, sig: &self.sig, block: &self.block, @@ -624,12 +628,14 @@ impl MaybeItemFn { /// (just like `ItemFn`, but skips parsing the body). impl Parse for MaybeItemFn { fn parse(input: ParseStream<'_>) -> syn::Result { - let attrs = input.call(syn::Attribute::parse_outer)?; + let outer_attrs = input.call(Attribute::parse_outer)?; let vis: Visibility = input.parse()?; let sig: Signature = input.parse()?; + let inner_attrs = input.call(Attribute::parse_inner)?; let block: TokenStream = input.parse()?; Ok(Self { - attrs, + outer_attrs, + inner_attrs, vis, sig, block, @@ -637,23 +643,35 @@ impl Parse for MaybeItemFn { } } +impl From for MaybeItemFn { + fn from( + ItemFn { + attrs, + vis, + sig, + block, + }: ItemFn, + ) -> Self { + let (outer_attrs, inner_attrs) = attrs + .into_iter() + .partition(|attr| attr.style == syn::AttrStyle::Outer); + Self { + outer_attrs, + inner_attrs, + vis, + sig, + block: block.to_token_stream(), + } + } +} + /// A generic reference type for `MaybeItemFn`, /// that takes a generic block type `B` that implements `ToTokens` (eg. `TokenStream`, `Block`). #[derive(Debug, Clone)] struct MaybeItemFnRef<'a, B: ToTokens> { - attrs: &'a Vec, + outer_attrs: &'a Vec, + inner_attrs: &'a Vec, vis: &'a Visibility, sig: &'a Signature, block: &'a B, } - -impl<'a> From<&'a ItemFn> for MaybeItemFnRef<'a, Box> { - fn from(val: &'a ItemFn) -> Self { - MaybeItemFnRef { - attrs: &val.attrs, - vis: &val.vis, - sig: &val.sig, - block: &val.block, - } - } -} diff --git a/vendor/tracing-attributes/tests/async_fn.rs b/vendor/tracing-attributes/tests/async_fn.rs index 7e27fb5ce..c89963672 100644 --- a/vendor/tracing-attributes/tests/async_fn.rs +++ b/vendor/tracing-attributes/tests/async_fn.rs @@ -14,6 +14,7 @@ async fn test_async_fn(polls: usize) -> Result<(), ()> { // Reproduces a compile error when returning an `impl Trait` from an // instrumented async fn (see https://github.com/tokio-rs/tracing/issues/1615) +#[allow(dead_code)] // this is just here to test whether it compiles. #[instrument] async fn test_ret_impl_trait(n: i32) -> Result, ()> { let n = n; @@ -22,6 +23,7 @@ async fn test_ret_impl_trait(n: i32) -> Result, ()> { // Reproduces a compile error when returning an `impl Trait` from an // instrumented async fn (see https://github.com/tokio-rs/tracing/issues/1615) +#[allow(dead_code)] // this is just here to test whether it compiles. #[instrument(err)] async fn test_ret_impl_trait_err(n: i32) -> Result, &'static str> { Ok((0..10).filter(move |x| *x < n)) @@ -30,6 +32,15 @@ async fn test_ret_impl_trait_err(n: i32) -> Result, &' #[instrument] async fn test_async_fn_empty() {} +// Reproduces a compile error when an instrumented function body contains inner +// attributes (https://github.com/tokio-rs/tracing/issues/2294). +#[deny(unused_variables)] +#[instrument] +async fn repro_async_2294() { + #![allow(unused_variables)] + let i = 42; +} + // Reproduces https://github.com/tokio-rs/tracing/issues/1613 #[instrument] // LOAD-BEARING `#[rustfmt::skip]`! This is necessary to reproduce the bug; @@ -53,6 +64,7 @@ async fn repro_1613_2() { } // Reproduces https://github.com/tokio-rs/tracing/issues/1831 +#[allow(dead_code)] // this is just here to test whether it compiles. #[instrument] #[deny(unused_braces)] fn repro_1831() -> Pin>> { @@ -61,6 +73,7 @@ fn repro_1831() -> Pin>> { // This replicates the pattern used to implement async trait methods on nightly using the // `type_alias_impl_trait` feature +#[allow(dead_code)] // this is just here to test whether it compiles. #[instrument(ret, err)] #[deny(unused_braces)] #[allow(clippy::manual_async_fn)] diff --git a/vendor/tracing-attributes/tests/instrument.rs b/vendor/tracing-attributes/tests/instrument.rs index 2b2fee71e..768692748 100644 --- a/vendor/tracing-attributes/tests/instrument.rs +++ b/vendor/tracing-attributes/tests/instrument.rs @@ -3,6 +3,15 @@ use tracing::Level; use tracing_attributes::instrument; use tracing_mock::*; +// Reproduces a compile error when an instrumented function body contains inner +// attributes (https://github.com/tokio-rs/tracing/issues/2294). +#[deny(unused_variables)] +#[instrument] +fn repro_2294() { + #![allow(unused_variables)] + let i = 42; +} + #[test] fn override_everything() { #[instrument(target = "my_target", level = "debug")] diff --git a/vendor/tracing-attributes/tests/ui.rs b/vendor/tracing-attributes/tests/ui.rs new file mode 100644 index 000000000..f11cc019e --- /dev/null +++ b/vendor/tracing-attributes/tests/ui.rs @@ -0,0 +1,7 @@ +// Only test on nightly, since UI tests are bound to change over time +#[rustversion::stable] +#[test] +fn async_instrument() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/async_instrument.rs"); +} diff --git a/vendor/tracing-attributes/tests/ui/async_instrument.rs b/vendor/tracing-attributes/tests/ui/async_instrument.rs new file mode 100644 index 000000000..5b245746a --- /dev/null +++ b/vendor/tracing-attributes/tests/ui/async_instrument.rs @@ -0,0 +1,46 @@ +#![allow(unreachable_code)] + +#[tracing::instrument] +async fn unit() { + "" +} + +#[tracing::instrument] +async fn simple_mismatch() -> String { + "" +} + +// FIXME: this span is still pretty poor +#[tracing::instrument] +async fn opaque_unsatisfied() -> impl std::fmt::Display { + ("",) +} + +struct Wrapper(T); + +#[tracing::instrument] +async fn mismatch_with_opaque() -> Wrapper { + "" +} + +#[tracing::instrument] +async fn early_return_unit() { + if true { + return ""; + } +} + +#[tracing::instrument] +async fn early_return() -> String { + if true { + return ""; + } + String::new() +} + +#[tracing::instrument] +async fn extra_semicolon() -> i32 { + 1; +} + +fn main() {} diff --git a/vendor/tracing-attributes/tests/ui/async_instrument.stderr b/vendor/tracing-attributes/tests/ui/async_instrument.stderr new file mode 100644 index 000000000..db6f6b434 --- /dev/null +++ b/vendor/tracing-attributes/tests/ui/async_instrument.stderr @@ -0,0 +1,98 @@ +error[E0308]: mismatched types + --> tests/ui/async_instrument.rs:5:5 + | +5 | "" + | ^^ expected `()`, found `&str` + | +note: return type inferred to be `()` here + --> tests/ui/async_instrument.rs:4:10 + | +4 | async fn unit() { + | ^^^^ + +error[E0308]: mismatched types + --> tests/ui/async_instrument.rs:10:5 + | +10 | "" + | ^^- help: try using a conversion method: `.to_string()` + | | + | expected struct `String`, found `&str` + | +note: return type inferred to be `String` here + --> tests/ui/async_instrument.rs:9:31 + | +9 | async fn simple_mismatch() -> String { + | ^^^^^^ + +error[E0277]: `(&str,)` doesn't implement `std::fmt::Display` + --> tests/ui/async_instrument.rs:14:1 + | +14 | #[tracing::instrument] + | ^^^^^^^^^^^^^^^^^^^^^^ `(&str,)` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `(&str,)` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the attribute macro `tracing::instrument` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `(&str,)` doesn't implement `std::fmt::Display` + --> tests/ui/async_instrument.rs:15:34 + | +15 | async fn opaque_unsatisfied() -> impl std::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^^ `(&str,)` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `(&str,)` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + +error[E0308]: mismatched types + --> tests/ui/async_instrument.rs:23:5 + | +23 | "" + | ^^ expected struct `Wrapper`, found `&str` + | + = note: expected struct `Wrapper<_>` + found reference `&'static str` +note: return type inferred to be `Wrapper<_>` here + --> tests/ui/async_instrument.rs:22:36 + | +22 | async fn mismatch_with_opaque() -> Wrapper { + | ^^^^^^^ +help: try wrapping the expression in `Wrapper` + | +23 | Wrapper("") + | ++++++++ + + +error[E0308]: mismatched types + --> tests/ui/async_instrument.rs:29:16 + | +29 | return ""; + | ^^ expected `()`, found `&str` + | +note: return type inferred to be `()` here + --> tests/ui/async_instrument.rs:27:10 + | +27 | async fn early_return_unit() { + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> tests/ui/async_instrument.rs:36:16 + | +36 | return ""; + | ^^- help: try using a conversion method: `.to_string()` + | | + | expected struct `String`, found `&str` + | +note: return type inferred to be `String` here + --> tests/ui/async_instrument.rs:34:28 + | +34 | async fn early_return() -> String { + | ^^^^^^ + +error[E0308]: mismatched types + --> tests/ui/async_instrument.rs:42:35 + | +42 | async fn extra_semicolon() -> i32 { + | ___________________________________^ +43 | | 1; + | | - help: remove this semicolon +44 | | } + | |_^ expected `i32`, found `()` diff --git a/vendor/tracing-core/.cargo-checksum.json b/vendor/tracing-core/.cargo-checksum.json index c51d0e671..6a9cec13f 100644 --- a/vendor/tracing-core/.cargo-checksum.json +++ b/vendor/tracing-core/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"10eae751c81a268b6118e2dea49d0d501ea4d2a69ece6350232f3800407ab2d3","Cargo.toml":"d29fae6d4ae043c79697e4305224fb8f65279515e1db6ad1211ccd27d073287f","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"f40e479c4d837f4fec140b0f4adad7aae062d55b53708f2255b93217f19d22a9","src/callsite.rs":"f5e9cdaed7fdc75dad5da6486af0ea6e9be896ab5fc1b44c49a90b8b88b33d53","src/dispatcher.rs":"1d129a0c3af976669787733101c2ce7d2f9eca794deeb2ae5a662085e966e0cf","src/event.rs":"f2673bf5d266972e567e521c9cd92fb33f28b0c7e010937e3bc2bf9eb483087f","src/field.rs":"4ec913012ffcf05d3feba2a5ea2ba99c35e2072dabfa2db75614c0e122961b7e","src/lazy.rs":"318e3558e4446abf26294287167c0788e343044a28072f9217bd985929809087","src/lib.rs":"088b29ecce4bdb5b68df9cbe3984f4b22d7124988866d5aace0e7029ea033d58","src/metadata.rs":"1a79326aee210b9e20eb08d5baa22133390f2b1e868cf4dc72a3e9bc9a37d17f","src/parent.rs":"5d5ad733343280a64a1feb6a008e186c39305ec554f14279012b8d7915821471","src/span.rs":"dcf2135e4ca158c1be45007f0be25426c375a4081f8f3c5a4d7f7382d8a950a4","src/spin/LICENSE":"58545fed1565e42d687aecec6897d35c6d37ccb71479a137c0deb2203e125c79","src/spin/mod.rs":"c458ce5e875acb7fbfb279f23254f4924d7c6d6fee419b740800d2e8087d1524","src/spin/mutex.rs":"4d30ff2b59b18fd7909f016e1abdf9aa0c04aa11d047a46e98cffe1319e32dad","src/spin/once.rs":"3781fd4eae0db04d80c03a039906c99b1e01d1583b29ac0144e6fbbd5a0fef0b","src/stdlib.rs":"698693062b8109cace3ffea02e9c2372b7d5b5d43c0b11cb4800b0e7b1a69971","src/subscriber.rs":"916d315ca324a752f70fc3cc557089418a63779ceda54955f55f0ab3c1f3fc7b","tests/common/mod.rs":"0bbb217baa17df0f96cc1ff57dfa74ccc5a959e7f66b15bb7d25d5f43358a278","tests/dispatch.rs":"d3f000fab43734a854c82a7783142910c5e79f806cbd3f8ec5eded598c59ddb1","tests/global_dispatch.rs":"cdc05d77e448ee8b50bfb930abafa3f19b4c6f922b7bebc7797fa1dbdaa1d398","tests/macros.rs":"b1603d888b349c8d103794deceec3b1ae4538b8d3eba805f3f561899e8ad0dd2"},"package":"5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"} \ No newline at end of file +{"files":{"CHANGELOG.md":"93400b6ed3661b8f238549f19e55b0482da163a4504080785fefdcdc8b719198","Cargo.toml":"798de58e851a5cc16f76850f08ab381628c3858a438c31a3fa3e35c06e60992c","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"5f5e27d08d3c5ae5f8cc304fcd71ecc61f0c61b27e4bd983c89558805353479d","src/callsite.rs":"479f3b3809afff20ac2a4652f11ec1adc8dd59bd90c608e4e248de4a43c5a43c","src/dispatcher.rs":"16c0ceb3e9de5b7c1365d1c8cc010d12048569d3e9b1146b99b3ea3f0f582ba8","src/event.rs":"f2673bf5d266972e567e521c9cd92fb33f28b0c7e010937e3bc2bf9eb483087f","src/field.rs":"4ec913012ffcf05d3feba2a5ea2ba99c35e2072dabfa2db75614c0e122961b7e","src/lazy.rs":"318e3558e4446abf26294287167c0788e343044a28072f9217bd985929809087","src/lib.rs":"088b29ecce4bdb5b68df9cbe3984f4b22d7124988866d5aace0e7029ea033d58","src/metadata.rs":"1a79326aee210b9e20eb08d5baa22133390f2b1e868cf4dc72a3e9bc9a37d17f","src/parent.rs":"5d5ad733343280a64a1feb6a008e186c39305ec554f14279012b8d7915821471","src/span.rs":"dcf2135e4ca158c1be45007f0be25426c375a4081f8f3c5a4d7f7382d8a950a4","src/spin/LICENSE":"58545fed1565e42d687aecec6897d35c6d37ccb71479a137c0deb2203e125c79","src/spin/mod.rs":"c458ce5e875acb7fbfb279f23254f4924d7c6d6fee419b740800d2e8087d1524","src/spin/mutex.rs":"4d30ff2b59b18fd7909f016e1abdf9aa0c04aa11d047a46e98cffe1319e32dad","src/spin/once.rs":"3781fd4eae0db04d80c03a039906c99b1e01d1583b29ac0144e6fbbd5a0fef0b","src/stdlib.rs":"698693062b8109cace3ffea02e9c2372b7d5b5d43c0b11cb4800b0e7b1a69971","src/subscriber.rs":"baef1454ccf5f552b0a7ba6840eeeca19f7edf21e0303607b86e9e5ffc989a38","tests/common/mod.rs":"0bbb217baa17df0f96cc1ff57dfa74ccc5a959e7f66b15bb7d25d5f43358a278","tests/dispatch.rs":"d3f000fab43734a854c82a7783142910c5e79f806cbd3f8ec5eded598c59ddb1","tests/global_dispatch.rs":"cdc05d77e448ee8b50bfb930abafa3f19b4c6f922b7bebc7797fa1dbdaa1d398","tests/macros.rs":"b1603d888b349c8d103794deceec3b1ae4538b8d3eba805f3f561899e8ad0dd2"},"package":"24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"} \ No newline at end of file diff --git a/vendor/tracing-core/CHANGELOG.md b/vendor/tracing-core/CHANGELOG.md index 2db8553c9..cf0d8e3b9 100644 --- a/vendor/tracing-core/CHANGELOG.md +++ b/vendor/tracing-core/CHANGELOG.md @@ -1,3 +1,21 @@ +# 0.1.30 (October 6, 2022) + +This release of `tracing-core` adds a new `on_register_dispatch` method to the +`Subscriber` trait to allow the `Subscriber` to perform initialization after +being registered as a `Dispatch`, and a `WeakDispatch` type to allow a +`Subscriber` to store its own `Dispatch` without creating reference count +cycles. + +### Added + +- `Subscriber::on_register_dispatch` method ([#2269]) +- `WeakDispatch` type and `Dispatch::downgrade()` function ([#2293]) + +Thanks to @jswrenn for contributing to this release! + +[#2269]: https://github.com/tokio-rs/tracing/pull/2269 +[#2293]: https://github.com/tokio-rs/tracing/pull/2293 + # 0.1.29 (July 29, 2022) This release of `tracing-core` adds `PartialEq` and `Eq` implementations for diff --git a/vendor/tracing-core/Cargo.toml b/vendor/tracing-core/Cargo.toml index 957194d39..806006141 100644 --- a/vendor/tracing-core/Cargo.toml +++ b/vendor/tracing-core/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.49.0" name = "tracing-core" -version = "0.1.29" +version = "0.1.30" authors = ["Tokio Contributors "] description = """ Core primitives for application-level tracing. diff --git a/vendor/tracing-core/README.md b/vendor/tracing-core/README.md index c6f7b0333..f06c76059 100644 --- a/vendor/tracing-core/README.md +++ b/vendor/tracing-core/README.md @@ -16,9 +16,9 @@ Core primitives for application-level tracing. [Documentation][docs-url] | [Chat][discord-url] [crates-badge]: https://img.shields.io/crates/v/tracing-core.svg -[crates-url]: https://crates.io/crates/tracing-core/0.1.29 +[crates-url]: https://crates.io/crates/tracing-core/0.1.30 [docs-badge]: https://docs.rs/tracing-core/badge.svg -[docs-url]: https://docs.rs/tracing-core/0.1.29 +[docs-url]: https://docs.rs/tracing-core/0.1.30 [docs-master-badge]: https://img.shields.io/badge/docs-master-blue [docs-master-url]: https://tracing-rs.netlify.com/tracing_core [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg @@ -79,22 +79,22 @@ The following crate feature flags are available: ```toml [dependencies] - tracing-core = { version = "0.1.29", default-features = false } + tracing-core = { version = "0.1.30", default-features = false } ``` **Note**:`tracing-core`'s `no_std` support requires `liballoc`. [`tracing`]: ../tracing -[`span::Id`]: https://docs.rs/tracing-core/0.1.29/tracing_core/span/struct.Id.html -[`Event`]: https://docs.rs/tracing-core/0.1.29/tracing_core/event/struct.Event.html -[`Subscriber`]: https://docs.rs/tracing-core/0.1.29/tracing_core/subscriber/trait.Subscriber.html -[`Metadata`]: https://docs.rs/tracing-core/0.1.29/tracing_core/metadata/struct.Metadata.html -[`Callsite`]: https://docs.rs/tracing-core/0.1.29/tracing_core/callsite/trait.Callsite.html -[`Field`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/struct.Field.html -[`FieldSet`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/struct.FieldSet.html -[`Value`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/trait.Value.html -[`ValueSet`]: https://docs.rs/tracing-core/0.1.29/tracing_core/field/struct.ValueSet.html -[`Dispatch`]: https://docs.rs/tracing-core/0.1.29/tracing_core/dispatcher/struct.Dispatch.html +[`span::Id`]: https://docs.rs/tracing-core/0.1.30/tracing_core/span/struct.Id.html +[`Event`]: https://docs.rs/tracing-core/0.1.30/tracing_core/event/struct.Event.html +[`Subscriber`]: https://docs.rs/tracing-core/0.1.30/tracing_core/subscriber/trait.Subscriber.html +[`Metadata`]: https://docs.rs/tracing-core/0.1.30/tracing_core/metadata/struct.Metadata.html +[`Callsite`]: https://docs.rs/tracing-core/0.1.30/tracing_core/callsite/trait.Callsite.html +[`Field`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/struct.Field.html +[`FieldSet`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/struct.FieldSet.html +[`Value`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/trait.Value.html +[`ValueSet`]: https://docs.rs/tracing-core/0.1.30/tracing_core/field/struct.ValueSet.html +[`Dispatch`]: https://docs.rs/tracing-core/0.1.30/tracing_core/dispatcher/struct.Dispatch.html ## Supported Rust Versions diff --git a/vendor/tracing-core/src/callsite.rs b/vendor/tracing-core/src/callsite.rs index bc7405ffa..f88713236 100644 --- a/vendor/tracing-core/src/callsite.rs +++ b/vendor/tracing-core/src/callsite.rs @@ -487,6 +487,7 @@ impl Callsites { pub(crate) fn register_dispatch(dispatch: &Dispatch) { let dispatchers = DISPATCHERS.register_dispatch(dispatch); + dispatch.subscriber().on_register_dispatch(dispatch); CALLSITES.rebuild_interest(dispatchers); } diff --git a/vendor/tracing-core/src/dispatcher.rs b/vendor/tracing-core/src/dispatcher.rs index a3661817c..36b3cfd85 100644 --- a/vendor/tracing-core/src/dispatcher.rs +++ b/vendor/tracing-core/src/dispatcher.rs @@ -134,7 +134,7 @@ use crate::stdlib::{ fmt, sync::{ atomic::{AtomicBool, AtomicUsize, Ordering}, - Arc, + Arc, Weak, }, }; @@ -142,16 +142,50 @@ use crate::stdlib::{ use crate::stdlib::{ cell::{Cell, RefCell, RefMut}, error, - sync::Weak, }; +#[cfg(feature = "alloc")] +use alloc::sync::{Arc, Weak}; + +#[cfg(feature = "alloc")] +use core::ops::Deref; + /// `Dispatch` trace data to a [`Subscriber`]. -/// #[derive(Clone)] pub struct Dispatch { subscriber: Arc, } +/// `WeakDispatch` is a version of [`Dispatch`] that holds a non-owning reference +/// to a [`Subscriber`]. +/// +/// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +/// which returns an `Option`. If all [`Dispatch`] clones that point +/// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return +/// `None`. Otherwise, it will return `Some(Dispatch)`. +/// +/// A `WeakDispatch` may be created from a [`Dispatch`] by calling the +/// [`Dispatch::downgrade`] method. The primary use for creating a +/// [`WeakDispatch`] is to allow a Subscriber` to hold a cyclical reference to +/// itself without creating a memory leak. See [here] for details. +/// +/// This type is analogous to the [`std::sync::Weak`] type, but for a +/// [`Dispatch`] rather than an [`Arc`]. +/// +/// [`Arc`]: std::sync::Arc +/// [here]: Subscriber#avoiding-memory-leaks +#[derive(Clone)] +pub struct WeakDispatch { + subscriber: Weak, +} + +#[cfg(feature = "alloc")] +#[derive(Clone)] +enum Kind { + Global(&'static (dyn Collect + Send + Sync)), + Scoped(T), +} + #[cfg(feature = "std")] thread_local! { static CURRENT_STATE: State = State { @@ -430,8 +464,34 @@ impl Dispatch { Registrar(Arc::downgrade(&self.subscriber)) } - /// Registers a new callsite with this subscriber, returning whether or not - /// the subscriber is interested in being notified about the callsite. + /// Creates a [`WeakDispatch`] from this `Dispatch`. + /// + /// A [`WeakDispatch`] is similar to a [`Dispatch`], but it does not prevent + /// the underlying [`Subscriber`] from being dropped. Instead, it only permits + /// access while other references to the `Subscriber` exist. This is equivalent + /// to the standard library's [`Arc::downgrade`] method, but for `Dispatch` + /// rather than `Arc`. + /// + /// The primary use for creating a [`WeakDispatch`] is to allow a `Subscriber` + /// to hold a cyclical reference to itself without creating a memory leak. + /// See [here] for details. + /// + /// [`Arc::downgrade`]: std::sync::Arc::downgrade + /// [here]: Subscriber#avoiding-memory-leaks + pub fn downgrade(&self) -> WeakDispatch { + WeakDispatch { + subscriber: Arc::downgrade(&self.subscriber), + } + } + + #[inline(always)] + #[cfg(not(feature = "alloc"))] + pub(crate) fn subscriber(&self) -> &(dyn Subscriber + Send + Sync) { + &self.subscriber + } + + /// Registers a new callsite with this collector, returning whether or not + /// the collector is interested in being notified about the callsite. /// /// This calls the [`register_callsite`] function on the [`Subscriber`] /// that this `Dispatch` forwards to. @@ -631,14 +691,14 @@ impl Dispatch { /// `T`. #[inline] pub fn is(&self) -> bool { - ::is::(&*self.subscriber) + ::is::(&self.subscriber) } /// Returns some reference to the `Subscriber` this `Dispatch` forwards to /// if it is of type `T`, or `None` if it isn't. #[inline] pub fn downcast_ref(&self) -> Option<&T> { - ::downcast_ref(&*self.subscriber) + ::downcast_ref(&self.subscriber) } } @@ -667,6 +727,45 @@ where } } +// === impl WeakDispatch === + +impl WeakDispatch { + /// Attempts to upgrade this `WeakDispatch` to a [`Dispatch`]. + /// + /// Returns `None` if the referenced `Dispatch` has already been dropped. + /// + /// ## Examples + /// + /// ``` + /// # use tracing_core::subscriber::NoSubscriber; + /// # use tracing_core::dispatcher::Dispatch; + /// let strong = Dispatch::new(NoSubscriber::default()); + /// let weak = strong.downgrade(); + /// + /// // The strong here keeps it alive, so we can still access the object. + /// assert!(weak.upgrade().is_some()); + /// + /// drop(strong); // But not any more. + /// assert!(weak.upgrade().is_none()); + /// ``` + pub fn upgrade(&self) -> Option { + self.subscriber + .upgrade() + .map(|subscriber| Dispatch { subscriber }) + } +} + +impl fmt::Debug for WeakDispatch { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut tuple = f.debug_tuple("WeakDispatch"); + match self.subscriber.upgrade() { + Some(subscriber) => tuple.field(&format_args!("Some({:p})", subscriber)), + None => tuple.field(&format_args!("None")), + }; + tuple.finish() + } +} + #[cfg(feature = "std")] impl Registrar { pub(crate) fn upgrade(&self) -> Option { diff --git a/vendor/tracing-core/src/subscriber.rs b/vendor/tracing-core/src/subscriber.rs index a6f0834e2..e8f444119 100644 --- a/vendor/tracing-core/src/subscriber.rs +++ b/vendor/tracing-core/src/subscriber.rs @@ -1,5 +1,5 @@ -//! Subscribers collect and record trace data. -use crate::{span, Event, LevelFilter, Metadata}; +//! Collectors collect and record trace data. +use crate::{span, Dispatch, Event, LevelFilter, Metadata}; use crate::stdlib::{ any::{Any, TypeId}, @@ -81,7 +81,28 @@ use crate::stdlib::{ /// [`event`]: Subscriber::event /// [`event_enabled`]: Subscriber::event_enabled pub trait Subscriber: 'static { - // === Span registry methods ============================================== + /// Invoked when this subscriber becomes a [`Dispatch`]. + /// + /// ## Avoiding Memory Leaks + /// + /// `Subscriber`s should not store their own [`Dispatch`]. Because the + /// `Dispatch` owns the `Subscriber`, storing the `Dispatch` within the + /// `Subscriber` will create a reference count cycle, preventing the `Dispatch` + /// from ever being dropped. + /// + /// Instead, when it is necessary to store a cyclical reference to the + /// `Dispatch` within a `Subscriber`, use [`Dispatch::downgrade`] to convert a + /// `Dispatch` into a [`WeakDispatch`]. This type is analogous to + /// [`std::sync::Weak`], and does not create a reference count cycle. A + /// [`WeakDispatch`] can be stored within a `Subscriber` without causing a + /// memory leak, and can be [upgraded] into a `Dispatch` temporarily when + /// the `Dispatch` must be accessed by the `Subscriber`. + /// + /// [`WeakDispatch`]: crate::dispatcher::WeakDispatch + /// [upgraded]: crate::dispatcher::WeakDispatch::upgrade + fn on_register_dispatch(&self, subscriber: &Dispatch) { + let _ = subscriber; + } /// Registers a new [callsite] with this subscriber, returning whether or not /// the subscriber is interested in being notified about the callsite. diff --git a/vendor/tracing-subscriber-0.3.3/.cargo-checksum.json b/vendor/tracing-subscriber-0.3.3/.cargo-checksum.json new file mode 100644 index 000000000..3fd14355e --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"fd7a732ca8d5997cf09a6ffbde0dda0667873031884aa3549d6044971dc00a66","Cargo.toml":"4908f04be83f94bc75fbcf4244fa57b8a52c984928a3320550b692c1038d5448","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"803714740b5ad75ac31a0f9dafd10e0d4d62f7c27c2c0e182d2076a313b0649b","benches/enter.rs":"4a94a04e2abd07950ef2f0b646f4dcdf4ff00abf6396edb5a53c8b41b7691b1a","benches/filter.rs":"6374005ffa47fa19880bb95e3e37406f40ea72a02c5136f4d5eb4c663d452b18","benches/filter_log.rs":"612716bdf9a188093e84d014a4847f18157f148f7d64e54150cd5c91ac709a8a","benches/fmt.rs":"5a0ff37967ffef3a221eebb78855d031e2e883a8a67528c8e794cc6f16cbee8a","benches/support/mod.rs":"72bef51154da9c9b3d81300195c1929a818858fa4b4fc2aa07b49ca586f4cd39","src/field/debug.rs":"4ab50198a0b042d92fefa77b5cac0aef7ba6936149fa555f4b6e2036dcd7f2d7","src/field/delimited.rs":"e6b2dcbf9cb1e9b5e862b462f91190adaf8e14f9c2c5d2048ad651f49cfa2007","src/field/display.rs":"9c06a52919dbe9bfd4cf7eec39293240c9facebe052a2fecc2f21184beb5195f","src/field/mod.rs":"35e3dd4ad7b49c99a24e80c6a40a00b3189a114488793657d6d733a90d2e10f6","src/filter/directive.rs":"7ecf87b17afbddadbc385764c2d9c1fda4b020a08d75f741f8e34c7dc475bd74","src/filter/env/directive.rs":"628f9f566ccee924d43d79b287c569abfc32c2fb74e078958aed6cb8285cfb4f","src/filter/env/field.rs":"9f2ceaedf2e2ecefaff863347ef8dfa85cd5f64a0fd09a0f77f64f412c9bb548","src/filter/env/mod.rs":"7f864a5ef0c008c7fe9a21d0a94bb87dd72746e628ff3e68c18b0fd173763918","src/filter/filter_fn.rs":"0debbc4a4b4d2a57b2a06905017ac908bf34b0a64aaf961535fbf6f4d5a700a9","src/filter/layer_filters.rs":"16ff19fed003b913de4f85a03b31864d71ee73c7ce86b07c80da07fe633f682e","src/filter/level.rs":"cc449757aac47caaf19dd5ba4d74c8efbcd7531fcd6c13da0c5f6fdda12cc9ca","src/filter/mod.rs":"8ebfd0dc92415ff27ec552f20919e598842a87186f13f120449053a96e1e3307","src/filter/targets.rs":"5cec882366d7f12de0a88f7daaac8499785ce9e3832619f251876a02ae19a6bf","src/fmt/fmt_layer.rs":"486264d810ab6b28428bd48e00774fc822762fc9f991332a2d94a42b3168f2e6","src/fmt/format/json.rs":"1a38c049e1bf99efaf7db1f1fd26d3a5bb1e768fc1524c95816708e5d39fca35","src/fmt/format/mod.rs":"ff92f7910bed4f3c0c2ce798333d273d6b5b5fc09cc78031f52d13e043986227","src/fmt/format/pretty.rs":"eecf278b15cc60b35c3f6aa5d05452401c7a4a29195357e92318d684fcfe3072","src/fmt/mod.rs":"270ffa0a9e6543a602247fccef276a3012daa558181f24cd9032292edbc8dc2c","src/fmt/time/datetime.rs":"778d4604d800e46b940087394e7b72750738b554e02aea523fa9820ab0768c08","src/fmt/time/mod.rs":"304c9383e5cfc0c42d79f47a10323ed5a98585e018b127924b0925ec067f0739","src/fmt/time/time_crate.rs":"bacec2c8bb31175b85f2fb3ae40155a08b2aab7a04adaf4c88679147dc651c58","src/fmt/writer.rs":"1d7a4e2dddddff1bfd1344f2cecdb6b2b69b015c9869d95987d26e177dffa793","src/layer/context.rs":"2478693e2faffdf2e519b6d37e1c3aa3dd75088185accc2b68ffa8612bf73195","src/layer/layered.rs":"ba918a9b944f2c083cbb75d6d7f99f90083aa0a29cf3f4f1dd78aa034e09ade6","src/layer/mod.rs":"e1804cfe91051020cac63fb1067d196552ebb844b6c6d1d2279b97dbec1c64df","src/layer/tests.rs":"3e974d627c4bc4269cfa10c82c890e596c9d46af8e6bc03c6c117bde1237e948","src/lib.rs":"cb362279b3c6d23645cda6d768707576f460e275d332d5350a036437cd5404e0","src/macros.rs":"e184bffc6b5999c48e365ad08343dca764a5fb711b789beb26bd1d5f1d767726","src/prelude.rs":"088635def33be9a4c4b6ed934dc22540c555e27d62f7625a43aa9c0e525ca467","src/registry/extensions.rs":"7333aefd69c767212a7924c57283442430edccb17092c91e02a7d13b2d312b11","src/registry/mod.rs":"4f0108e75e0f6e239b8eb69fcad052f25e3b887e412e951e0cbec02cf13f05d5","src/registry/sharded.rs":"972bdd94f43a33ef1f2ebf96ea69ebe4c1d4b0215e69315a3b525783c2025696","src/registry/stack.rs":"9ef333d6a8a28a064e80ff1e376dbb07bc597009010ec332b2dc3ab435d737c2","src/reload.rs":"41fa9a1a28fef626e302a80a68d665492e73ef6d1a2a3c2a7aac5d6c9a0bb496","src/sync.rs":"7f78f3de5b618a999be0e61f936a233975e7769f1ebb55a0e48c3d199e9c45e3","src/util.rs":"55b4e9d63112f9d5a12a287273a9b1212741058384332d3edc024168cacfd627","tests/cached_layer_filters_dont_break_other_layers.rs":"b2084542a014abeff821b30b2b8c21e32bfdcffae53ce5335fb588f557fa4244","tests/duplicate_spans.rs":"48f596bbfabcc6618244afddcf3c3f2e915b9d79284f17bdd0e0616ad29929be","tests/field_filter.rs":"c44d88ab711164a2b1b3a09377284b469f79ddf4651416515a035782c7c64b79","tests/filter.rs":"a43d23e867af779031b6245047092aca57ee26980a8f3faa19036542bcd37f06","tests/filter_log.rs":"e0cd9d394dbfeeb80570a7686bc7f588c5489657980436810711ed8852f86169","tests/fmt_max_level_hint.rs":"d4c6d6f976ae41ab8052fa610a7337ad7150802cbd5634cb30fc45c1f215cfcd","tests/hinted_layer_filters_dont_break_other_layers.rs":"d5ba9cfb6784cf59f007e673ad549dc722d109f6b3d4a69f6aa11b25ca10b469","tests/layer_filter_interests_are_cached.rs":"d036d1c4bc3754e94ebfdda9c841f4858ccec40aba0720f3fbf26c817bfe5a83","tests/layer_filters/boxed.rs":"04db459721a26d6502a2b3fbe42154c5a451021a9374a18c017d10971f44e0c0","tests/layer_filters/downcast_raw.rs":"9b90ead571543cbe14e89b4fe637360d9baf3069f6f656ed3bdf65e7318648f1","tests/layer_filters/filter_scopes.rs":"02611bc58d0d8a67a127eca8cab1b2d9a9901bd2c8a8daad41adf6089b28aee0","tests/layer_filters/main.rs":"0316d611c740e234b78ed9a9dae392fe80472c1e8b004a007ad2dd87d068c67b","tests/layer_filters/targets.rs":"138e3f9ddd68571d94c5aff9d54ee2fbc5f44724c6ee42477a411740ccb79ee6","tests/layer_filters/trees.rs":"4df7b5cf12da44a9255c56e5b80e2b0cf84820230ba916f324c67bc3ee4e4605","tests/multiple_layer_filter_interests_cached.rs":"1ea195f03e58d715228ec1b604f85bda2fc82812d05b2f6370d5edd34a035f32","tests/registry_max_level_hint.rs":"ba386d32b8d13832d7009163241c3d0723488c0393d85647eb9368776251e4fc","tests/registry_with_subscriber.rs":"13b92ed68d9013aefefbc4c73e695c690630e4460634206d214db4c19abb7c0f","tests/reload.rs":"4566386b1b26e6609f5a4bf0e6bef1c2245a591d12417cee189b26dfa14f7f95","tests/same_len_filters.rs":"50c8f5fa1494773410a9f52a56b303534a01a023b186cf2f3131e5e7706eb156","tests/support.rs":"75559505af8018012739d24b3c8743dd079b4d3a8ae28f08b4586a961720aa7b","tests/unhinted_layer_filters_dont_break_other_layers.rs":"519cfef4977e511af938546d4208c645a28248c8ed8666daf180f0ad32f0a261","tests/utils.rs":"2b04ce2d8b56a9062a025900104853e081eae8e3f113f990a915d5f9dea6577b"},"package":"245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3"} \ No newline at end of file diff --git a/vendor/tracing-subscriber-0.3.3/CHANGELOG.md b/vendor/tracing-subscriber-0.3.3/CHANGELOG.md new file mode 100644 index 000000000..c380ff3b1 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/CHANGELOG.md @@ -0,0 +1,902 @@ +# 0.3.3 (Nov 29, 2021) + +This release fixes a pair of regressions in `tracing-subscriber`'s `fmt` module. + +### Fixed + +- **fmt**: Fixed missing event fields with `Compact` formatter ([#1755]) +- **fmt**: Fixed `PrettyFields` formatter (and thus `format::Pretty` event + formatter) ignoring the `fmt::Layer`'s ANSI color code configuration ([#1747]) + +[#1755]: https://github.com/tokio-rs/tracing/pull/1755 +[#1747]: https://github.com/tokio-rs/tracing/pull/1747 + +# 0.3.2 (Nov 19, 2021) + +### Fixed + +- **fmt**: Fixed `MakeWriter` filtering not working with `BoxMakeWriter` + ([#1694]) + +### Added + +- **fmt**: `Writer::has_ansi_escapes` method to check if an output supports ANSI + terminal formatting escape codes ([#1696]) +- **fmt**: Added additional ANSI terminal formatting to field formatters when + supported ([#1702]) +- **fmt**: Added `FmtContext::span_scope`, `FmtContext::event_scope`, and + `FmtContext::parent_span` methods for accessing the current span and its scope + when formatting an event ([#1728]) +- **fmt**: Improved documentation on implementing event formatters ([#1727]) + +[#1694]: https://github.com/tokio-rs/tracing/pull/1694 +[#1696]: https://github.com/tokio-rs/tracing/pull/1696 +[#1702]: https://github.com/tokio-rs/tracing/pull/1702 +[#1728]: https://github.com/tokio-rs/tracing/pull/1728 +[#1727]: https://github.com/tokio-rs/tracing/pull/1727 +# 0.3.1 (Oct 25, 2021) + +This release fixes a few issues related to feature flagging. + +### Fixed + +- **time**: Compilation error when enabling the "time" feature flag without also + enabling the "local-time" feature flag ([#1685]) +- **registry**: Unused method warnings when the "std" feature is enabled but the + "registry" feature is disabled ([#1686]) + +[#1685]: https://github.com/tokio-rs/tracing/pull/1685 +[#1686]: https://github.com/tokio-rs/tracing/pull/1686 + +# 0.3.0 (Oct 22, 2021) + +This is a breaking release of `tracing-subscriber`. The primary breaking change +in this release is the removal of the dependency on the [`chrono` crate], due to +[RUSTSEC-2020-0159]. To replace `chrono`, support is added for formatting +timestamps using the [`time` crate] instead. + +In addition, this release includes a number of other breaking API changes, such +as adding (limited) support for `#![no_std]` targets, removing previously +deprecated APIs, and more. + +### Breaking Changes + +- Removed APIs deprecated in the v0.2.x release series. +- Renamed `Layer::new_span` to `Layer::on_new_span` ([#1674]) +- Removed `Layer` impl for `Arc>` and `Arc + ...>` + ([#1649]) +- Replaced the [`chrono` crate] with the [`time` crate] for timestamp formatting, to + resolve [RUSTSEC-2020-0159] ([#1646]) +- Removed `json` and `env-filter` from default features. They must now be + enabled explictly ([#1647]). This means that `RUST_LOG`-based filters _will not_ + work unless the `env-filter` feature is enabled. +- Changed `FormatEvent::format_event` and `FormatFields::format_fields` + trait methods to take a `Writer` type, rather than a `&mut dyn fmt::Write` + trait object ([#1661]) +- Changed the signature of the `MakeWriter` trait by adding a lifetime parameter + ([#781]) + +### Changed + +- **layer**: Renamed `Layer::new_span` to `Layer::on_new_span` ([#1674]) +- **fmt**: Changed `FormatEvent::format_event` and `FormatFields::format_fields` + trait methods to take a `Writer` type, rather than a `&mut dyn fmt::Write` + trait object ([#1661]) +- **json**, **env-filter**: `json` and `env-filter` feature flags are no longer + enabled by default ([#1647]) +### Removed + +- Removed deprecated `CurrentSpan` type ([#1320]) +- **registry**: Removed deprecated `SpanRef::parents` iterator, replaced by + `SpanRef::scope` in [#1431] ([#1648)]) +- **layer**: Removed deprecated `Context::scope` iterator, replaced by + `Context::span_scope` and `Context::event_scope` in [#1431] and [#1434] + ([#1648)]) +- **layer**: Removed `Layer` impl for `Arc>` and + `Arc + ...>`. These interfere with per-layer filtering. ([#1649]) +- **fmt**: Removed deprecated `LayerBuilder` type ([#1673]) +- **fmt**: Removed `fmt::Layer::on_event` (renamed to `fmt::Layer::fmt_event`) + ([#1673]) +- **fmt**, **chrono**: Removed the `chrono` feature flag and APIs for using the + [`chrono` crate] for timestamp formatting ([#1646]) +### Added + +- **fmt**, **time**: `LocalTime` and `UtcTime` types for formatting timestamps + using the [`time` crate] ([#1646]) +- **fmt**: Added a lifetime parameter to the `MakeWriter` trait, allowing it to + return a borrowed writer. This enables implementations of `MakeWriter` for + types such as `Mutex` and `std::fs::File`. ([#781]) +- **env-filter**: Documentation improvements ([#1637]) +- Support for some APIs on `#![no_std]` targets, by disabling the `std` feature + flag ([#1660]) + +Thanks to @Folyd and @nmathewson for contributing to this release! + +[#1320]: https://github.com/tokio-rs/tracing/pull/1320 +[#1673]: https://github.com/tokio-rs/tracing/pull/1673 +[#1674]: https://github.com/tokio-rs/tracing/pull/1674 +[#1646]: https://github.com/tokio-rs/tracing/pull/1646 +[#1647]: https://github.com/tokio-rs/tracing/pull/1647 +[#1648]: https://github.com/tokio-rs/tracing/pull/1648 +[#1649]: https://github.com/tokio-rs/tracing/pull/1649 +[#1660]: https://github.com/tokio-rs/tracing/pull/1660 +[#1661]: https://github.com/tokio-rs/tracing/pull/1661 +[#1431]: https://github.com/tokio-rs/tracing/pull/1431 +[#1434]: https://github.com/tokio-rs/tracing/pull/1434 +[#781]: https://github.com/tokio-rs/tracing/pull/781 + +[`chrono` crate]: https://crates.io/crates/chrono +[`time` crate]: https://crates.io/crates/time +[RUSTSEC-2020-0159]: https://rustsec.org/advisories/RUSTSEC-2020-0159.html + +# 0.2.25 (October 5, 2021) + +This release fixes an issue where a `Layer` implementation's custom +`downcast_raw` implementation was lost when wrapping that layer with a per-layer +filter. + +### Fixed + +- **registry**: Forward `Filtered::downcast_raw` to wrapped `Layer` ([#1619]) + +### Added + +- Documentation improvements ([#1596], [#1601]) + +Thanks to @bryanburgers for contributing to this release! + +[#1619]: https://github.com/tokio-rs/tracing/pull/1619 +[#1601]: https://github.com/tokio-rs/tracing/pull/1601 +[#1596]: https://github.com/tokio-rs/tracing/pull/1596 + +# 0.2.24 (September 19, 2021) + +This release contains a number of bug fixes, including a fix for +`tracing-subscriber` failing to compile on the minimum supported Rust version of +1.42.0. It also adds `IntoIterator` implementations for the `Targets` type. + +### Fixed + +- Fixed compilation on Rust 1.42.0 ([#1580], [#1581]) +- **registry**: Ensure per-layer filter `enabled` state is cleared when a global + filter short-circuits filter evaluation ([#1575]) +- **layer**: Fixed `Layer::on_layer` not being called for `Box`ed `Layer`s, + which broke per-layer filtering ([#1576]) + +### Added + +- **filter**: Added `Targets::iter`, returning an iterator over the set of + target-level pairs enabled by a `Targets` filter ([#1574]) +- **filter**: Added `IntoIterator` implementations for `Targets` and `&Targets` + ([#1574]) + +Thanks to new contributor @connec for contributing to this release! + +[#1580]: https://github.com/tokio-rs/tracing/pull/1580 +[#1581]: https://github.com/tokio-rs/tracing/pull/1581 +[#1575]: https://github.com/tokio-rs/tracing/pull/1575 +[#1576]: https://github.com/tokio-rs/tracing/pull/1576 +[#1574]: https://github.com/tokio-rs/tracing/pull/1574 + +# 0.2.23 (September 16, 2021) + +This release fixes a few bugs in the per-layer filtering API added in v0.2.21. + +### Fixed + +- **env-filter**: Fixed excessive `EnvFilter` memory use ([#1568]) +- **filter**: Fixed a panic that may occur in debug mode when using per-layer + filters together with global filters ([#1569]) +- Fixed incorrect documentation formatting ([#1572]) + +[#1568]: https://github.com/tokio-rs/tracing/pull/1568 +[#1569]: https://github.com/tokio-rs/tracing/pull/1569 +[#1572]: https://github.com/tokio-rs/tracing/pull/1572 + +# 0.2.22 (September 13, 2021) + +This fixes a regression where the `filter::ParseError` type was accidentally +renamed. + +### Fixed + +- **filter**: Fix `filter::ParseError` accidentally being renamed to + `filter::DirectiveParseError` ([#1558]) + +[#1558]: https://github.com/tokio-rs/tracing/pull/1558 + +# 0.2.21 (September 12, 2021) + +This release introduces the [`Filter`] trait, a new API for [per-layer +filtering][plf]. This allows controlling which spans and events are recorded by +various layers individually, rather than globally. + +In addition, it adds a new [`Targets`] filter, which provides a lighter-weight +version of the filtering provided by [`EnvFilter`], as well as other smaller API +improvements and fixes. + +### Deprecated + +- **registry**: `SpanRef::parent_id`, which cannot properly support per-layer + filtering. Use `.parent().map(SpanRef::id)` instead. ([#1523]) + +### Fixed + +- **layer** `Context` methods that are provided when the `Subscriber` implements + `LookupSpan` no longer require the "registry" feature flag ([#1525]) +- **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` + type parameter to implement `Debug` ([#1528]) + +### Added + +- **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, + and other APIs for per-layer filtering ([#1523]) +- **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) + and per-layer (`Filter`) filtering for closures and function pointers + ([#1523]) +- **filter**: `Targets` filter, which implements a lighter-weight form of + `EnvFilter`-like filtering ([#1550]) +- **env-filter**: Added support for filtering on floating-point values ([#1507]) +- **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a +`Subscriber` ([#1523]) +- **layer**: `Layer` implementations for `Box` and `Arc` where `L: Layer` + ([#1536]) +- **layer**: `Layer` implementations for `Box + Send + Sync + 'static>` + and `Arc + Send + Sync + 'static>` ([#1536]) +- A number of small documentation fixes and improvements ([#1553], [#1544], + [#1539], [#1524]) + +Special thanks to new contributors @jsgf and @maxburke for contributing to this +release! + +[`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html +[plf]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering +[`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html +[`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html +[#1507]: https://github.com/tokio-rs/tracing/pull/1507 +[#1523]: https://github.com/tokio-rs/tracing/pull/1523 +[#1524]: https://github.com/tokio-rs/tracing/pull/1524 +[#1525]: https://github.com/tokio-rs/tracing/pull/1525 +[#1528]: https://github.com/tokio-rs/tracing/pull/1528 +[#1539]: https://github.com/tokio-rs/tracing/pull/1539 +[#1544]: https://github.com/tokio-rs/tracing/pull/1544 +[#1550]: https://github.com/tokio-rs/tracing/pull/1550 +[#1553]: https://github.com/tokio-rs/tracing/pull/1553 + +# 0.2.20 (August 17, 2021) + +### Fixed + +- **fmt**: Fixed `fmt` printing only the first `source` for errors with a chain + of sources ([#1460]) +- **fmt**: Fixed missing space between level and event in the `Pretty` formatter + ([#1498]) +- **json**: Fixed `Json` formatter not honoring `without_time` and `with_level` + configurations ([#1463]) + +### Added + +- **registry**: Improved panic message when cloning a span whose ID doesn't + exist, to aid in debugging issues with multiple subscribers ([#1483]) +- **registry**: Improved documentation on span ID generation ([#1453]) + +[#1460]: https://github.com/tokio-rs/tracing/pull/1460 +[#1483]: https://github.com/tokio-rs/tracing/pull/1483 +[#1463]: https://github.com/tokio-rs/tracing/pull/1463 +[#1453]: https://github.com/tokio-rs/tracing/pull/1453 +[#1498]: https://github.com/tokio-rs/tracing/pull/1498 + +Thanks to new contributors @joshtriplett and @lerouxrgd, and returning +contributor @teozkr, for contributing to this release! + +# 0.2.19 (June 25, 2021) + +### Deprecated + +- **registry**: `SpanRef::parents`, `SpanRef::from_root`, and `Context::scope` + iterators, which are replaced by new `SpanRef::scope` and `Scope::from_root` + iterators ([#1413]) + +### Added + +- **registry**: `SpanRef::scope` method, which returns a leaf-to-root `Iterator` + including the leaf span ([#1413]) +- **registry**: `Scope::from_root` method, which reverses the `scope` iterator + to iterate root-to-leaf ([#1413]) +- **registry**: `Context::event_span` method, which looks up the parent span of + an event ([#1434]) +- **registry**: `Context::event_scope` method, returning a `Scope` iterator over + the span scope of an event ([#1434]) +- **fmt**: `MakeWriter::make_writer_for` method, which allows returning a + different writer based on a span or event's metadata ([#1141]) +- **fmt**: `MakeWriterExt` trait, with `with_max_level`, `with_min_level`, + `with_filter`, `and`, and `or_else` combinators ([#1274]) +- **fmt**: `MakeWriter` implementation for `Arc where &W: io::Write` + ([#1274]) + +Thanks to @teozkr and @Folyd for contributing to this release! + +[#1413]: https://github.com/tokio-rs/tracing/pull/1413 +[#1434]: https://github.com/tokio-rs/tracing/pull/1434 +[#1141]: https://github.com/tokio-rs/tracing/pull/1141 +[#1274]: https://github.com/tokio-rs/tracing/pull/1274 + +# 0.2.18 (April 30, 2021) + +### Deprecated + +- Deprecated the `CurrentSpan` type, which is inefficient and largely superseded + by the `registry` API ([#1321]) + +### Fixed + +- **json**: Invalid JSON emitted for events in spans with no fields ([#1333]) +- **json**: Missing span data for synthesized new span, exit, and close events + ([#1334]) +- **fmt**: Extra space before log lines when timestamps are disabled ([#1355]) + +### Added + +- **env-filter**: Support for filters on spans whose names contain any + characters other than `{` and `]` ([#1368]) + +Thanks to @Folyd, and new contributors @akinnane and @aym-v for contributing to +this release! + +[#1321]: https://github.com/tokio-rs/tracing/pull/1321 +[#1333]: https://github.com/tokio-rs/tracing/pull/1333 +[#1334]: https://github.com/tokio-rs/tracing/pull/1334 +[#1355]: https://github.com/tokio-rs/tracing/pull/1355 +[#1368]: https://github.com/tokio-rs/tracing/pull/1368 + +# 0.2.17 (March 12, 2021) + +### Fixed + +- **fmt**: `Pretty` formatter now honors `with_ansi(false)` to disable ANSI + terminal formatting ([#1240]) +- **fmt**: Fixed extra padding when using `Pretty` formatter ([#1275]) +- **chrono**: Removed extra trailing space with `ChronoLocal` time formatter + ([#1103]) + +### Added + +- **fmt**: Added `FmtContext::current_span()` method, returning the current span + ([#1290]) +- **fmt**: `FmtSpan` variants may now be combined using the `|` operator for + more granular control over what span events are generated ([#1277]) + +Thanks to new contributors @cratelyn, @dignati, and @zicklag, as well as @Folyd, +@matklad, and @najamelan, for contributing to this release! + +[#1240]: https://github.com/tokio-rs/tracing/pull/1240 +[#1275]: https://github.com/tokio-rs/tracing/pull/1275 +[#1103]: https://github.com/tokio-rs/tracing/pull/1103 +[#1290]: https://github.com/tokio-rs/tracing/pull/1290 +[#1277]: https://github.com/tokio-rs/tracing/pull/1277 + +# 0.2.16 (February 19, 2021) + +### Fixed + +- **env-filter**: Fixed directives where the level is in mixed case (such as + `Info`) failing to parse ([#1126]) +- **fmt**: Fixed `fmt::Subscriber` not providing a max-level hint ([#1251]) +- `tracing-subscriber` no longer enables `tracing` and `tracing-core`'s default + features ([#1144]) + +### Changed + +- **chrono**: Updated `chrono` dependency to 0.4.16 ([#1189]) +- **log**: Updated `tracing-log` dependency to 0.1.2 + +Thanks to @salewski, @taiki-e, @davidpdrsn and @markdingram for contributing to +this release! + +[#1126]: https://github.com/tokio-rs/tracing/pull/1126 +[#1251]: https://github.com/tokio-rs/tracing/pull/1251 +[#1144]: https://github.com/tokio-rs/tracing/pull/1144 +[#1189]: https://github.com/tokio-rs/tracing/pull/1189 + +# 0.2.15 (November 2, 2020) + +### Fixed + +- **fmt**: Fixed wrong lifetime parameters on `FormatFields` impl for + `FmtContext` ([#1082]) + +### Added + +- **fmt**: `format::Pretty`, an aesthetically pleasing, human-readable event + formatter for local development and user-facing CLIs ([#1080]) +- **fmt**: `FmtContext::field_format`, which returns the subscriber's field + formatter ([#1082]) + +[#1082]: https://github.com/tokio-rs/tracing/pull/1082 +[#1080]: https://github.com/tokio-rs/tracing/pull/1080 + +# 0.2.14 (October 22, 2020) + +### Fixed + +- **registry**: Fixed `Registry::new` allocating an excessively large amount of + memory, most of which would never be used ([#1064]) + +### Changed + +- **registry**: Improved `new_span` performance by reusing `HashMap` allocations + for `Extensions` ([#1064]) +- **registry**: Significantly improved the performance of `Registry::enter` and + `Registry::exit` ([#1058]) + +[#1064]: https://github.com/tokio-rs/tracing/pull/1064 +[#1058]: https://github.com/tokio-rs/tracing/pull/1058 + +# 0.2.13 (October 7, 2020) + +### Changed + +- Updated `tracing-core` to 0.1.17 ([#992]) + +### Added + +- **env-filter**: Added support for filtering on targets which contain dashes + ([#1014]) +- **env-filter**: Added a warning when creating an `EnvFilter` that contains + directives that would enable a level disabled by the `tracing` crate's + `static_max_level` features ([#1021]) + +Thanks to @jyn514 and @bkchr for contributing to this release! + +[#992]: https://github.com/tokio-rs/tracing/pull/992 +[#1014]: https://github.com/tokio-rs/tracing/pull/1014 +[#1021]: https://github.com/tokio-rs/tracing/pull/1021 + +# 0.2.12 (September 11, 2020) + +### Fixed + +- **env-filter**: Fixed a regression where `Option` lost its + `Into` impl ([#966]) +- **env-filter**: Fixed `EnvFilter` enabling spans that should not be enabled + when multiple subscribers are in use ([#927]) + +### Changed + +- **json**: `format::Json` now outputs fields in a more readable order ([#892]) +- Updated `tracing-core` dependency to 0.1.16 + +### Added + +- **fmt**: Add `BoxMakeWriter` for erasing the type of a `MakeWriter` + implementation ([#958]) +- **fmt**: Add `TestWriter` `MakeWriter` implementation to support libtest + output capturing ([#938]) +- **layer**: Add `Layer` impl for `Option where T: Layer` ([#910]) +- **env-filter**: Add `From` impl for `Directive` ([#918]) +- Multiple documentation fixes and improvements + +Thanks to @Pothulapati, @samrg472, @bryanburgers, @keetonian, and @SriRamanujam +for contributing to this release! + +[#927]: https://github.com/tokio-rs/tracing/pull/927 +[#966]: https://github.com/tokio-rs/tracing/pull/966 +[#958]: https://github.com/tokio-rs/tracing/pull/958 +[#892]: https://github.com/tokio-rs/tracing/pull/892 +[#938]: https://github.com/tokio-rs/tracing/pull/938 +[#910]: https://github.com/tokio-rs/tracing/pull/910 +[#918]: https://github.com/tokio-rs/tracing/pull/918 + +# 0.2.11 (August 10, 2020) + +### Fixed + +- **env-filter**: Incorrect max level hint when filters involving span field + values are in use (#907) +- **registry**: Fixed inconsistent span stacks when multiple registries are in + use on the same thread (#901) + +### Changed + +- **env-filter**: `regex` dependency enables fewer unused feature flags (#899) + +Thanks to @bdonlan and @jeromegn for contributing to this release! + +# 0.2.10 (July 31, 2020) + +### Fixed + +- **docs**: Incorrect formatting (#862) + +### Changed + +- **filter**: `LevelFilter` is now a re-export of the + `tracing_core::LevelFilter` type, it can now be used interchangably with the + versions in `tracing` and `tracing-core` (#853) +- **filter**: Significant performance improvements when comparing `LevelFilter`s + and `Level`s (#853) +- Updated the minimum `tracing-core` dependency to 0.1.12 (#853) + +### Added + +- **filter**: `LevelFilter` and `EnvFilter` now participate in `tracing-core`'s + max level hinting, improving performance significantly in some use cases where + levels are disabled globally (#853) + +# 0.2.9 (July 23, 2020) + +### Fixed + +- **fmt**: Fixed compilation failure on MSRV when the `chrono` feature is + disabled (#844) + +### Added + +- **fmt**: Span lookup methods defined by `layer::Context` are now also provided + by `FmtContext` (#834) + +# 0.2.8 (July 17, 2020) + +### Changed + +- **fmt**: When the `chrono` dependency is enabled, the `SystemTime` timestamp + formatter now emits human-readable timestamps rather than using `SystemTime`'s + `fmt::Debug`implementation (`chrono` is still required for customized + timestamp formatting) (#807) +- **ansi**: Updated `ansi_term` dependency to 0.12 (#816) + +### Added + +- **json**: `with_span_list` method to configure the JSON formatter to include a + list of all spans in the current trace in formatting events (similarly to the + text formatter) (#741) +- **json**: `with_current_span` method to configure the JSON formatter to include + a field for the _current_ span (the leaf of the trace) in formatted events + (#741) +- **fmt**: `with_thread_names` and `with_thread_ids` methods to configure + `fmt::Subscriber`s and `fmt::Layer`s to include the thread name and/or thread ID + of the current thread when formatting events (#818) + +Thanks to new contributors @mockersf, @keetonian, and @Pothulapati for +contributing to this release! + +# 0.2.7 (July 1, 2020) + +### Changed + +- **parking_lot**: Updated the optional `parking_lot` dependency to accept the + latest `parking_lot` version (#774) + +### Fixed + +- **fmt**: Fixed events with explicitly overridden parent spans being formatted + as though they were children of the current span (#767) + +### Added + +- **fmt**: Added the option to print synthesized events when spans are created, + entered, exited, and closed, including span durations (#761) +- Documentation clarification and improvement (#762, #769) + +Thanks to @rkuhn, @greenwoodcm, and @Ralith for contributing to this release! + +# 0.2.6 (June 19, 2020) + +### Fixed + +- **fmt**: Fixed an issue in the JSON formatter where using `Span::record` would + result in malformed spans (#709) + +# 0.2.5 (April 21, 2020) + +### Changed + +- **fmt**: Bump sharded-slab dependency (#679) + +### Fixed + +- **fmt**: remove trailing space in `ChronoUtc` `format_time` (#677) + +# 0.2.4 (April 6, 2020) + +This release includes several API ergonomics improvements, including shorthand +constructors for many types, and an extension trait for initializing subscribers +using method-chaining style. Additionally, several bugs in less commonly used +`fmt` APIs were fixed. + +### Added + +- **fmt**: Shorthand free functions for constructing most types in `fmt` + (including `tracing_subscriber::fmt()` to return a `SubscriberBuilder`, + `tracing_subscriber::fmt::layer()` to return a format `Layer`, etc) (#660) +- **registry**: Shorthand free function `tracing_subscriber::registry()` to + construct a new registry (#660) +- Added `SubscriberInitExt` extension trait for more ergonomic subscriber + initialization (#660) + +### Changed + +- **fmt**: Moved `LayerBuilder` methods to `Layer` (#655) + +### Deprecated + +- **fmt**: `LayerBuilder`, as `Layer` now implements all builder methods (#655) + +### Fixed + +- **fmt**: Fixed `Compact` formatter not omitting levels with + `with_level(false)` (#657) +- **fmt**: Fixed `fmt::Layer` duplicating the fields for a new span if another + layer has already formatted its fields (#634) +- **fmt**: Added missing space when using `record` to add new fields to a span + that already has fields (#659) +- Updated outdated documentation (#647) + + +# 0.2.3 (March 5, 2020) + +### Fixed + +- **env-filter**: Regression where filter directives were selected in the order + they were listed, rather than most specific first (#624) + +# 0.2.2 (February 27, 2020) + +### Added + +- **fmt**: Added `flatten_event` to `SubscriberBuilder` (#599) +- **fmt**: Added `with_level` to `SubscriberBuilder` (#594) + +# 0.2.1 (February 13, 2020) + +### Changed + +- **filter**: `EnvFilter` directive selection now behaves correctly (i.e. like + `env_logger`) (#583) + +### Fixed + +- **filter**: Fixed `EnvFilter` incorrectly allowing less-specific filter + directives to enable events that are disabled by more-specific filters (#583) +- **filter**: Multiple significant `EnvFilter` performance improvements, + especially when filtering events generated by `log` records (#578, #583) +- **filter**: Replaced `BTreeMap` with `Vec` in `DirectiveSet`, improving + iteration performance significantly with typical numbers of filter directives + (#580) + +A big thank-you to @samschlegel for lots of help with `EnvFilter` performance +tuning in this release! + +# 0.2.0 (February 4, 2020) + +### Breaking Changes + +- **fmt**: Renamed `Context` to `FmtContext` (#420, #425) +- **fmt**: Renamed `Builder` to `SubscriberBuilder` (#420) +- **filter**: Removed `Filter`. Use `EnvFilter` instead (#434) + +### Added + +- **registry**: `Registry`, a `Subscriber` implementation that `Layer`s can use + as a high-performance, in-memory span store. (#420, #425, #432, #433, #435) +- **registry**: Added `LookupSpan` trait, implemented by `Subscriber`s to expose + stored span data to `Layer`s (#420) +- **fmt**: Added `fmt::Layer`, to allow composing log formatting with other `Layer`s +- **fmt**: Added support for JSON field and event formatting (#377, #415) +- **filter**: Documentation for filtering directives (#554) + +### Changed + +- **fmt**: Renamed `Context` to `FmtContext` (#420, #425) (BREAKING) +- **fmt**: Renamed `Builder` to `SubscriberBuilder` (#420) (BREAKING) +- **fmt**: Reimplemented `fmt::Subscriber` in terms of the `Registry` + and `Layer`s (#420) + +### Removed + +- **filter**: Removed `Filter`. Use `EnvFilter` instead (#434) (BREAKING) + +### Fixed + +- **fmt**: Fixed memory leaks in the slab used to store per-span data + (3c35048) +- **fmt**: `fmt::SubscriberBuilder::init` not setting up `log` compatibility + (#489) +- **fmt**: Spans closed by a child span closing not also closing _their_ + parents (#514) +- **Layer**: Fixed `Layered` subscribers failing to downcast to their own type + (#549) +- **Layer**: Fixed `Layer::downcast_ref` returning invalid references (#454) + +# 0.2.0-alpha.6 (February 3, 2020) + +### Fixed + +- **fmt**: Fixed empty `{}` printed after spans with no fields (f079f2d) +- **fmt**: Fixed inconsistent formatting when ANSI colors are disabled (506a482) +- **fmt**: Fixed mis-aligned levels when ANSI colors are disabled (eba1adb) +- Fixed warnings on nightly Rust compilers (#558) + +# 0.2.0-alpha.5 (January 31, 2020) + +### Added + +- **env_filter**: Documentation for filtering directives (#554) +- **registry**, **env_filter**: Updated `smallvec` dependency to 0.1 (#543) + +### Fixed + +- **registry**: Fixed a memory leak in the slab used to store per-span data + (3c35048) +- **Layer**: Fixed `Layered` subscribers failing to downcast to their own type + (#549) +- **fmt**: Fixed a panic when multiple layers insert `FormattedFields` + extensions from the same formatter type (1c3bb70) +- **fmt**: Fixed `fmt::Layer::on_record` inserting a new `FormattedFields` when + formatted fields for a span already exist (1c3bb70) + +# 0.2.0-alpha.4 (January 11, 2020) + +### Fixed + +- **registry**: Removed inadvertently committed `dbg!` macros (#533) + +# 0.2.0-alpha.3 (January 10, 2020) + +### Added + +- **fmt**: Public `FormattedFields::new` constructor (#478) +- **fmt**: Added examples to `fmt::Layer` documentation (#510) +- Documentation now shows what feature flags are required by each API item (#525) + +### Fixed + +- **fmt**: Missing space between timestamp and level (#480) +- **fmt**: Incorrect formatting with `with_target(false)` (#481) +- **fmt**: `fmt::SubscriberBuilder::init` not setting up `log` compatibility + (#489) +- **registry**: Spans exited out of order not being closed properly on exit + (#509) +- **registry**: Memory leak when spans are closed by a child span closing (#514) +- **registry**: Spans closed by a child span closing not also closing _their_ + parents (#514) +- Compilation errors with `no-default-features` (#499, #500) + +# 0.2.0-alpha.2 (December 8, 2019) + +### Added + +- `LookupSpans` implementation for `Layered` (#448) +- `SpanRef::from_root` to iterate over a span's parents from the root (#460) +- `Context::scope`, to iterate over the current context from the root (#460) +- `Context::lookup_current`, which returns a `SpanRef` to the current + span's data (#460) + +### Changed + +- Lifetimes on some new `Context` methods to be less restrictive (#460) + +### Fixed + +- `Layer::downcast_ref` returning invalid references (#454) +- Compilation failure on 32-bit platforms (#462) +- Compilation failure with ANSI formatters (#438) + +# 0.2.0-alpha.1 (November 18, 2019) + +### Added + +- `Registry`, a reusable span store that `Layer`s can use a + high-performance, in-memory store. (#420, #425, #432, #433, #435) +- Reimplemented `fmt::Subscriber` in terms of the `Registry` + and `Layer`s (#420) +- Add benchmarks for fmt subscriber (#421) +- Add support for JSON field and event formatting (#377, #415) + +### Changed + +- **BREAKING**: Change `fmt::format::FormatFields` and + `fmt::format::FormatEvent` to accept a mandatory `FmtContext`. These + `FormatFields` and `FormatEvent` will likely see additional breaking + changes in subsequent alpha. (#420, #425) +- **BREAKING**: Removed `Filter`. Use `EnvFilter` instead (#434) + +### Contributers + +Thanks to all the contributers to this release! + +- @pimeys for #377 and #415 + +# 0.1.6 (October 29, 2019) + +### Added + +- Add `init` and `try_init` functions to `FmtSubscriber` (#385) +- Add `ChronoUtc` and `ChronoLocal` timers, RFC 3339 support (#387) +- Add `tracing::subscriber::set_default` which sets the default + subscriber and returns a drop guard. This drop guard will reset the + dispatch on drop (#388). + +### Fixed + +- Fix default level for `EnvFilter`. Setting `RUST_LOG=target` + previously only the `ERROR` level, while it should enable everything. + `tracing-subscriber` now defaults to `TRACE` if no level is specified + (#401) +- Fix `tracing-log` feature flag for init + try_init. The feature flag + `tracing_log` was used instead of the correct `tracing-log`. As a + result, both `tracing-log` and `tracing_log` needed to be specified in + order to initialize the global logger. Only `tracing-log` needs to be + specified now (#400). + +### Contributers + +Thanks to all the contributers to this release! + +- @emschwartz for #385, #387, #400 and #401 +- @bIgBV for #388 + +# 0.1.5 (October 7, 2019) + +### Fixed + +- Spans not being closed properly when `FmtSubscriber::current_span` is used + (#371) + +# 0.1.4 (September 26, 2019) + +### Fixed + +- Spans entered twice on the same thread sometimes being completely exited when + the more deeply-nested entry is exited (#361) +- Setting `with_ansi(false)` on `FmtSubscriber` not disabling ANSI color + formatting for timestamps (#354) +- Incorrect reference counting in `FmtSubscriber` that could cause spans to not + be closed when all references are dropped (#366) + +# 0.1.3 (September 16, 2019) + +### Fixed + +- `Layered` subscribers not properly forwarding calls to `current_span` + (#350) + +# 0.1.2 (September 12, 2019) + +### Fixed + +- `EnvFilter` ignoring directives with targets that are the same number of + characters (#333) +- `EnvFilter` failing to properly apply filter directives to events generated + from `log` records by`tracing-log` (#344) + +### Changed + +- Renamed `Filter` to `EnvFilter`, deprecated `Filter` (#339) +- Renamed "filter" feature flag to "env-filter", deprecated "filter" (#339) +- `FmtSubscriber` now defaults to enabling only the `INFO` level and above when + a max level filter or `EnvFilter` is not set (#336) +- Made `parking_lot` dependency an opt-in feature flag (#348) + +### Added + +- `EnvFilter::add_directive` to add new directives to filters after they are + constructed (#334) +- `fmt::Builder::with_max_level` to set a global level filter for a + `FmtSubscriber` without requiring the use of `EnvFilter` (#336) +- `Layer` implementation for `LevelFilter` (#336) +- `EnvFilter` now implements `fmt::Display` (#329) + +### Removed + +- Removed dependency on `crossbeam-util` (#348) + +# 0.1.1 (September 4, 2019) + +### Fixed + +- Potential double panic in `CurrentSpan` (#325) + +# 0.1.0 (September 3, 2019) + +- Initial release diff --git a/vendor/tracing-subscriber-0.3.3/Cargo.toml b/vendor/tracing-subscriber-0.3.3/Cargo.toml new file mode 100644 index 000000000..b5e7ba7db --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/Cargo.toml @@ -0,0 +1,150 @@ +# 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 = "2018" +rust-version = "1.42.0" +name = "tracing-subscriber" +version = "0.3.3" +authors = ["Eliza Weisman ", "David Barsky ", "Tokio Contributors "] +description = "Utilities for implementing and composing `tracing` subscribers.\n" +homepage = "https://tokio.rs" +readme = "README.md" +keywords = ["logging", "tracing", "metrics", "subscriber"] +categories = ["development-tools::debugging", "development-tools::profiling", "asynchronous"] +license = "MIT" +repository = "https://github.com/tokio-rs/tracing" +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[[bench]] +name = "filter" +harness = false + +[[bench]] +name = "filter_log" +harness = false + +[[bench]] +name = "fmt" +harness = false + +[[bench]] +name = "enter" +harness = false +[dependencies.ansi_term] +version = "0.12" +optional = true + +[dependencies.lazy_static] +version = "1" +optional = true + +[dependencies.matchers] +version = "0.1.0" +optional = true + +[dependencies.parking_lot] +version = ">= 0.7, <= 0.11" +optional = true + +[dependencies.regex] +version = "1" +features = ["std"] +optional = true +default-features = false + +[dependencies.serde] +version = "1.0" +optional = true + +[dependencies.serde_json] +version = "1.0" +optional = true + +[dependencies.sharded-slab] +version = "0.1.0" +optional = true + +[dependencies.smallvec] +version = "1" +optional = true + +[dependencies.thread_local] +version = "1.0.1" +optional = true + +[dependencies.time] +version = "0.3" +features = ["formatting"] +optional = true + +[dependencies.tracing] +version = "0.1" +optional = true +default-features = false + +[dependencies.tracing-core] +version = "0.1.20" + +[dependencies.tracing-log] +version = "0.1.2" +features = ["log-tracer", "std"] +optional = true +default-features = false + +[dependencies.tracing-serde] +version = "0.1.2" +optional = true +[dev-dependencies.criterion] +version = "0.3" +default_features = false + +[dev-dependencies.log] +version = "0.4" + +[dev-dependencies.regex] +version = "1" +features = ["std"] +default-features = false + +[dev-dependencies.time] +version = "0.3" +features = ["formatting", "macros"] + +[dev-dependencies.tokio] +version = "0.2" +features = ["rt-core", "macros"] + +[dev-dependencies.tracing] +version = "0.1" + +[dev-dependencies.tracing-futures] +version = "0.2" +features = ["std-future", "std"] +default-features = false + +[dev-dependencies.tracing-log] +version = "0.1.2" + +[features] +alloc = [] +ansi = ["fmt", "ansi_term"] +default = ["smallvec", "fmt", "ansi", "tracing-log", "std"] +env-filter = ["matchers", "regex", "lazy_static", "tracing", "std"] +fmt = ["registry", "std"] +json = ["tracing-serde", "serde", "serde_json"] +local-time = ["time/local-offset"] +registry = ["sharded-slab", "thread_local", "std"] +std = ["alloc", "tracing-core/std"] +[badges.maintenance] +status = "experimental" diff --git a/vendor/tracing-subscriber-0.3.3/LICENSE b/vendor/tracing-subscriber-0.3.3/LICENSE new file mode 100644 index 000000000..cdb28b4b5 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tokio 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. diff --git a/vendor/tracing-subscriber-0.3.3/README.md b/vendor/tracing-subscriber-0.3.3/README.md new file mode 100644 index 000000000..75c62e8ca --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/README.md @@ -0,0 +1,61 @@ +![Tracing — Structured, application-level diagnostics][splash] + +[splash]: https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/splash.svg + +# tracing-subscriber + +Utilities for implementing and composing [`tracing`][tracing] subscribers. + +[![Crates.io][crates-badge]][crates-url] +[![Documentation][docs-badge]][docs-url] +[![Documentation (master)][docs-master-badge]][docs-master-url] +[![MIT licensed][mit-badge]][mit-url] +[![Build Status][actions-badge]][actions-url] +[![Discord chat][discord-badge]][discord-url] +![maintenance status][maint-badge] + +[Documentation][docs-url] | [Chat][discord-url] + +[tracing]: https://github.com/tokio-rs/tracing/tree/master/tracing +[tracing-fmt]: https://github.com/tokio-rs/tracing/tree/master/tracing-subscriber +[crates-badge]: https://img.shields.io/crates/v/tracing-subscriber.svg +[crates-url]: https://crates.io/crates/tracing-subscriber +[docs-badge]: https://docs.rs/tracing-subscriber/badge.svg +[docs-url]: https://docs.rs/tracing-subscriber/0.3.1 +[docs-master-badge]: https://img.shields.io/badge/docs-master-blue +[docs-master-url]: https://tracing-rs.netlify.com/tracing_subscriber +[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg +[mit-url]: LICENSE +[actions-badge]: https://github.com/tokio-rs/tracing/workflows/CI/badge.svg +[actions-url]:https://github.com/tokio-rs/tracing/actions?query=workflow%3ACI +[discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white +[discord-url]: https://discord.gg/EeF3cQw +[maint-badge]: https://img.shields.io/badge/maintenance-experimental-blue.svg + +*Compiler support: [requires `rustc` 1.42+][msrv]* + +[msrv]: #supported-rust-versions + +## Supported Rust Versions + +Tracing is built against the latest stable release. The minimum supported +version is 1.42. The current Tracing version is not guaranteed to build on Rust +versions earlier than the minimum supported version. + +Tracing follows the same compiler support policies as the rest of the Tokio +project. The current stable Rust compiler and the three most recent minor +versions before it will always be supported. For example, if the current stable +compiler version is 1.45, the minimum supported version will not be increased +past 1.42, three minor versions prior. Increasing the minimum supported compiler +version is not considered a semver breaking change as long as doing so complies +with this policy. + +## License + +This project is licensed under the [MIT license](LICENSE). + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Tracing by you, shall be licensed as MIT, without any additional +terms or conditions. diff --git a/vendor/tracing-subscriber-0.3.3/benches/enter.rs b/vendor/tracing-subscriber-0.3.3/benches/enter.rs new file mode 100644 index 000000000..49c6e730a --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/benches/enter.rs @@ -0,0 +1,64 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use tracing_subscriber::prelude::*; + +fn enter(c: &mut Criterion) { + let mut group = c.benchmark_group("enter"); + let _subscriber = tracing_subscriber::fmt() + .with_max_level(tracing::Level::INFO) + .finish() + .set_default(); + group.bench_function("enabled", |b| { + let span = tracing::info_span!("foo"); + b.iter_with_large_drop(|| span.enter()) + }); + group.bench_function("disabled", |b| { + let span = tracing::debug_span!("foo"); + b.iter_with_large_drop(|| span.enter()) + }); +} + +fn enter_exit(c: &mut Criterion) { + let mut group = c.benchmark_group("enter_exit"); + let _subscriber = tracing_subscriber::fmt() + .with_max_level(tracing::Level::INFO) + .finish() + .set_default(); + group.bench_function("enabled", |b| { + let span = tracing::info_span!("foo"); + b.iter(|| span.enter()) + }); + group.bench_function("disabled", |b| { + let span = tracing::debug_span!("foo"); + b.iter(|| span.enter()) + }); +} + +fn enter_many(c: &mut Criterion) { + let mut group = c.benchmark_group("enter_many"); + let _subscriber = tracing_subscriber::fmt() + .with_max_level(tracing::Level::INFO) + .finish() + .set_default(); + group.bench_function("enabled", |b| { + let span1 = tracing::info_span!("span1"); + let _e1 = span1.enter(); + let span2 = tracing::info_span!("span2"); + let _e2 = span2.enter(); + let span3 = tracing::info_span!("span3"); + let _e3 = span3.enter(); + let span = tracing::info_span!("foo"); + b.iter_with_large_drop(|| span.enter()) + }); + group.bench_function("disabled", |b| { + let span1 = tracing::info_span!("span1"); + let _e1 = span1.enter(); + let span2 = tracing::info_span!("span2"); + let _e2 = span2.enter(); + let span3 = tracing::info_span!("span3"); + let _e3 = span3.enter(); + let span = tracing::debug_span!("foo"); + b.iter_with_large_drop(|| span.enter()) + }); +} +criterion_group!(benches, enter, enter_exit, enter_many); +criterion_main!(benches); diff --git a/vendor/tracing-subscriber-0.3.3/benches/filter.rs b/vendor/tracing-subscriber-0.3.3/benches/filter.rs new file mode 100644 index 000000000..91ab9c91d --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/benches/filter.rs @@ -0,0 +1,308 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use std::time::Duration; +use tracing::{dispatcher::Dispatch, span, Event, Id, Metadata}; +use tracing_subscriber::{prelude::*, EnvFilter}; + +mod support; +use support::MultithreadedBench; + +/// A subscriber that is enabled but otherwise does nothing. +struct EnabledSubscriber; + +impl tracing::Subscriber for EnabledSubscriber { + fn new_span(&self, span: &span::Attributes<'_>) -> Id { + let _ = span; + Id::from_u64(0xDEAD_FACE) + } + + fn event(&self, event: &Event<'_>) { + let _ = event; + } + + fn record(&self, span: &Id, values: &span::Record<'_>) { + let _ = (span, values); + } + + fn record_follows_from(&self, span: &Id, follows: &Id) { + let _ = (span, follows); + } + + fn enabled(&self, metadata: &Metadata<'_>) -> bool { + let _ = metadata; + true + } + + fn enter(&self, span: &Id) { + let _ = span; + } + + fn exit(&self, span: &Id) { + let _ = span; + } +} + +fn bench_static(c: &mut Criterion) { + let mut group = c.benchmark_group("static"); + + group.bench_function("baseline_single_threaded", |b| { + tracing::subscriber::with_default(EnabledSubscriber, || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + tracing::debug!(target: "static_filter", "hi"); + tracing::warn!(target: "static_filter", "hi"); + tracing::trace!(target: "foo", "hi"); + }) + }); + }); + group.bench_function("single_threaded", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + tracing::debug!(target: "static_filter", "hi"); + tracing::warn!(target: "static_filter", "hi"); + tracing::trace!(target: "foo", "hi"); + }) + }); + }); + group.bench_function("enabled_one", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("enabled_many", |b| { + let filter = "foo=debug,bar=trace,baz=error,quux=warn,static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_level_one", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::debug!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_level_many", |b| { + let filter = "foo=debug,bar=info,baz=error,quux=warn,static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::trace!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_one", |b| { + let filter = "foo=info".parse::().expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_many", |b| { + let filter = "foo=debug,bar=trace,baz=error,quux=warn,whibble=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("baseline_multithreaded", |b| { + let dispatch = Dispatch::new(EnabledSubscriber); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + tracing::info!(target: "static_filter", "hi"); + }) + .thread(|| { + tracing::debug!(target: "static_filter", "hi"); + }) + .thread(|| { + tracing::warn!(target: "static_filter", "hi"); + }) + .thread(|| { + tracing::warn!(target: "foo", "hi"); + }) + .run(); + total += elapsed; + } + total + }) + }); + group.bench_function("multithreaded", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + tracing::info!(target: "static_filter", "hi"); + }) + .thread(|| { + tracing::debug!(target: "static_filter", "hi"); + }) + .thread(|| { + tracing::warn!(target: "static_filter", "hi"); + }) + .thread(|| { + tracing::warn!(target: "foo", "hi"); + }) + .run(); + total += elapsed; + } + total + }); + }); + group.finish(); +} + +fn bench_dynamic(c: &mut Criterion) { + let mut group = c.benchmark_group("dynamic"); + + group.bench_function("baseline_single_threaded", |b| { + tracing::subscriber::with_default(EnabledSubscriber, || { + b.iter(|| { + tracing::info_span!("foo").in_scope(|| { + tracing::info!("hi"); + tracing::debug!("hi"); + }); + tracing::info_span!("bar").in_scope(|| { + tracing::warn!("hi"); + }); + tracing::trace!("hi"); + }) + }); + }); + group.bench_function("single_threaded", |b| { + let filter = "[foo]=trace".parse::().expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info_span!("foo").in_scope(|| { + tracing::info!("hi"); + tracing::debug!("hi"); + }); + tracing::info_span!("bar").in_scope(|| { + tracing::warn!("hi"); + }); + tracing::trace!("hi"); + }) + }); + }); + group.bench_function("baseline_multithreaded", |b| { + let dispatch = Dispatch::new(EnabledSubscriber); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + tracing::info!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + tracing::debug!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("bar"); + let _ = span.enter(); + tracing::debug!("hi"); + }) + .thread(|| { + tracing::trace!("hi"); + }) + .run(); + total += elapsed; + } + total + }) + }); + group.bench_function("multithreaded", |b| { + let filter = "[foo]=trace".parse::().expect("should parse"); + let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + tracing::info!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + tracing::debug!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("bar"); + let _ = span.enter(); + tracing::debug!("hi"); + }) + .thread(|| { + tracing::trace!("hi"); + }) + .run(); + total += elapsed; + } + total + }) + }); + + group.finish(); +} + +fn bench_mixed(c: &mut Criterion) { + let mut group = c.benchmark_group("mixed"); + group.bench_function("disabled", |b| { + let filter = "[foo]=trace,bar[quux]=debug,[{baz}]=debug,asdf=warn,wibble=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_by_level", |b| { + let filter = "[foo]=info,bar[quux]=debug,asdf=warn,static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::trace!(target: "static_filter", "hi"); + }) + }); + }); +} + +criterion_group!(benches, bench_static, bench_dynamic, bench_mixed); +criterion_main!(benches); diff --git a/vendor/tracing-subscriber-0.3.3/benches/filter_log.rs b/vendor/tracing-subscriber-0.3.3/benches/filter_log.rs new file mode 100644 index 000000000..4dcf3b4ec --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/benches/filter_log.rs @@ -0,0 +1,315 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use std::time::Duration; +use tracing::{dispatcher::Dispatch, span, Event, Id, Metadata}; +use tracing_subscriber::{prelude::*, EnvFilter}; + +mod support; +use support::MultithreadedBench; + +/// A subscriber that is enabled but otherwise does nothing. +struct EnabledSubscriber; + +impl tracing::Subscriber for EnabledSubscriber { + fn new_span(&self, span: &span::Attributes<'_>) -> Id { + let _ = span; + Id::from_u64(0xDEAD_FACE) + } + + fn event(&self, event: &Event<'_>) { + let _ = event; + } + + fn record(&self, span: &Id, values: &span::Record<'_>) { + let _ = (span, values); + } + + fn record_follows_from(&self, span: &Id, follows: &Id) { + let _ = (span, follows); + } + + fn enabled(&self, metadata: &Metadata<'_>) -> bool { + let _ = metadata; + true + } + + fn enter(&self, span: &Id) { + let _ = span; + } + + fn exit(&self, span: &Id) { + let _ = span; + } +} + +fn bench_static(c: &mut Criterion) { + let _ = tracing_log::LogTracer::init(); + + let mut group = c.benchmark_group("log/static"); + + group.bench_function("baseline_single_threaded", |b| { + tracing::subscriber::with_default(EnabledSubscriber, || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + log::debug!(target: "static_filter", "hi"); + log::warn!(target: "static_filter", "hi"); + log::trace!(target: "foo", "hi"); + }) + }); + }); + group.bench_function("single_threaded", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + log::debug!(target: "static_filter", "hi"); + log::warn!(target: "static_filter", "hi"); + log::trace!(target: "foo", "hi"); + }) + }); + }); + group.bench_function("enabled_one", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("enabled_many", |b| { + let filter = "foo=debug,bar=trace,baz=error,quux=warn,static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_level_one", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::debug!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_level_many", |b| { + let filter = "foo=debug,bar=info,baz=error,quux=warn,static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::trace!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_one", |b| { + let filter = "foo=info".parse::().expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_many", |b| { + let filter = "foo=debug,bar=trace,baz=error,quux=warn,whibble=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("baseline_multithreaded", |b| { + let dispatch = Dispatch::new(EnabledSubscriber); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + log::info!(target: "static_filter", "hi"); + }) + .thread(|| { + log::debug!(target: "static_filter", "hi"); + }) + .thread(|| { + log::warn!(target: "static_filter", "hi"); + }) + .thread(|| { + log::warn!(target: "foo", "hi"); + }) + .run(); + total += elapsed; + } + total + }) + }); + group.bench_function("multithreaded", |b| { + let filter = "static_filter=info" + .parse::() + .expect("should parse"); + let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + log::info!(target: "static_filter", "hi"); + }) + .thread(|| { + log::debug!(target: "static_filter", "hi"); + }) + .thread(|| { + log::warn!(target: "static_filter", "hi"); + }) + .thread(|| { + log::warn!(target: "foo", "hi"); + }) + .run(); + total += elapsed; + } + total + }); + }); + group.finish(); +} + +fn bench_dynamic(c: &mut Criterion) { + let _ = tracing_log::LogTracer::init(); + + let mut group = c.benchmark_group("log/dynamic"); + + group.bench_function("baseline_single_threaded", |b| { + tracing::subscriber::with_default(EnabledSubscriber, || { + b.iter(|| { + tracing::info_span!("foo").in_scope(|| { + log::info!("hi"); + log::debug!("hi"); + }); + tracing::info_span!("bar").in_scope(|| { + log::warn!("hi"); + }); + log::trace!("hi"); + }) + }); + }); + group.bench_function("single_threaded", |b| { + let filter = "[foo]=trace".parse::().expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + tracing::info_span!("foo").in_scope(|| { + log::info!("hi"); + log::debug!("hi"); + }); + tracing::info_span!("bar").in_scope(|| { + log::warn!("hi"); + }); + log::trace!("hi"); + }) + }); + }); + group.bench_function("baseline_multithreaded", |b| { + let dispatch = Dispatch::new(EnabledSubscriber); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + log::info!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + log::debug!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("bar"); + let _ = span.enter(); + log::debug!("hi"); + }) + .thread(|| { + log::trace!("hi"); + }) + .run(); + total += elapsed; + } + total + }) + }); + group.bench_function("multithreaded", |b| { + let filter = "[foo]=trace".parse::().expect("should parse"); + let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + log::info!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("foo"); + let _ = span.enter(); + log::debug!("hi"); + }) + .thread(|| { + let span = tracing::info_span!("bar"); + let _ = span.enter(); + log::debug!("hi"); + }) + .thread(|| { + log::trace!("hi"); + }) + .run(); + total += elapsed; + } + total + }) + }); + + group.finish(); +} + +fn bench_mixed(c: &mut Criterion) { + let _ = tracing_log::LogTracer::init(); + + let mut group = c.benchmark_group("log/mixed"); + + group.bench_function("disabled", |b| { + let filter = "[foo]=trace,bar[quux]=debug,[{baz}]=debug,asdf=warn,wibble=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::info!(target: "static_filter", "hi"); + }) + }); + }); + group.bench_function("disabled_by_level", |b| { + let filter = "[foo]=info,bar[quux]=debug,asdf=warn,static_filter=info" + .parse::() + .expect("should parse"); + tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { + b.iter(|| { + log::trace!(target: "static_filter", "hi"); + }) + }); + }); +} + +criterion_group!(benches, bench_static, bench_dynamic, bench_mixed); +criterion_main!(benches); diff --git a/vendor/tracing-subscriber-0.3.3/benches/fmt.rs b/vendor/tracing-subscriber-0.3.3/benches/fmt.rs new file mode 100644 index 000000000..a039e66d4 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/benches/fmt.rs @@ -0,0 +1,331 @@ +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use std::{io, time::Duration}; + +mod support; +use support::MultithreadedBench; + +/// A fake writer that doesn't actually do anything. +/// +/// We want to measure the subscriber's overhead, *not* the performance of +/// stdout/file writers. Using a no-op Write implementation lets us only measure +/// the subscriber's overhead. +struct NoWriter; + +impl io::Write for NoWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl NoWriter { + fn new() -> Self { + Self + } +} + +fn bench_new_span(c: &mut Criterion) { + bench_thrpt(c, "new_span", |group, i| { + group.bench_with_input(BenchmarkId::new("single_thread", i), i, |b, &i| { + tracing::dispatcher::with_default(&mk_dispatch(), || { + b.iter(|| { + for n in 0..i { + let _span = tracing::info_span!("span", n); + } + }) + }); + }); + group.bench_with_input(BenchmarkId::new("multithreaded", i), i, |b, &i| { + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + let dispatch = mk_dispatch(); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(move || { + for n in 0..i { + let _span = tracing::info_span!("span", n); + } + }) + .thread(move || { + for n in 0..i { + let _span = tracing::info_span!("span", n); + } + }) + .thread(move || { + for n in 0..i { + let _span = tracing::info_span!("span", n); + } + }) + .thread(move || { + for n in 0..i { + let _span = tracing::info_span!("span", n); + } + }) + .run(); + total += elapsed; + } + total + }) + }); + }); +} + +type Group<'a> = criterion::BenchmarkGroup<'a, criterion::measurement::WallTime>; +fn bench_thrpt(c: &mut Criterion, name: &'static str, mut f: impl FnMut(&mut Group<'_>, &usize)) { + const N_SPANS: &[usize] = &[1, 10, 50]; + + let mut group = c.benchmark_group(name); + for spans in N_SPANS { + group.throughput(Throughput::Elements(*spans as u64)); + f(&mut group, spans); + } + group.finish(); +} + +fn mk_dispatch() -> tracing::Dispatch { + let subscriber = tracing_subscriber::FmtSubscriber::builder() + .with_writer(NoWriter::new) + .finish(); + tracing::Dispatch::new(subscriber) +} + +fn bench_event(c: &mut Criterion) { + bench_thrpt(c, "event", |group, i| { + group.bench_with_input(BenchmarkId::new("root/single_threaded", i), i, |b, &i| { + let dispatch = mk_dispatch(); + tracing::dispatcher::with_default(&dispatch, || { + b.iter(|| { + for n in 0..i { + tracing::info!(n); + } + }) + }); + }); + group.bench_with_input(BenchmarkId::new("root/multithreaded", i), i, |b, &i| { + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + let dispatch = mk_dispatch(); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread(move || { + for n in 0..i { + tracing::info!(n); + } + }) + .thread(move || { + for n in 0..i { + tracing::info!(n); + } + }) + .thread(move || { + for n in 0..i { + tracing::info!(n); + } + }) + .thread(move || { + for n in 0..i { + tracing::info!(n); + } + }) + .run(); + total += elapsed; + } + total + }) + }); + group.bench_with_input( + BenchmarkId::new("unique_parent/single_threaded", i), + i, + |b, &i| { + tracing::dispatcher::with_default(&mk_dispatch(), || { + let span = tracing::info_span!("unique_parent", foo = false); + let _guard = span.enter(); + b.iter(|| { + for n in 0..i { + tracing::info!(n); + } + }) + }); + }, + ); + group.bench_with_input( + BenchmarkId::new("unique_parent/multithreaded", i), + i, + |b, &i| { + b.iter_custom(|iters| { + let mut total = Duration::from_secs(0); + let dispatch = mk_dispatch(); + for _ in 0..iters { + let bench = MultithreadedBench::new(dispatch.clone()); + let elapsed = bench + .thread_with_setup(move |start| { + let span = tracing::info_span!("unique_parent", foo = false); + let _guard = span.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }) + .thread_with_setup(move |start| { + let span = tracing::info_span!("unique_parent", foo = false); + let _guard = span.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }) + .thread_with_setup(move |start| { + let span = tracing::info_span!("unique_parent", foo = false); + let _guard = span.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }) + .thread_with_setup(move |start| { + let span = tracing::info_span!("unique_parent", foo = false); + let _guard = span.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }) + .run(); + total += elapsed; + } + total + }) + }, + ); + group.bench_with_input( + BenchmarkId::new("shared_parent/multithreaded", i), + i, + |b, &i| { + b.iter_custom(|iters| { + let dispatch = mk_dispatch(); + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let parent = tracing::dispatcher::with_default(&dispatch, || { + tracing::info_span!("shared_parent", foo = "hello world") + }); + let bench = MultithreadedBench::new(dispatch.clone()); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + for n in 0..i { + tracing::info!(n); + } + }); + let elapsed = bench.run(); + total += elapsed; + } + total + }) + }, + ); + group.bench_with_input( + BenchmarkId::new("multi-parent/multithreaded", i), + i, + |b, &i| { + b.iter_custom(|iters| { + let dispatch = mk_dispatch(); + let mut total = Duration::from_secs(0); + for _ in 0..iters { + let parent = tracing::dispatcher::with_default(&dispatch, || { + tracing::info_span!("multiparent", foo = "hello world") + }); + let bench = MultithreadedBench::new(dispatch.clone()); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + let mut span = tracing::info_span!("parent"); + for n in 0..i { + let s = tracing::info_span!(parent: &span, "parent2", n, i); + s.in_scope(|| { + tracing::info!(n); + }); + span = s; + } + }); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + let mut span = tracing::info_span!("parent"); + for n in 0..i { + let s = tracing::info_span!(parent: &span, "parent2", n, i); + s.in_scope(|| { + tracing::info!(n); + }); + span = s; + } + }); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + let mut span = tracing::info_span!("parent"); + for n in 0..i { + let s = tracing::info_span!(parent: &span, "parent2", n, i); + s.in_scope(|| { + tracing::info!(n); + }); + span = s; + } + }); + let parent2 = parent.clone(); + bench.thread_with_setup(move |start| { + let _guard = parent2.enter(); + start.wait(); + let mut span = tracing::info_span!("parent"); + for n in 0..i { + let s = tracing::info_span!(parent: &span, "parent2", n, i); + s.in_scope(|| { + tracing::info!(n); + }); + span = s; + } + }); + let elapsed = bench.run(); + total += elapsed; + } + total + }) + }, + ); + }); +} + +criterion_group!(benches, bench_new_span, bench_event); +criterion_main!(benches); diff --git a/vendor/tracing-subscriber-0.3.3/benches/support/mod.rs b/vendor/tracing-subscriber-0.3.3/benches/support/mod.rs new file mode 100644 index 000000000..25e9e7e22 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/benches/support/mod.rs @@ -0,0 +1,49 @@ +use std::{ + sync::{Arc, Barrier}, + thread, + time::{Duration, Instant}, +}; +use tracing::dispatcher::Dispatch; + +#[derive(Clone)] +pub(super) struct MultithreadedBench { + start: Arc, + end: Arc, + dispatch: Dispatch, +} + +impl MultithreadedBench { + pub(super) fn new(dispatch: Dispatch) -> Self { + Self { + start: Arc::new(Barrier::new(5)), + end: Arc::new(Barrier::new(5)), + dispatch, + } + } + + pub(super) fn thread(&self, f: impl FnOnce() + Send + 'static) -> &Self { + self.thread_with_setup(|start| { + start.wait(); + f() + }) + } + + pub(super) fn thread_with_setup(&self, f: impl FnOnce(&Barrier) + Send + 'static) -> &Self { + let this = self.clone(); + thread::spawn(move || { + let dispatch = this.dispatch.clone(); + tracing::dispatcher::with_default(&dispatch, move || { + f(&*this.start); + this.end.wait(); + }) + }); + self + } + + pub(super) fn run(&self) -> Duration { + self.start.wait(); + let t0 = Instant::now(); + self.end.wait(); + t0.elapsed() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/field/debug.rs b/vendor/tracing-subscriber-0.3.3/src/field/debug.rs new file mode 100644 index 000000000..cc67d29fe --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/field/debug.rs @@ -0,0 +1,111 @@ +//! `MakeVisitor` wrappers for working with `fmt::Debug` fields. +use super::{MakeVisitor, VisitFmt, VisitOutput}; +use tracing_core::field::{Field, Visit}; + +use core::fmt; + +/// A visitor wrapper that ensures any `fmt::Debug` fields are formatted using +/// the alternate (`:#`) formatter. +#[derive(Debug, Clone)] +pub struct Alt(V); + +// TODO(eliza): When `error` as a primitive type is stable, add a +// `DisplayErrors` wrapper... + +// === impl Alt === +// +impl Alt { + /// Wraps the provided visitor so that any `fmt::Debug` fields are formatted + /// using the alternative (`:#`) formatter. + pub fn new(inner: V) -> Self { + Alt(inner) + } +} + +impl MakeVisitor for Alt +where + V: MakeVisitor, +{ + type Visitor = Alt; + + #[inline] + fn make_visitor(&self, target: T) -> Self::Visitor { + Alt(self.0.make_visitor(target)) + } +} + +impl Visit for Alt +where + V: Visit, +{ + #[inline] + fn record_f64(&mut self, field: &Field, value: f64) { + self.0.record_f64(field, value) + } + + #[inline] + fn record_i64(&mut self, field: &Field, value: i64) { + self.0.record_i64(field, value) + } + + #[inline] + fn record_u64(&mut self, field: &Field, value: u64) { + self.0.record_u64(field, value) + } + + #[inline] + fn record_bool(&mut self, field: &Field, value: bool) { + self.0.record_bool(field, value) + } + + /// Visit a string value. + fn record_str(&mut self, field: &Field, value: &str) { + self.0.record_str(field, value) + } + + // TODO(eliza): add RecordError when stable + // fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { + // self.record_debug(field, &format_args!("{}", value)) + // } + + #[inline] + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + self.0.record_debug(field, &format_args!("{:#?}", value)) + } +} + +impl VisitOutput for Alt +where + V: VisitOutput, +{ + #[inline] + fn finish(self) -> O { + self.0.finish() + } +} + +feature! { + #![feature = "std"] + use super::VisitWrite; + use std::io; + + impl VisitWrite for Alt + where + V: VisitWrite, + { + #[inline] + fn writer(&mut self) -> &mut dyn io::Write { + self.0.writer() + } + } +} + +impl VisitFmt for Alt +where + V: VisitFmt, +{ + #[inline] + fn writer(&mut self) -> &mut dyn fmt::Write { + self.0.writer() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/field/delimited.rs b/vendor/tracing-subscriber-0.3.3/src/field/delimited.rs new file mode 100644 index 000000000..8c78c4b20 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/field/delimited.rs @@ -0,0 +1,184 @@ +//! A `MakeVisitor` wrapper that separates formatted fields with a delimiter. +use super::{MakeVisitor, VisitFmt, VisitOutput}; + +use core::fmt; +use tracing_core::field::{Field, Visit}; + +/// A `MakeVisitor` wrapper that wraps a visitor that writes formatted output so +/// that a delimiter is inserted between writing formatted field values. +#[derive(Debug, Clone)] +pub struct Delimited { + delimiter: D, + inner: V, +} + +/// A visitor wrapper that inserts a delimiter after the wrapped visitor formats +/// a field value. +#[derive(Debug)] +pub struct VisitDelimited { + delimiter: D, + seen: bool, + inner: V, + err: fmt::Result, +} + +// === impl Delimited === + +impl MakeVisitor for Delimited +where + D: AsRef + Clone, + V: MakeVisitor, + V::Visitor: VisitFmt, +{ + type Visitor = VisitDelimited; + fn make_visitor(&self, target: T) -> Self::Visitor { + let inner = self.inner.make_visitor(target); + VisitDelimited::new(self.delimiter.clone(), inner) + } +} + +impl Delimited { + /// Returns a new [`MakeVisitor`] implementation that wraps `inner` so that + /// it will format each visited field separated by the provided `delimiter`. + /// + /// [`MakeVisitor`]: ../trait.MakeVisitor.html + pub fn new(delimiter: D, inner: V) -> Self { + Self { delimiter, inner } + } +} + +// === impl VisitDelimited === + +impl VisitDelimited { + /// Returns a new [`Visit`] implementation that wraps `inner` so that + /// each formatted field is separated by the provided `delimiter`. + /// + /// [`Visit`]: https://docs.rs/tracing-core/0.1.6/tracing_core/field/trait.Visit.html + pub fn new(delimiter: D, inner: V) -> Self { + Self { + delimiter, + inner, + seen: false, + err: Ok(()), + } + } + + fn delimit(&mut self) + where + V: VisitFmt, + D: AsRef, + { + if self.err.is_err() { + return; + } + + if self.seen { + self.err = self.inner.writer().write_str(self.delimiter.as_ref()); + } + + self.seen = true; + } +} + +impl Visit for VisitDelimited +where + V: VisitFmt, + D: AsRef, +{ + fn record_i64(&mut self, field: &Field, value: i64) { + self.delimit(); + self.inner.record_i64(field, value); + } + + fn record_u64(&mut self, field: &Field, value: u64) { + self.delimit(); + self.inner.record_u64(field, value); + } + + fn record_bool(&mut self, field: &Field, value: bool) { + self.delimit(); + self.inner.record_bool(field, value); + } + + fn record_str(&mut self, field: &Field, value: &str) { + self.delimit(); + self.inner.record_str(field, value); + } + + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + self.delimit(); + self.inner.record_debug(field, value); + } +} + +impl VisitOutput for VisitDelimited +where + V: VisitFmt, + D: AsRef, +{ + fn finish(self) -> fmt::Result { + self.err?; + self.inner.finish() + } +} + +impl VisitFmt for VisitDelimited +where + V: VisitFmt, + D: AsRef, +{ + fn writer(&mut self) -> &mut dyn fmt::Write { + self.inner.writer() + } +} + +#[cfg(test)] +#[cfg(all(test, feature = "alloc"))] +mod test { + use super::*; + use crate::field::test_util::*; + + #[test] + fn delimited_visitor() { + let mut s = String::new(); + let visitor = DebugVisitor::new(&mut s); + let mut visitor = VisitDelimited::new(", ", visitor); + + TestAttrs1::with(|attrs| attrs.record(&mut visitor)); + visitor.finish().unwrap(); + + assert_eq!( + s.as_str(), + "question=\"life, the universe, and everything\", tricky=true, can_you_do_it=true" + ); + } + + #[test] + fn delimited_new_visitor() { + let make = Delimited::new("; ", MakeDebug); + + TestAttrs1::with(|attrs| { + let mut s = String::new(); + { + let mut v = make.make_visitor(&mut s); + attrs.record(&mut v); + } + assert_eq!( + s.as_str(), + "question=\"life, the universe, and everything\"; tricky=true; can_you_do_it=true" + ); + }); + + TestAttrs2::with(|attrs| { + let mut s = String::new(); + { + let mut v = make.make_visitor(&mut s); + attrs.record(&mut v); + } + assert_eq!( + s.as_str(), + "question=None; question.answer=42; tricky=true; can_you_do_it=false" + ); + }); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/field/display.rs b/vendor/tracing-subscriber-0.3.3/src/field/display.rs new file mode 100644 index 000000000..e0bbc55ed --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/field/display.rs @@ -0,0 +1,117 @@ +//! `MakeVisitor` wrappers for working with `fmt::Display` fields. +use super::{MakeVisitor, VisitFmt, VisitOutput}; +use tracing_core::field::{Field, Visit}; + +use core::fmt; + +/// A visitor wrapper that ensures any strings named "message" are formatted +/// using `fmt::Display` +#[derive(Debug, Clone)] +pub struct Messages(V); + +// TODO(eliza): When `error` as a primitive type is stable, add a +// `DisplayErrors` wrapper... + +// === impl Messages === +// +impl Messages { + /// Returns a new [`MakeVisitor`] implementation that will wrap `inner` so + /// that any strings named `message` are formatted using `fmt::Display`. + /// + /// [`MakeVisitor`]: ../trait.MakeVisitor.html + pub fn new(inner: V) -> Self { + Messages(inner) + } +} + +impl MakeVisitor for Messages +where + V: MakeVisitor, +{ + type Visitor = Messages; + + #[inline] + fn make_visitor(&self, target: T) -> Self::Visitor { + Messages(self.0.make_visitor(target)) + } +} + +impl Visit for Messages +where + V: Visit, +{ + #[inline] + fn record_f64(&mut self, field: &Field, value: f64) { + self.0.record_f64(field, value) + } + + #[inline] + fn record_i64(&mut self, field: &Field, value: i64) { + self.0.record_i64(field, value) + } + + #[inline] + fn record_u64(&mut self, field: &Field, value: u64) { + self.0.record_u64(field, value) + } + + #[inline] + fn record_bool(&mut self, field: &Field, value: bool) { + self.0.record_bool(field, value) + } + + /// Visit a string value. + fn record_str(&mut self, field: &Field, value: &str) { + if field.name() == "message" { + self.0.record_debug(field, &format_args!("{}", value)) + } else { + self.0.record_str(field, value) + } + } + + // TODO(eliza): add RecordError when stable + // fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { + // self.record_debug(field, &format_args!("{}", value)) + // } + + #[inline] + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + self.0.record_debug(field, value) + } +} + +impl VisitOutput for Messages +where + V: VisitOutput, +{ + #[inline] + fn finish(self) -> O { + self.0.finish() + } +} + +feature! { + #![feature = "std"] + use super::VisitWrite; + use std::io; + + impl VisitWrite for Messages + where + V: VisitWrite, + { + #[inline] + fn writer(&mut self) -> &mut dyn io::Write { + self.0.writer() + } + } +} + +impl VisitFmt for Messages +where + V: VisitFmt, +{ + #[inline] + fn writer(&mut self) -> &mut dyn fmt::Write { + self.0.writer() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/field/mod.rs b/vendor/tracing-subscriber-0.3.3/src/field/mod.rs new file mode 100644 index 000000000..f7d03f2cc --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/field/mod.rs @@ -0,0 +1,366 @@ +//! Utilities for working with [fields] and [field visitors]. +//! +//! [fields]: tracing_core::field +//! [field visitors]: tracing_core::field::Visit +use core::{fmt, marker::PhantomData}; +pub use tracing_core::field::Visit; +use tracing_core::{ + span::{Attributes, Record}, + Event, +}; +pub mod debug; +pub mod delimited; +pub mod display; + +/// Creates new [visitors]. +/// +/// A type implementing `MakeVisitor` represents a composable factory for types +/// implementing the [`Visit` trait][visitors]. The `MakeVisitor` trait defines +/// a single function, `make_visitor`, which takes in a `T`-typed `target` and +/// returns a type implementing `Visit` configured for that target. A target may +/// be a string, output stream, or data structure that the visitor will record +/// data to, configuration variables that determine the visitor's behavior, or +/// `()` when no input is required to produce a visitor. +/// +/// [visitors]: https://docs.rs/tracing-core/latest/tracing_core/field/trait.Visit.html +pub trait MakeVisitor { + /// The visitor type produced by this `MakeVisitor`. + type Visitor: Visit; + + /// Make a new visitor for the provided `target`. + fn make_visitor(&self, target: T) -> Self::Visitor; +} + +/// A [visitor] that produces output once it has visited a set of fields. +/// +/// [visitor]: https://docs.rs/tracing-core/latest/tracing_core/field/trait.Visit.html +pub trait VisitOutput: Visit { + /// Completes the visitor, returning any output. + /// + /// This is called once a full set of fields has been visited. + fn finish(self) -> Out; + + /// Visit a set of fields, and return the output of finishing the visitor + /// once the fields have been visited. + fn visit(mut self, fields: &R) -> Out + where + R: RecordFields, + Self: Sized, + { + fields.record(&mut self); + self.finish() + } +} + +/// Extension trait implemented by types which can be recorded by a [visitor]. +/// +/// This allows writing code that is generic over `tracing_core`'s +/// [`span::Attributes`][attr], [`span::Record`][rec], and [`Event`][event] +/// types. These types all provide inherent `record` methods that allow a +/// visitor to record their fields, but there is no common trait representing this. +/// +/// With `RecordFields`, we can write code like this: +/// ``` +/// use tracing_core::field::Visit; +/// # use tracing_core::field::Field; +/// use tracing_subscriber::field::RecordFields; +/// +/// struct MyVisitor { +/// // ... +/// } +/// # impl MyVisitor { fn new() -> Self { Self{} } } +/// impl Visit for MyVisitor { +/// // ... +/// # fn record_debug(&mut self, _: &Field, _: &dyn std::fmt::Debug) {} +/// } +/// +/// fn record_with_my_visitor(r: R) +/// where +/// R: RecordFields, +/// { +/// let mut visitor = MyVisitor::new(); +/// r.record(&mut visitor); +/// } +/// ``` +/// [visitor]: https://docs.rs/tracing-core/latest/tracing_core/field/trait.Visit.html +/// [attr]: https://docs.rs/tracing-core/latest/tracing_core/span/struct.Attributes.html +/// [rec]: https://docs.rs/tracing-core/latest/tracing_core/span/struct.Record.html +/// [event]: https://docs.rs/tracing-core/latest/tracing_core/event/struct.Event.html +pub trait RecordFields: crate::sealed::Sealed { + /// Record all the fields in `self` with the provided `visitor`. + fn record(&self, visitor: &mut dyn Visit); +} + +/// Extension trait implemented for all `MakeVisitor` implementations that +/// produce a visitor implementing `VisitOutput`. +pub trait MakeOutput +where + Self: MakeVisitor + crate::sealed::Sealed<(T, Out)>, + Self::Visitor: VisitOutput, +{ + /// Visits all fields in `fields` with a new visitor constructed from + /// `target`. + fn visit_with(&self, target: T, fields: &F) -> Out + where + F: RecordFields, + { + self.make_visitor(target).visit(fields) + } +} + +feature! { + #![feature = "std"] + use std::io; + + /// Extension trait implemented by visitors to indicate that they write to an + /// `io::Write` instance, and allow access to that writer. + pub trait VisitWrite: VisitOutput> { + /// Returns the writer that this visitor writes to. + fn writer(&mut self) -> &mut dyn io::Write; + } +} + +/// Extension trait implemented by visitors to indicate that they write to a +/// `fmt::Write` instance, and allow access to that writer. +pub trait VisitFmt: VisitOutput { + /// Returns the formatter that this visitor writes to. + fn writer(&mut self) -> &mut dyn fmt::Write; +} + +/// Extension trait providing `MakeVisitor` combinators. +pub trait MakeExt +where + Self: MakeVisitor + Sized, + Self: crate::sealed::Sealed>, +{ + /// Wraps `self` so that any `fmt::Debug` fields are recorded using the + /// alternate formatter (`{:#?}`). + fn debug_alt(self) -> debug::Alt { + debug::Alt::new(self) + } + + /// Wraps `self` so that any string fields named "message" are recorded + /// using `fmt::Display`. + fn display_messages(self) -> display::Messages { + display::Messages::new(self) + } + + /// Wraps `self` so that when fields are formatted to a writer, they are + /// separated by the provided `delimiter`. + fn delimited(self, delimiter: D) -> delimited::Delimited + where + D: AsRef + Clone, + Self::Visitor: VisitFmt, + { + delimited::Delimited::new(delimiter, self) + } +} + +// === impl RecordFields === + +impl<'a> crate::sealed::Sealed for Event<'a> {} +impl<'a> RecordFields for Event<'a> { + fn record(&self, visitor: &mut dyn Visit) { + Event::record(self, visitor) + } +} + +impl<'a> crate::sealed::Sealed for Attributes<'a> {} +impl<'a> RecordFields for Attributes<'a> { + fn record(&self, visitor: &mut dyn Visit) { + Attributes::record(self, visitor) + } +} + +impl<'a> crate::sealed::Sealed for Record<'a> {} +impl<'a> RecordFields for Record<'a> { + fn record(&self, visitor: &mut dyn Visit) { + Record::record(self, visitor) + } +} + +impl<'a, F> crate::sealed::Sealed for &'a F where F: RecordFields {} +impl<'a, F> RecordFields for &'a F +where + F: RecordFields, +{ + fn record(&self, visitor: &mut dyn Visit) { + F::record(*self, visitor) + } +} + +// === blanket impls === + +impl MakeVisitor for F +where + F: Fn(T) -> V, + V: Visit, +{ + type Visitor = V; + fn make_visitor(&self, target: T) -> Self::Visitor { + (self)(target) + } +} + +impl crate::sealed::Sealed<(T, Out)> for M +where + M: MakeVisitor, + M::Visitor: VisitOutput, +{ +} + +impl MakeOutput for M +where + M: MakeVisitor, + M::Visitor: VisitOutput, +{ +} + +impl crate::sealed::Sealed> for M where M: MakeVisitor + Sized {} + +impl MakeExt for M +where + M: MakeVisitor + Sized, + M: crate::sealed::Sealed>, +{ +} + +#[derive(Debug)] +#[doc(hidden)] +pub struct MakeExtMarker { + _p: PhantomData, +} + +#[derive(Debug)] +#[doc(hidden)] +pub struct RecordFieldsMarker { + _p: (), +} + +#[cfg(all(test, feature = "alloc"))] +#[macro_use] +pub(in crate::field) mod test_util { + use super::*; + pub(in crate::field) use alloc::string::String; + use tracing_core::{ + callsite::Callsite, + field::{Field, Value}, + metadata::{Kind, Level, Metadata}, + }; + + pub(crate) struct TestAttrs1; + pub(crate) struct TestAttrs2; + + impl TestAttrs1 { + pub(crate) fn with(f: impl FnOnce(Attributes<'_>) -> T) -> T { + let fieldset = TEST_META_1.fields(); + let values = &[ + ( + &fieldset.field("question").unwrap(), + Some(&"life, the universe, and everything" as &dyn Value), + ), + (&fieldset.field("question.answer").unwrap(), None), + ( + &fieldset.field("tricky").unwrap(), + Some(&true as &dyn Value), + ), + ( + &fieldset.field("can_you_do_it").unwrap(), + Some(&true as &dyn Value), + ), + ]; + let valueset = fieldset.value_set(values); + let attrs = tracing_core::span::Attributes::new(&TEST_META_1, &valueset); + f(attrs) + } + } + + impl TestAttrs2 { + pub(crate) fn with(f: impl FnOnce(Attributes<'_>) -> T) -> T { + let fieldset = TEST_META_1.fields(); + let none = tracing_core::field::debug(&Option::<&str>::None); + let values = &[ + ( + &fieldset.field("question").unwrap(), + Some(&none as &dyn Value), + ), + ( + &fieldset.field("question.answer").unwrap(), + Some(&42 as &dyn Value), + ), + ( + &fieldset.field("tricky").unwrap(), + Some(&true as &dyn Value), + ), + ( + &fieldset.field("can_you_do_it").unwrap(), + Some(&false as &dyn Value), + ), + ]; + let valueset = fieldset.value_set(values); + let attrs = tracing_core::span::Attributes::new(&TEST_META_1, &valueset); + f(attrs) + } + } + + struct TestCallsite1; + static TEST_CALLSITE_1: &'static dyn Callsite = &TestCallsite1; + static TEST_META_1: Metadata<'static> = tracing_core::metadata! { + name: "field_test1", + target: module_path!(), + level: Level::INFO, + fields: &["question", "question.answer", "tricky", "can_you_do_it"], + callsite: TEST_CALLSITE_1, + kind: Kind::SPAN, + }; + + impl Callsite for TestCallsite1 { + fn set_interest(&self, _: tracing_core::subscriber::Interest) { + unimplemented!() + } + + fn metadata(&self) -> &Metadata<'_> { + &TEST_META_1 + } + } + + pub(crate) struct MakeDebug; + pub(crate) struct DebugVisitor<'a> { + writer: &'a mut dyn fmt::Write, + err: fmt::Result, + } + + impl<'a> DebugVisitor<'a> { + pub(crate) fn new(writer: &'a mut dyn fmt::Write) -> Self { + Self { + writer, + err: Ok(()), + } + } + } + + impl<'a> Visit for DebugVisitor<'a> { + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + write!(&mut self.writer, "{}={:?}", field, value).unwrap(); + } + } + + impl<'a> VisitOutput for DebugVisitor<'a> { + fn finish(self) -> fmt::Result { + self.err + } + } + + impl<'a> VisitFmt for DebugVisitor<'a> { + fn writer(&mut self) -> &mut dyn fmt::Write { + self.writer + } + } + + impl<'a> MakeVisitor<&'a mut dyn fmt::Write> for MakeDebug { + type Visitor = DebugVisitor<'a>; + fn make_visitor(&self, w: &'a mut dyn fmt::Write) -> DebugVisitor<'a> { + DebugVisitor::new(w) + } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/directive.rs b/vendor/tracing-subscriber-0.3.3/src/filter/directive.rs new file mode 100644 index 000000000..dd6b063c4 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/directive.rs @@ -0,0 +1,424 @@ +use crate::filter::level::{self, LevelFilter}; +#[cfg(not(feature = "smallvec"))] +use alloc::vec; +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec::Vec}; + +use core::{cmp::Ordering, fmt, iter::FromIterator, slice, str::FromStr}; +use tracing_core::Metadata; +/// Indicates that a string could not be parsed as a filtering directive. +#[derive(Debug)] +pub struct ParseError { + kind: ParseErrorKind, +} + +/// A directive which will statically enable or disable a given callsite. +/// +/// Unlike a dynamic directive, this can be cached by the callsite. +#[derive(Debug, PartialEq, Eq, Clone)] +pub(crate) struct StaticDirective { + pub(in crate::filter) target: Option, + pub(in crate::filter) field_names: Vec, + pub(in crate::filter) level: LevelFilter, +} + +#[cfg(feature = "smallvec")] +pub(crate) type FilterVec = smallvec::SmallVec<[T; 8]>; +#[cfg(not(feature = "smallvec"))] +pub(crate) type FilterVec = Vec; + +#[derive(Debug, PartialEq, Clone)] +pub(in crate::filter) struct DirectiveSet { + directives: FilterVec, + pub(in crate::filter) max_level: LevelFilter, +} + +pub(in crate::filter) trait Match { + fn cares_about(&self, meta: &Metadata<'_>) -> bool; + fn level(&self) -> &LevelFilter; +} + +#[derive(Debug)] +enum ParseErrorKind { + #[cfg(feature = "std")] + Field(Box), + Level(level::ParseError), + Other(Option<&'static str>), +} + +// === impl DirectiveSet === + +impl DirectiveSet { + #[cfg(feature = "env-filter")] + pub(crate) fn is_empty(&self) -> bool { + self.directives.is_empty() + } + + pub(crate) fn iter(&self) -> slice::Iter<'_, T> { + self.directives.iter() + } +} + +impl Default for DirectiveSet { + fn default() -> Self { + Self { + directives: FilterVec::new(), + max_level: LevelFilter::OFF, + } + } +} + +impl DirectiveSet { + pub(crate) fn directives(&self) -> impl Iterator { + self.directives.iter() + } + + pub(crate) fn directives_for<'a>( + &'a self, + metadata: &'a Metadata<'a>, + ) -> impl Iterator + 'a { + self.directives().filter(move |d| d.cares_about(metadata)) + } + + pub(crate) fn add(&mut self, directive: T) { + // does this directive enable a more verbose level than the current + // max? if so, update the max level. + let level = *directive.level(); + if level > self.max_level { + self.max_level = level; + } + // insert the directive into the vec of directives, ordered by + // specificity (length of target + number of field filters). this + // ensures that, when finding a directive to match a span or event, we + // search the directive set in most specific first order. + match self.directives.binary_search(&directive) { + Ok(i) => self.directives[i] = directive, + Err(i) => self.directives.insert(i, directive), + } + } + + #[cfg(test)] + pub(in crate::filter) fn into_vec(self) -> FilterVec { + self.directives + } +} + +impl FromIterator for DirectiveSet { + fn from_iter>(iter: I) -> Self { + let mut this = Self::default(); + this.extend(iter); + this + } +} + +impl Extend for DirectiveSet { + fn extend>(&mut self, iter: I) { + for directive in iter.into_iter() { + self.add(directive); + } + } +} + +impl IntoIterator for DirectiveSet { + type Item = T; + + #[cfg(feature = "smallvec")] + type IntoIter = smallvec::IntoIter<[T; 8]>; + #[cfg(not(feature = "smallvec"))] + type IntoIter = vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.directives.into_iter() + } +} + +// === impl Statics === + +impl DirectiveSet { + pub(crate) fn enabled(&self, meta: &Metadata<'_>) -> bool { + let level = meta.level(); + match self.directives_for(meta).next() { + Some(d) => d.level >= *level, + None => false, + } + } +} + +// === impl StaticDirective === + +impl StaticDirective { + pub(in crate::filter) fn new( + target: Option, + field_names: Vec, + level: LevelFilter, + ) -> Self { + Self { + target, + field_names, + level, + } + } +} + +impl Ord for StaticDirective { + fn cmp(&self, other: &StaticDirective) -> Ordering { + // We attempt to order directives by how "specific" they are. This + // ensures that we try the most specific directives first when + // attempting to match a piece of metadata. + + // First, we compare based on whether a target is specified, and the + // lengths of those targets if both have targets. + let ordering = self + .target + .as_ref() + .map(String::len) + .cmp(&other.target.as_ref().map(String::len)) + // Then we compare how many field names are matched by each directive. + .then_with(|| self.field_names.len().cmp(&other.field_names.len())) + // Finally, we fall back to lexicographical ordering if the directives are + // equally specific. Although this is no longer semantically important, + // we need to define a total ordering to determine the directive's place + // in the BTreeMap. + .then_with(|| { + self.target + .cmp(&other.target) + .then_with(|| self.field_names[..].cmp(&other.field_names[..])) + }) + .reverse(); + + #[cfg(debug_assertions)] + { + if ordering == Ordering::Equal { + debug_assert_eq!( + self.target, other.target, + "invariant violated: Ordering::Equal must imply a.target == b.target" + ); + debug_assert_eq!( + self.field_names, other.field_names, + "invariant violated: Ordering::Equal must imply a.field_names == b.field_names" + ); + } + } + + ordering + } +} + +impl PartialOrd for StaticDirective { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Match for StaticDirective { + fn cares_about(&self, meta: &Metadata<'_>) -> bool { + // Does this directive have a target filter, and does it match the + // metadata's target? + if let Some(ref target) = self.target { + if !meta.target().starts_with(&target[..]) { + return false; + } + } + + if meta.is_event() && !self.field_names.is_empty() { + let fields = meta.fields(); + for name in &self.field_names { + if fields.field(name).is_none() { + return false; + } + } + } + + true + } + + fn level(&self) -> &LevelFilter { + &self.level + } +} + +impl Default for StaticDirective { + fn default() -> Self { + StaticDirective { + target: None, + field_names: Vec::new(), + level: LevelFilter::ERROR, + } + } +} + +impl fmt::Display for StaticDirective { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut wrote_any = false; + if let Some(ref target) = self.target { + fmt::Display::fmt(target, f)?; + wrote_any = true; + } + + if !self.field_names.is_empty() { + f.write_str("[")?; + + let mut fields = self.field_names.iter(); + if let Some(field) = fields.next() { + write!(f, "{{{}", field)?; + for field in fields { + write!(f, ",{}", field)?; + } + f.write_str("}")?; + } + + f.write_str("]")?; + wrote_any = true; + } + + if wrote_any { + f.write_str("=")?; + } + + fmt::Display::fmt(&self.level, f) + } +} + +impl FromStr for StaticDirective { + type Err = ParseError; + + fn from_str(s: &str) -> Result { + // This method parses a filtering directive in one of the following + // forms: + // + // * `foo=trace` (TARGET=LEVEL) + // * `foo[{bar,baz}]=info` (TARGET[{FIELD,+}]=LEVEL) + // * `trace` (bare LEVEL) + // * `foo` (bare TARGET) + let mut split = s.split('='); + let part0 = split + .next() + .ok_or_else(|| ParseError::msg("string must not be empty"))?; + + // Directive includes an `=`: + // * `foo=trace` + // * `foo[{bar}]=trace` + // * `foo[{bar,baz}]=trace` + if let Some(part1) = split.next() { + if split.next().is_some() { + return Err(ParseError::msg( + "too many '=' in filter directive, expected 0 or 1", + )); + } + + let mut split = part0.split("[{"); + let target = split.next().map(String::from); + let mut field_names = Vec::new(); + // Directive includes fields: + // * `foo[{bar}]=trace` + // * `foo[{bar,baz}]=trace` + if let Some(maybe_fields) = split.next() { + if split.next().is_some() { + return Err(ParseError::msg( + "too many '[{' in filter directive, expected 0 or 1", + )); + } + + if !maybe_fields.ends_with("}]") { + return Err(ParseError::msg("expected fields list to end with '}]'")); + } + + let fields = maybe_fields + .trim_end_matches("}]") + .split(',') + .filter_map(|s| { + if s.is_empty() { + None + } else { + Some(String::from(s)) + } + }); + field_names.extend(fields); + }; + let level = part1.parse()?; + return Ok(Self { + level, + field_names, + target, + }); + } + + // Okay, the part after the `=` was empty, the directive is either a + // bare level or a bare target. + // * `foo` + // * `info` + Ok(match part0.parse::() { + Ok(level) => Self { + level, + target: None, + field_names: Vec::new(), + }, + Err(_) => Self { + target: Some(String::from(part0)), + level: LevelFilter::TRACE, + field_names: Vec::new(), + }, + }) + } +} + +// === impl ParseError === + +impl ParseError { + #[cfg(feature = "env-filter")] + pub(crate) fn new() -> Self { + ParseError { + kind: ParseErrorKind::Other(None), + } + } + + pub(crate) fn msg(s: &'static str) -> Self { + ParseError { + kind: ParseErrorKind::Other(Some(s)), + } + } +} + +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.kind { + ParseErrorKind::Other(None) => f.pad("invalid filter directive"), + ParseErrorKind::Other(Some(msg)) => write!(f, "invalid filter directive: {}", msg), + ParseErrorKind::Level(ref l) => l.fmt(f), + #[cfg(feature = "std")] + ParseErrorKind::Field(ref e) => write!(f, "invalid field filter: {}", e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ParseError { + fn description(&self) -> &str { + "invalid filter directive" + } + + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self.kind { + ParseErrorKind::Other(_) => None, + ParseErrorKind::Level(ref l) => Some(l), + ParseErrorKind::Field(ref n) => Some(n.as_ref()), + } + } +} + +#[cfg(feature = "std")] +impl From> for ParseError { + fn from(e: Box) -> Self { + Self { + kind: ParseErrorKind::Field(e), + } + } +} + +impl From for ParseError { + fn from(l: level::ParseError) -> Self { + Self { + kind: ParseErrorKind::Level(l), + } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/env/directive.rs b/vendor/tracing-subscriber-0.3.3/src/filter/env/directive.rs new file mode 100644 index 000000000..66ca23dc4 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/env/directive.rs @@ -0,0 +1,846 @@ +pub(crate) use crate::filter::directive::{FilterVec, ParseError, StaticDirective}; +use crate::filter::{ + directive::{DirectiveSet, Match}, + env::{field, FieldMap}, + level::LevelFilter, +}; +use lazy_static::lazy_static; +use regex::Regex; +use std::{cmp::Ordering, fmt, iter::FromIterator, str::FromStr}; +use tracing_core::{span, Level, Metadata}; + +/// A single filtering directive. +// TODO(eliza): add a builder for programmatically constructing directives? +#[derive(Debug, Eq, PartialEq)] +#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] +pub struct Directive { + in_span: Option, + fields: Vec, + pub(crate) target: Option, + pub(crate) level: LevelFilter, +} + +/// A set of dynamic filtering directives. +pub(super) type Dynamics = DirectiveSet; + +/// A set of static filtering directives. +pub(super) type Statics = DirectiveSet; + +pub(crate) type CallsiteMatcher = MatchSet; +pub(crate) type SpanMatcher = MatchSet; + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct MatchSet { + field_matches: FilterVec, + base_level: LevelFilter, +} + +impl Directive { + pub(super) fn has_name(&self) -> bool { + self.in_span.is_some() + } + + pub(super) fn has_fields(&self) -> bool { + !self.fields.is_empty() + } + + pub(super) fn to_static(&self) -> Option { + if !self.is_static() { + return None; + } + + // TODO(eliza): these strings are all immutable; we should consider + // `Arc`ing them to make this more efficient... + let field_names = self.fields.iter().map(field::Match::name).collect(); + + Some(StaticDirective::new( + self.target.clone(), + field_names, + self.level, + )) + } + + fn is_static(&self) -> bool { + !self.has_name() && !self.fields.iter().any(field::Match::has_value) + } + + pub(super) fn is_dynamic(&self) -> bool { + self.has_name() || self.has_fields() + } + + pub(crate) fn field_matcher(&self, meta: &Metadata<'_>) -> Option { + let fieldset = meta.fields(); + let fields = self + .fields + .iter() + .filter_map( + |field::Match { + ref name, + ref value, + }| { + if let Some(field) = fieldset.field(name) { + let value = value.as_ref().cloned()?; + Some(Ok((field, value))) + } else { + Some(Err(())) + } + }, + ) + .collect::, ()>>() + .ok()?; + Some(field::CallsiteMatch { + fields, + level: self.level, + }) + } + + pub(super) fn make_tables( + directives: impl IntoIterator, + ) -> (Dynamics, Statics) { + // TODO(eliza): this could be made more efficient... + let (dyns, stats): (Vec, Vec) = + directives.into_iter().partition(Directive::is_dynamic); + let statics = stats + .into_iter() + .filter_map(|d| d.to_static()) + .chain(dyns.iter().filter_map(Directive::to_static)) + .collect(); + (Dynamics::from_iter(dyns), statics) + } +} + +impl Match for Directive { + fn cares_about(&self, meta: &Metadata<'_>) -> bool { + // Does this directive have a target filter, and does it match the + // metadata's target? + if let Some(ref target) = self.target { + if !meta.target().starts_with(&target[..]) { + return false; + } + } + + // Do we have a name filter, and does it match the metadata's name? + // TODO(eliza): put name globbing here? + if let Some(ref name) = self.in_span { + if name != meta.name() { + return false; + } + } + + // Does the metadata define all the fields that this directive cares about? + let fields = meta.fields(); + for field in &self.fields { + if fields.field(&field.name).is_none() { + return false; + } + } + + true + } + + fn level(&self) -> &LevelFilter { + &self.level + } +} + +impl FromStr for Directive { + type Err = ParseError; + fn from_str(from: &str) -> Result { + lazy_static! { + static ref DIRECTIVE_RE: Regex = Regex::new( + r"(?x) + ^(?P(?i:trace|debug|info|warn|error|off|[0-5]))$ | + # ^^^. + # `note: we match log level names case-insensitively + ^ + (?: # target name or span name + (?P[\w:-]+)|(?P\[[^\]]*\]) + ){1,2} + (?: # level or nothing + =(?P(?i:trace|debug|info|warn|error|off|[0-5]))? + # ^^^. + # `note: we match log level names case-insensitively + )? + $ + " + ) + .unwrap(); + static ref SPAN_PART_RE: Regex = + Regex::new(r#"(?P[^\]\{]+)?(?:\{(?P[^\}]*)\})?"#).unwrap(); + static ref FIELD_FILTER_RE: Regex = + // TODO(eliza): this doesn't _currently_ handle value matchers that include comma + // characters. We should fix that. + Regex::new(r#"(?x) + ( + # field name + [[:word:]][[[:word:]]\.]* + # value part (optional) + (?:=[^,]+)? + ) + # trailing comma or EOS + (?:,\s?|$) + "#).unwrap(); + } + + let caps = DIRECTIVE_RE.captures(from).ok_or_else(ParseError::new)?; + + if let Some(level) = caps + .name("global_level") + .and_then(|s| s.as_str().parse().ok()) + { + return Ok(Directive { + level, + ..Default::default() + }); + } + + let target = caps.name("target").and_then(|c| { + let s = c.as_str(); + if s.parse::().is_ok() { + None + } else { + Some(s.to_owned()) + } + }); + + let (in_span, fields) = caps + .name("span") + .and_then(|cap| { + let cap = cap.as_str().trim_matches(|c| c == '[' || c == ']'); + let caps = SPAN_PART_RE.captures(cap)?; + let span = caps.name("name").map(|c| c.as_str().to_owned()); + let fields = caps + .name("fields") + .map(|c| { + FIELD_FILTER_RE + .find_iter(c.as_str()) + .map(|c| c.as_str().parse()) + .collect::, _>>() + }) + .unwrap_or_else(|| Ok(Vec::new())); + Some((span, fields)) + }) + .unwrap_or_else(|| (None, Ok(Vec::new()))); + + let level = caps + .name("level") + .and_then(|l| l.as_str().parse().ok()) + // Setting the target without the level enables every level for that target + .unwrap_or(LevelFilter::TRACE); + + Ok(Directive { + level, + target, + in_span, + fields: fields?, + }) + } +} + +impl Default for Directive { + fn default() -> Self { + Directive { + level: LevelFilter::OFF, + target: None, + in_span: None, + fields: Vec::new(), + } + } +} + +impl PartialOrd for Directive { + fn partial_cmp(&self, other: &Directive) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Directive { + fn cmp(&self, other: &Directive) -> Ordering { + // We attempt to order directives by how "specific" they are. This + // ensures that we try the most specific directives first when + // attempting to match a piece of metadata. + + // First, we compare based on whether a target is specified, and the + // lengths of those targets if both have targets. + let ordering = self + .target + .as_ref() + .map(String::len) + .cmp(&other.target.as_ref().map(String::len)) + // Next compare based on the presence of span names. + .then_with(|| self.in_span.is_some().cmp(&other.in_span.is_some())) + // Then we compare how many fields are defined by each + // directive. + .then_with(|| self.fields.len().cmp(&other.fields.len())) + // Finally, we fall back to lexicographical ordering if the directives are + // equally specific. Although this is no longer semantically important, + // we need to define a total ordering to determine the directive's place + // in the BTreeMap. + .then_with(|| { + self.target + .cmp(&other.target) + .then_with(|| self.in_span.cmp(&other.in_span)) + .then_with(|| self.fields[..].cmp(&other.fields[..])) + }) + .reverse(); + + #[cfg(debug_assertions)] + { + if ordering == Ordering::Equal { + debug_assert_eq!( + self.target, other.target, + "invariant violated: Ordering::Equal must imply a.target == b.target" + ); + debug_assert_eq!( + self.in_span, other.in_span, + "invariant violated: Ordering::Equal must imply a.in_span == b.in_span" + ); + debug_assert_eq!( + self.fields, other.fields, + "invariant violated: Ordering::Equal must imply a.fields == b.fields" + ); + } + } + + ordering + } +} + +impl fmt::Display for Directive { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut wrote_any = false; + if let Some(ref target) = self.target { + fmt::Display::fmt(target, f)?; + wrote_any = true; + } + + if self.in_span.is_some() || !self.fields.is_empty() { + f.write_str("[")?; + + if let Some(ref span) = self.in_span { + fmt::Display::fmt(span, f)?; + } + + let mut fields = self.fields.iter(); + if let Some(field) = fields.next() { + write!(f, "{{{}", field)?; + for field in fields { + write!(f, ",{}", field)?; + } + f.write_str("}")?; + } + + f.write_str("]")?; + wrote_any = true; + } + + if wrote_any { + f.write_str("=")?; + } + + fmt::Display::fmt(&self.level, f) + } +} + +impl From for Directive { + fn from(level: LevelFilter) -> Self { + Self { + level, + ..Self::default() + } + } +} + +impl From for Directive { + fn from(level: Level) -> Self { + LevelFilter::from_level(level).into() + } +} + +// === impl Dynamics === + +impl Dynamics { + pub(crate) fn matcher(&self, metadata: &Metadata<'_>) -> Option { + let mut base_level = None; + let field_matches = self + .directives_for(metadata) + .filter_map(|d| { + if let Some(f) = d.field_matcher(metadata) { + return Some(f); + } + match base_level { + Some(ref b) if d.level > *b => base_level = Some(d.level), + None => base_level = Some(d.level), + _ => {} + } + None + }) + .collect(); + + if let Some(base_level) = base_level { + Some(CallsiteMatcher { + field_matches, + base_level, + }) + } else if !field_matches.is_empty() { + Some(CallsiteMatcher { + field_matches, + base_level: base_level.unwrap_or(LevelFilter::OFF), + }) + } else { + None + } + } + + pub(crate) fn has_value_filters(&self) -> bool { + self.directives() + .any(|d| d.fields.iter().any(|f| f.value.is_some())) + } +} + +// ===== impl DynamicMatch ===== + +impl CallsiteMatcher { + /// Create a new `SpanMatch` for a given instance of the matched callsite. + pub(crate) fn to_span_match(&self, attrs: &span::Attributes<'_>) -> SpanMatcher { + let field_matches = self + .field_matches + .iter() + .map(|m| { + let m = m.to_span_match(); + attrs.record(&mut m.visitor()); + m + }) + .collect(); + SpanMatcher { + field_matches, + base_level: self.base_level, + } + } +} + +impl SpanMatcher { + /// Returns the level currently enabled for this callsite. + pub(crate) fn level(&self) -> LevelFilter { + self.field_matches + .iter() + .filter_map(field::SpanMatch::filter) + .max() + .unwrap_or(self.base_level) + } + + pub(crate) fn record_update(&self, record: &span::Record<'_>) { + for m in &self.field_matches { + record.record(&mut m.visitor()) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn parse_directives(dirs: impl AsRef) -> Vec { + dirs.as_ref() + .split(',') + .filter_map(|s| s.parse().ok()) + .collect() + } + + fn expect_parse(dirs: impl AsRef) -> Vec { + dirs.as_ref() + .split(',') + .map(|s| { + s.parse() + .unwrap_or_else(|err| panic!("directive '{:?}' should parse: {}", s, err)) + }) + .collect() + } + + #[test] + fn directive_ordering_by_target_len() { + // TODO(eliza): it would be nice to have a property-based test for this + // instead. + let mut dirs = expect_parse( + "foo::bar=debug,foo::bar::baz=trace,foo=info,a_really_long_name_with_no_colons=warn", + ); + dirs.sort_unstable(); + + let expected = vec![ + "a_really_long_name_with_no_colons", + "foo::bar::baz", + "foo::bar", + "foo", + ]; + let sorted = dirs + .iter() + .map(|d| d.target.as_ref().unwrap()) + .collect::>(); + + assert_eq!(expected, sorted); + } + #[test] + fn directive_ordering_by_span() { + // TODO(eliza): it would be nice to have a property-based test for this + // instead. + let mut dirs = expect_parse("bar[span]=trace,foo=debug,baz::quux=info,a[span]=warn"); + dirs.sort_unstable(); + + let expected = vec!["baz::quux", "bar", "foo", "a"]; + let sorted = dirs + .iter() + .map(|d| d.target.as_ref().unwrap()) + .collect::>(); + + assert_eq!(expected, sorted); + } + + #[test] + fn directive_ordering_uses_lexicographic_when_equal() { + // TODO(eliza): it would be nice to have a property-based test for this + // instead. + let mut dirs = expect_parse("span[b]=debug,b=debug,a=trace,c=info,span[a]=info"); + dirs.sort_unstable(); + + let expected = vec![ + ("span", Some("b")), + ("span", Some("a")), + ("c", None), + ("b", None), + ("a", None), + ]; + let sorted = dirs + .iter() + .map(|d| { + ( + d.target.as_ref().unwrap().as_ref(), + d.in_span.as_ref().map(String::as_ref), + ) + }) + .collect::>(); + + assert_eq!(expected, sorted); + } + + // TODO: this test requires the parser to support directives with multiple + // fields, which it currently can't handle. We should enable this test when + // that's implemented. + #[test] + #[ignore] + fn directive_ordering_by_field_num() { + // TODO(eliza): it would be nice to have a property-based test for this + // instead. + let mut dirs = expect_parse( + "b[{foo,bar}]=info,c[{baz,quuux,quuux}]=debug,a[{foo}]=warn,bar[{field}]=trace,foo=debug,baz::quux=info" + ); + dirs.sort_unstable(); + + let expected = vec!["baz::quux", "bar", "foo", "c", "b", "a"]; + let sorted = dirs + .iter() + .map(|d| d.target.as_ref().unwrap()) + .collect::>(); + + assert_eq!(expected, sorted); + } + + #[test] + fn parse_directives_ralith() { + let dirs = parse_directives("common=trace,server=trace"); + assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("common".to_string())); + assert_eq!(dirs[0].level, LevelFilter::TRACE); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("server".to_string())); + assert_eq!(dirs[1].level, LevelFilter::TRACE); + assert_eq!(dirs[1].in_span, None); + } + + #[test] + fn parse_directives_ralith_uc() { + let dirs = parse_directives("common=INFO,server=DEBUG"); + assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("common".to_string())); + assert_eq!(dirs[0].level, LevelFilter::INFO); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("server".to_string())); + assert_eq!(dirs[1].level, LevelFilter::DEBUG); + assert_eq!(dirs[1].in_span, None); + } + + #[test] + fn parse_directives_ralith_mixed() { + let dirs = parse_directives("common=iNfo,server=dEbUg"); + assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("common".to_string())); + assert_eq!(dirs[0].level, LevelFilter::INFO); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("server".to_string())); + assert_eq!(dirs[1].level, LevelFilter::DEBUG); + assert_eq!(dirs[1].in_span, None); + } + + #[test] + fn parse_directives_valid() { + let dirs = parse_directives("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off"); + assert_eq!(dirs.len(), 4, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LevelFilter::ERROR); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LevelFilter::TRACE); + assert_eq!(dirs[1].in_span, None); + + assert_eq!(dirs[2].target, Some("crate2".to_string())); + assert_eq!(dirs[2].level, LevelFilter::DEBUG); + assert_eq!(dirs[2].in_span, None); + + assert_eq!(dirs[3].target, Some("crate3".to_string())); + assert_eq!(dirs[3].level, LevelFilter::OFF); + assert_eq!(dirs[3].in_span, None); + } + + #[test] + + fn parse_level_directives() { + let dirs = parse_directives( + "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ + crate2=debug,crate3=trace,crate3::mod2::mod1=off", + ); + assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LevelFilter::ERROR); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LevelFilter::WARN); + assert_eq!(dirs[1].in_span, None); + + assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string())); + assert_eq!(dirs[2].level, LevelFilter::INFO); + assert_eq!(dirs[2].in_span, None); + + assert_eq!(dirs[3].target, Some("crate2".to_string())); + assert_eq!(dirs[3].level, LevelFilter::DEBUG); + assert_eq!(dirs[3].in_span, None); + + assert_eq!(dirs[4].target, Some("crate3".to_string())); + assert_eq!(dirs[4].level, LevelFilter::TRACE); + assert_eq!(dirs[4].in_span, None); + + assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string())); + assert_eq!(dirs[5].level, LevelFilter::OFF); + assert_eq!(dirs[5].in_span, None); + } + + #[test] + fn parse_uppercase_level_directives() { + let dirs = parse_directives( + "crate1::mod1=ERROR,crate1::mod2=WARN,crate1::mod2::mod3=INFO,\ + crate2=DEBUG,crate3=TRACE,crate3::mod2::mod1=OFF", + ); + assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LevelFilter::ERROR); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LevelFilter::WARN); + assert_eq!(dirs[1].in_span, None); + + assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string())); + assert_eq!(dirs[2].level, LevelFilter::INFO); + assert_eq!(dirs[2].in_span, None); + + assert_eq!(dirs[3].target, Some("crate2".to_string())); + assert_eq!(dirs[3].level, LevelFilter::DEBUG); + assert_eq!(dirs[3].in_span, None); + + assert_eq!(dirs[4].target, Some("crate3".to_string())); + assert_eq!(dirs[4].level, LevelFilter::TRACE); + assert_eq!(dirs[4].in_span, None); + + assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string())); + assert_eq!(dirs[5].level, LevelFilter::OFF); + assert_eq!(dirs[5].in_span, None); + } + + #[test] + fn parse_numeric_level_directives() { + let dirs = parse_directives( + "crate1::mod1=1,crate1::mod2=2,crate1::mod2::mod3=3,crate2=4,\ + crate3=5,crate3::mod2::mod1=0", + ); + assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LevelFilter::ERROR); + assert_eq!(dirs[0].in_span, None); + + assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LevelFilter::WARN); + assert_eq!(dirs[1].in_span, None); + + assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string())); + assert_eq!(dirs[2].level, LevelFilter::INFO); + assert_eq!(dirs[2].in_span, None); + + assert_eq!(dirs[3].target, Some("crate2".to_string())); + assert_eq!(dirs[3].level, LevelFilter::DEBUG); + assert_eq!(dirs[3].in_span, None); + + assert_eq!(dirs[4].target, Some("crate3".to_string())); + assert_eq!(dirs[4].level, LevelFilter::TRACE); + assert_eq!(dirs[4].in_span, None); + + assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string())); + assert_eq!(dirs[5].level, LevelFilter::OFF); + assert_eq!(dirs[5].in_span, None); + } + + #[test] + fn parse_directives_invalid_crate() { + // test parse_directives with multiple = in specification + let dirs = parse_directives("crate1::mod1=warn=info,crate2=debug"); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LevelFilter::DEBUG); + assert_eq!(dirs[0].in_span, None); + } + + #[test] + fn parse_directives_invalid_level() { + // test parse_directives with 'noNumber' as log level + let dirs = parse_directives("crate1::mod1=noNumber,crate2=debug"); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LevelFilter::DEBUG); + assert_eq!(dirs[0].in_span, None); + } + + #[test] + fn parse_directives_string_level() { + // test parse_directives with 'warn' as log level + let dirs = parse_directives("crate1::mod1=wrong,crate2=warn"); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LevelFilter::WARN); + assert_eq!(dirs[0].in_span, None); + } + + #[test] + fn parse_directives_empty_level() { + // test parse_directives with '' as log level + let dirs = parse_directives("crate1::mod1=wrong,crate2="); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate2".to_string())); + assert_eq!(dirs[0].level, LevelFilter::TRACE); + assert_eq!(dirs[0].in_span, None); + } + + #[test] + fn parse_directives_global() { + // test parse_directives with no crate + let dirs = parse_directives("warn,crate2=debug"); + assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, None); + assert_eq!(dirs[0].level, LevelFilter::WARN); + assert_eq!(dirs[1].in_span, None); + + assert_eq!(dirs[1].target, Some("crate2".to_string())); + assert_eq!(dirs[1].level, LevelFilter::DEBUG); + assert_eq!(dirs[1].in_span, None); + } + + // helper function for tests below + fn test_parse_bare_level(directive_to_test: &str, level_expected: LevelFilter) { + let dirs = parse_directives(directive_to_test); + assert_eq!( + dirs.len(), + 1, + "\ninput: \"{}\"; parsed: {:#?}", + directive_to_test, + dirs + ); + assert_eq!(dirs[0].target, None); + assert_eq!(dirs[0].level, level_expected); + assert_eq!(dirs[0].in_span, None); + } + + #[test] + fn parse_directives_global_bare_warn_lc() { + // test parse_directives with no crate, in isolation, all lowercase + test_parse_bare_level("warn", LevelFilter::WARN); + } + + #[test] + fn parse_directives_global_bare_warn_uc() { + // test parse_directives with no crate, in isolation, all uppercase + test_parse_bare_level("WARN", LevelFilter::WARN); + } + + #[test] + fn parse_directives_global_bare_warn_mixed() { + // test parse_directives with no crate, in isolation, mixed case + test_parse_bare_level("wArN", LevelFilter::WARN); + } + + #[test] + fn parse_directives_valid_with_spans() { + let dirs = parse_directives("crate1::mod1[foo]=error,crate1::mod2[bar],crate2[baz]=debug"); + assert_eq!(dirs.len(), 3, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[0].level, LevelFilter::ERROR); + assert_eq!(dirs[0].in_span, Some("foo".to_string())); + + assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[1].level, LevelFilter::TRACE); + assert_eq!(dirs[1].in_span, Some("bar".to_string())); + + assert_eq!(dirs[2].target, Some("crate2".to_string())); + assert_eq!(dirs[2].level, LevelFilter::DEBUG); + assert_eq!(dirs[2].in_span, Some("baz".to_string())); + } + + #[test] + fn parse_directives_with_dash_in_target_name() { + let dirs = parse_directives("target-name=info"); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("target-name".to_string())); + assert_eq!(dirs[0].level, LevelFilter::INFO); + assert_eq!(dirs[0].in_span, None); + } + + #[test] + fn parse_directives_with_dash_in_span_name() { + // Reproduces https://github.com/tokio-rs/tracing/issues/1367 + + let dirs = parse_directives("target[span-name]=info"); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("target".to_string())); + assert_eq!(dirs[0].level, LevelFilter::INFO); + assert_eq!(dirs[0].in_span, Some("span-name".to_string())); + } + + #[test] + fn parse_directives_with_special_characters_in_span_name() { + let span_name = "!\"#$%&'()*+-./:;<=>?@^_`|~[}"; + + let dirs = parse_directives(format!("target[{}]=info", span_name)); + assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("target".to_string())); + assert_eq!(dirs[0].level, LevelFilter::INFO); + assert_eq!(dirs[0].in_span, Some(span_name.to_string())); + } + + #[test] + fn parse_directives_with_invalid_span_chars() { + let invalid_span_name = "]{"; + + let dirs = parse_directives(format!("target[{}]=info", invalid_span_name)); + assert_eq!(dirs.len(), 0, "\nparsed: {:#?}", dirs); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/env/field.rs b/vendor/tracing-subscriber-0.3.3/src/filter/env/field.rs new file mode 100644 index 000000000..970850f92 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/env/field.rs @@ -0,0 +1,416 @@ +use matchers::Pattern; +use std::{ + cmp::Ordering, + error::Error, + fmt, + str::FromStr, + sync::{ + atomic::{AtomicBool, Ordering::*}, + Arc, + }, +}; + +use super::{FieldMap, LevelFilter}; +use tracing_core::field::{Field, Visit}; + +#[derive(Debug, Eq, PartialEq)] +pub(crate) struct Match { + pub(crate) name: String, // TODO: allow match patterns for names? + pub(crate) value: Option, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) struct CallsiteMatch { + pub(crate) fields: FieldMap, + pub(crate) level: LevelFilter, +} + +#[derive(Debug)] +pub(crate) struct SpanMatch { + fields: FieldMap<(ValueMatch, AtomicBool)>, + level: LevelFilter, + has_matched: AtomicBool, +} + +pub(crate) struct MatchVisitor<'a> { + inner: &'a SpanMatch, +} + +#[derive(Debug, Clone)] +pub(crate) enum ValueMatch { + Bool(bool), + F64(f64), + U64(u64), + I64(i64), + NaN, + Pat(Box), +} + +impl Eq for ValueMatch {} + +impl PartialEq for ValueMatch { + fn eq(&self, other: &Self) -> bool { + use ValueMatch::*; + match (self, other) { + (Bool(a), Bool(b)) => a.eq(b), + (F64(a), F64(b)) => { + debug_assert!(!a.is_nan()); + debug_assert!(!b.is_nan()); + + a.eq(b) + } + (U64(a), U64(b)) => a.eq(b), + (I64(a), I64(b)) => a.eq(b), + (NaN, NaN) => true, + (Pat(a), Pat(b)) => a.eq(b), + _ => false, + } + } +} + +impl Ord for ValueMatch { + fn cmp(&self, other: &Self) -> Ordering { + use ValueMatch::*; + match (self, other) { + (Bool(this), Bool(that)) => this.cmp(that), + (Bool(_), _) => Ordering::Less, + + (F64(this), F64(that)) => this + .partial_cmp(that) + .expect("`ValueMatch::F64` may not contain `NaN` values"), + (F64(_), Bool(_)) => Ordering::Greater, + (F64(_), _) => Ordering::Less, + + (NaN, NaN) => Ordering::Equal, + (NaN, Bool(_)) | (NaN, F64(_)) => Ordering::Greater, + (NaN, _) => Ordering::Less, + + (U64(this), U64(that)) => this.cmp(that), + (U64(_), Bool(_)) | (U64(_), F64(_)) | (U64(_), NaN) => Ordering::Greater, + (U64(_), _) => Ordering::Less, + + (I64(this), I64(that)) => this.cmp(that), + (I64(_), Bool(_)) | (I64(_), F64(_)) | (I64(_), NaN) | (I64(_), U64(_)) => { + Ordering::Greater + } + (I64(_), _) => Ordering::Less, + + (Pat(this), Pat(that)) => this.cmp(that), + (Pat(_), _) => Ordering::Greater, + } + } +} + +impl PartialOrd for ValueMatch { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[derive(Debug, Clone)] +pub(crate) struct MatchPattern { + pub(crate) matcher: Pattern, + pattern: Arc, +} + +/// Indicates that a field name specified in a filter directive was invalid. +#[derive(Clone, Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] +pub struct BadName { + name: String, +} + +// === impl Match === + +impl FromStr for Match { + type Err = Box; + fn from_str(s: &str) -> Result { + let mut parts = s.split('='); + let name = parts + .next() + .ok_or_else(|| BadName { + name: "".to_string(), + })? + // TODO: validate field name + .to_string(); + let value = parts.next().map(ValueMatch::from_str).transpose()?; + Ok(Match { name, value }) + } +} + +impl Match { + pub(crate) fn has_value(&self) -> bool { + self.value.is_some() + } + + // TODO: reference count these strings? + pub(crate) fn name(&self) -> String { + self.name.clone() + } +} + +impl fmt::Display for Match { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.name, f)?; + if let Some(ref value) = self.value { + write!(f, "={}", value)?; + } + Ok(()) + } +} + +impl Ord for Match { + fn cmp(&self, other: &Self) -> Ordering { + // Ordering for `Match` directives is based first on _whether_ a value + // is matched or not. This is semantically meaningful --- we would + // prefer to check directives that match values first as they are more + // specific. + let has_value = match (self.value.as_ref(), other.value.as_ref()) { + (Some(_), None) => Ordering::Greater, + (None, Some(_)) => Ordering::Less, + _ => Ordering::Equal, + }; + // If both directives match a value, we fall back to the field names in + // length + lexicographic ordering, and if these are equal as well, we + // compare the match directives. + // + // This ordering is no longer semantically meaningful but is necessary + // so that the directives can be stored in the `BTreeMap` in a defined + // order. + has_value + .then_with(|| self.name.cmp(&other.name)) + .then_with(|| self.value.cmp(&other.value)) + } +} + +impl PartialOrd for Match { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +// === impl ValueMatch === + +fn value_match_f64(v: f64) -> ValueMatch { + if v.is_nan() { + ValueMatch::NaN + } else { + ValueMatch::F64(v) + } +} + +impl FromStr for ValueMatch { + type Err = matchers::Error; + fn from_str(s: &str) -> Result { + s.parse::() + .map(ValueMatch::Bool) + .or_else(|_| s.parse::().map(ValueMatch::U64)) + .or_else(|_| s.parse::().map(ValueMatch::I64)) + .or_else(|_| s.parse::().map(value_match_f64)) + .or_else(|_| { + s.parse::() + .map(|p| ValueMatch::Pat(Box::new(p))) + }) + } +} + +impl fmt::Display for ValueMatch { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ValueMatch::Bool(ref inner) => fmt::Display::fmt(inner, f), + ValueMatch::F64(ref inner) => fmt::Display::fmt(inner, f), + ValueMatch::NaN => fmt::Display::fmt(&std::f64::NAN, f), + ValueMatch::I64(ref inner) => fmt::Display::fmt(inner, f), + ValueMatch::U64(ref inner) => fmt::Display::fmt(inner, f), + ValueMatch::Pat(ref inner) => fmt::Display::fmt(inner, f), + } + } +} + +// === impl MatchPattern === + +impl FromStr for MatchPattern { + type Err = matchers::Error; + fn from_str(s: &str) -> Result { + let matcher = s.parse::()?; + Ok(Self { + matcher, + pattern: s.to_owned().into(), + }) + } +} + +impl fmt::Display for MatchPattern { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&*self.pattern, f) + } +} + +impl AsRef for MatchPattern { + #[inline] + fn as_ref(&self) -> &str { + self.pattern.as_ref() + } +} + +impl MatchPattern { + #[inline] + fn str_matches(&self, s: &impl AsRef) -> bool { + self.matcher.matches(s) + } + + #[inline] + fn debug_matches(&self, d: &impl fmt::Debug) -> bool { + self.matcher.debug_matches(d) + } +} + +impl PartialEq for MatchPattern { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.pattern == other.pattern + } +} + +impl Eq for MatchPattern {} + +impl PartialOrd for MatchPattern { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.pattern.cmp(&other.pattern)) + } +} + +impl Ord for MatchPattern { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + self.pattern.cmp(&other.pattern) + } +} + +// === impl BadName === + +impl Error for BadName {} + +impl fmt::Display for BadName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "invalid field name `{}`", self.name) + } +} + +impl CallsiteMatch { + pub(crate) fn to_span_match(&self) -> SpanMatch { + let fields = self + .fields + .iter() + .map(|(k, v)| (k.clone(), (v.clone(), AtomicBool::new(false)))) + .collect(); + SpanMatch { + fields, + level: self.level, + has_matched: AtomicBool::new(false), + } + } +} + +impl SpanMatch { + pub(crate) fn visitor(&self) -> MatchVisitor<'_> { + MatchVisitor { inner: self } + } + + #[inline] + pub(crate) fn is_matched(&self) -> bool { + if self.has_matched.load(Acquire) { + return true; + } + self.is_matched_slow() + } + + #[inline(never)] + fn is_matched_slow(&self) -> bool { + let matched = self + .fields + .values() + .all(|(_, matched)| matched.load(Acquire)); + if matched { + self.has_matched.store(true, Release); + } + matched + } + + #[inline] + pub(crate) fn filter(&self) -> Option { + if self.is_matched() { + Some(self.level) + } else { + None + } + } +} + +impl<'a> Visit for MatchVisitor<'a> { + fn record_f64(&mut self, field: &Field, value: f64) { + match self.inner.fields.get(field) { + Some((ValueMatch::NaN, ref matched)) if value.is_nan() => { + matched.store(true, Release); + } + Some((ValueMatch::F64(ref e), ref matched)) + if (value - *e).abs() < std::f64::EPSILON => + { + matched.store(true, Release); + } + _ => {} + } + } + + fn record_i64(&mut self, field: &Field, value: i64) { + use std::convert::TryInto; + + match self.inner.fields.get(field) { + Some((ValueMatch::I64(ref e), ref matched)) if value == *e => { + matched.store(true, Release); + } + Some((ValueMatch::U64(ref e), ref matched)) if Ok(value) == (*e).try_into() => { + matched.store(true, Release); + } + _ => {} + } + } + + fn record_u64(&mut self, field: &Field, value: u64) { + match self.inner.fields.get(field) { + Some((ValueMatch::U64(ref e), ref matched)) if value == *e => { + matched.store(true, Release); + } + _ => {} + } + } + + fn record_bool(&mut self, field: &Field, value: bool) { + match self.inner.fields.get(field) { + Some((ValueMatch::Bool(ref e), ref matched)) if value == *e => { + matched.store(true, Release); + } + _ => {} + } + } + + fn record_str(&mut self, field: &Field, value: &str) { + match self.inner.fields.get(field) { + Some((ValueMatch::Pat(ref e), ref matched)) if e.str_matches(&value) => { + matched.store(true, Release); + } + _ => {} + } + } + + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + match self.inner.fields.get(field) { + Some((ValueMatch::Pat(ref e), ref matched)) if e.debug_matches(&value) => { + matched.store(true, Release); + } + _ => {} + } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/env/mod.rs b/vendor/tracing-subscriber-0.3.3/src/filter/env/mod.rs new file mode 100644 index 000000000..81fe0e62d --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/env/mod.rs @@ -0,0 +1,738 @@ +//! A `Layer` that enables or disables spans and events based on a set of +//! filtering directives. + +// these are publicly re-exported, but the compiler doesn't realize +// that for some reason. +#[allow(unreachable_pub)] +pub use self::{directive::Directive, field::BadName as BadFieldName}; +mod directive; +mod field; + +use crate::{ + filter::LevelFilter, + layer::{Context, Layer}, + sync::RwLock, +}; +use directive::ParseError; +use std::{cell::RefCell, collections::HashMap, env, error::Error, fmt, str::FromStr}; +use tracing_core::{ + callsite, + field::Field, + span, + subscriber::{Interest, Subscriber}, + Metadata, +}; + +/// A [`Layer`] which filters spans and events based on a set of filter +/// directives. +/// +/// # Directives +/// +/// A filter consists of one or more comma-separated directives which match on [`Span`]s and [`Event`]s. +/// Each directive may have a corresponding maximum verbosity [`level`] which +/// enables (e.g., _selects for_) spans and events that match. Like `log`, +/// `tracing` considers less exclusive levels (like `trace` or `info`) to be more +/// verbose than more exclusive levels (like `error` or `warn`). +/// +/// The directive syntax is similar to that of [`env_logger`]'s. At a high level, the syntax for directives +/// consists of several parts: +/// +/// ```text +/// target[span{field=value}]=level +/// ``` +/// +/// Each component (`target`, `span`, `field`, `value`, and `level`) will be covered in turn. +/// +/// - `target` matches the event or span's target. In general, this is the module path and/or crate name. +/// Examples of targets `h2`, `tokio::net`, or `tide::server`. For more information on targets, +/// please refer to [`Metadata`]'s documentation. +/// - `span` matches on the span's name. If a `span` directive is provided alongside a `target`, +/// the `span` directive will match on spans _within_ the `target`. +/// - `field` matches on [fields] within spans. Field names can also be supplied without a `value` +/// and will match on any [`Span`] or [`Event`] that has a field with that name. +/// For example: `[span{field=\"value\"}]=debug`, `[{field}]=trace`. +/// - `value` matches on the value of a span's field. If a value is a numeric literal or a bool, +/// it will match _only_ on that value. Otherwise, this filter acts as a regex on +/// the `std::fmt::Debug` output from the value. +/// - `level` sets a maximum verbosity level accepted by this directive. +/// +/// ## Usage Notes +/// +/// - The portion of the directive which is included within the square brackets is `tracing`-specific. +/// - Any portion of the directive can be omitted. +/// - The sole exception are the `field` and `value` directives. If a `value` is provided, +/// a `field` must _also_ be provided. However, the converse does not hold, as fields can +/// be matched without a value. +/// - If only a level is provided, it will set the maximum level for all `Span`s and `Event`s +/// that are not enabled by other filters. +/// - A directive without a level will enable anything that it matches. This is equivalent to `=trace`. +/// - When a crate has a dash in its name, the default target for events will be the +/// crate's module path as it appears in Rust. This means every dash will be replaced +/// with an underscore. +/// - A dash in a target will only appear when being specified explicitly: +/// `tracing::info!(target: "target-name", ...);` +/// +/// ## Examples +/// +/// - `tokio::net=info` will enable all spans or events that: +/// - have the `tokio::net` target, +/// - at the level `info` or above. +/// - `warn,tokio::net=info` will enable all spans and events that: +/// - are at the level `warn` or above, *or* +/// - have the `tokio::net` target at the level `info` or above. +/// - `my_crate[span_a]=trace` will enable all spans and events that: +/// - are within the `span_a` span or named `span_a` _if_ `span_a` has the target `my_crate`, +/// - at the level `trace` or above. +/// - `[span_b{name=\"bob\"}]` will enable all spans or event that: +/// - have _any_ target, +/// - are inside a span named `span_b`, +/// - which has a field named `name` with value `bob`, +/// - at _any_ level. +/// +/// The [`Targets`] type implements a similar form of filtering, but without the +/// ability to dynamically enable events based on the current span context, and +/// without filtering on field values. When these features are not required, +/// [`Targets`] provides a lighter-weight alternative to [`EnvFilter`]. +/// +/// [`Span`]: tracing_core::span +/// [fields]: tracing_core::Field +/// [`Event`]: tracing_core::Event +/// [`level`]: tracing_core::Level +/// [`Metadata`]: tracing_core::Metadata +/// [`Targets`]: crate::filter::Targets +#[cfg_attr(docsrs, doc(cfg(all(feature = "env-filter", feature = "std"))))] +#[derive(Debug)] +pub struct EnvFilter { + statics: directive::Statics, + dynamics: directive::Dynamics, + has_dynamics: bool, + by_id: RwLock>, + by_cs: RwLock>, +} + +thread_local! { + static SCOPE: RefCell> = RefCell::new(Vec::new()); +} + +type FieldMap = HashMap; + +/// Indicates that an error occurred while parsing a `EnvFilter` from an +/// environment variable. +#[cfg_attr(docsrs, doc(cfg(all(feature = "env-filter", feature = "std"))))] +#[derive(Debug)] +pub struct FromEnvError { + kind: ErrorKind, +} + +#[derive(Debug)] +enum ErrorKind { + Parse(ParseError), + Env(env::VarError), +} + +impl EnvFilter { + /// `RUST_LOG` is the default environment variable used by + /// [`EnvFilter::from_default_env`] and [`EnvFilter::try_from_default_env`]. + /// + /// [`EnvFilter::from_default_env`]: #method.from_default_env + /// [`EnvFilter::try_from_default_env`]: #method.try_from_default_env + pub const DEFAULT_ENV: &'static str = "RUST_LOG"; + + /// Returns a new `EnvFilter` from the value of the `RUST_LOG` environment + /// variable, ignoring any invalid filter directives. + pub fn from_default_env() -> Self { + Self::from_env(Self::DEFAULT_ENV) + } + + /// Returns a new `EnvFilter` from the value of the given environment + /// variable, ignoring any invalid filter directives. + pub fn from_env>(env: A) -> Self { + env::var(env.as_ref()).map(Self::new).unwrap_or_default() + } + + /// Returns a new `EnvFilter` from the directives in the given string, + /// ignoring any that are invalid. + pub fn new>(dirs: S) -> Self { + let directives = dirs.as_ref().split(',').filter_map(|s| match s.parse() { + Ok(d) => Some(d), + Err(err) => { + eprintln!("ignoring `{}`: {}", s, err); + None + } + }); + Self::from_directives(directives) + } + + /// Returns a new `EnvFilter` from the directives in the given string, + /// or an error if any are invalid. + pub fn try_new>(dirs: S) -> Result { + let directives = dirs + .as_ref() + .split(',') + .map(|s| s.parse()) + .collect::, _>>()?; + Ok(Self::from_directives(directives)) + } + + /// Returns a new `EnvFilter` from the value of the `RUST_LOG` environment + /// variable, or an error if the environment variable contains any invalid + /// filter directives. + pub fn try_from_default_env() -> Result { + Self::try_from_env(Self::DEFAULT_ENV) + } + + /// Returns a new `EnvFilter` from the value of the given environment + /// variable, or an error if the environment variable is unset or contains + /// any invalid filter directives. + pub fn try_from_env>(env: A) -> Result { + env::var(env.as_ref())?.parse().map_err(Into::into) + } + + /// Add a filtering directive to this `EnvFilter`. + /// + /// The added directive will be used in addition to any previously set + /// directives, either added using this method or provided when the filter + /// is constructed. + /// + /// Filters may be created from [`LevelFilter`] or [`Level`], which will + /// enable all traces at or below a certain verbosity level, or + /// parsed from a string specifying a directive. + /// + /// If a filter directive is inserted that matches exactly the same spans + /// and events as a previous filter, but sets a different level for those + /// spans and events, the previous directive is overwritten. + /// + /// [`LevelFilter`]: ../filter/struct.LevelFilter.html + /// [`Level`]: https://docs.rs/tracing-core/latest/tracing_core/struct.Level.html + /// + /// # Examples + /// + /// From [`LevelFilter`]: + //// + /// ```rust + /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; + /// let mut filter = EnvFilter::from_default_env() + /// .add_directive(LevelFilter::INFO.into()); + /// ``` + /// + /// Or from [`Level`]: + /// + /// ```rust + /// # use tracing_subscriber::filter::{EnvFilter, LevelFilter}; + /// # use tracing::Level; + /// let mut filter = EnvFilter::from_default_env() + /// .add_directive(Level::INFO.into()); + /// ``` + //// + /// Parsed from a string: + //// + /// ```rust + /// use tracing_subscriber::filter::{EnvFilter, Directive}; + /// + /// # fn try_mk_filter() -> Result<(), Box> { + /// let mut filter = EnvFilter::try_from_default_env()? + /// .add_directive("my_crate::module=trace".parse()?) + /// .add_directive("my_crate::my_other_module::something=info".parse()?); + /// # Ok(()) + /// # } + /// ``` + pub fn add_directive(mut self, directive: Directive) -> Self { + if let Some(stat) = directive.to_static() { + self.statics.add(stat) + } else { + self.has_dynamics = true; + self.dynamics.add(directive); + } + self + } + + fn from_directives(directives: impl IntoIterator) -> Self { + use tracing::level_filters::STATIC_MAX_LEVEL; + use tracing::Level; + + let directives: Vec<_> = directives.into_iter().collect(); + + let disabled: Vec<_> = directives + .iter() + .filter(|directive| directive.level > STATIC_MAX_LEVEL) + .collect(); + + if !disabled.is_empty() { + #[cfg(feature = "ansi_term")] + use ansi_term::{Color, Style}; + // NOTE: We can't use a configured `MakeWriter` because the EnvFilter + // has no knowledge of any underlying subscriber or subscriber, which + // may or may not use a `MakeWriter`. + let warn = |msg: &str| { + #[cfg(not(feature = "ansi_term"))] + let msg = format!("warning: {}", msg); + #[cfg(feature = "ansi_term")] + let msg = { + let bold = Style::new().bold(); + let mut warning = Color::Yellow.paint("warning"); + warning.style_ref_mut().is_bold = true; + format!("{}{} {}", warning, bold.paint(":"), bold.paint(msg)) + }; + eprintln!("{}", msg); + }; + let ctx_prefixed = |prefix: &str, msg: &str| { + #[cfg(not(feature = "ansi_term"))] + let msg = format!("note: {}", msg); + #[cfg(feature = "ansi_term")] + let msg = { + let mut equal = Color::Fixed(21).paint("="); // dark blue + equal.style_ref_mut().is_bold = true; + format!(" {} {} {}", equal, Style::new().bold().paint(prefix), msg) + }; + eprintln!("{}", msg); + }; + let ctx_help = |msg| ctx_prefixed("help:", msg); + let ctx_note = |msg| ctx_prefixed("note:", msg); + let ctx = |msg: &str| { + #[cfg(not(feature = "ansi_term"))] + let msg = format!("note: {}", msg); + #[cfg(feature = "ansi_term")] + let msg = { + let mut pipe = Color::Fixed(21).paint("|"); + pipe.style_ref_mut().is_bold = true; + format!(" {} {}", pipe, msg) + }; + eprintln!("{}", msg); + }; + warn("some trace filter directives would enable traces that are disabled statically"); + for directive in disabled { + let target = if let Some(target) = &directive.target { + format!("the `{}` target", target) + } else { + "all targets".into() + }; + let level = directive + .level + .into_level() + .expect("=off would not have enabled any filters"); + ctx(&format!( + "`{}` would enable the {} level for {}", + directive, level, target + )); + } + ctx_note(&format!("the static max level is `{}`", STATIC_MAX_LEVEL)); + let help_msg = || { + let (feature, filter) = match STATIC_MAX_LEVEL.into_level() { + Some(Level::TRACE) => unreachable!( + "if the max level is trace, no static filtering features are enabled" + ), + Some(Level::DEBUG) => ("max_level_debug", Level::TRACE), + Some(Level::INFO) => ("max_level_info", Level::DEBUG), + Some(Level::WARN) => ("max_level_warn", Level::INFO), + Some(Level::ERROR) => ("max_level_error", Level::WARN), + None => return ("max_level_off", String::new()), + }; + (feature, format!("{} ", filter)) + }; + let (feature, earlier_level) = help_msg(); + ctx_help(&format!( + "to enable {}logging, remove the `{}` feature", + earlier_level, feature + )); + } + + let (dynamics, mut statics) = Directive::make_tables(directives); + let has_dynamics = !dynamics.is_empty(); + + if statics.is_empty() && !has_dynamics { + statics.add(directive::StaticDirective::default()); + } + + Self { + statics, + dynamics, + has_dynamics, + by_id: RwLock::new(HashMap::new()), + by_cs: RwLock::new(HashMap::new()), + } + } + + fn cares_about_span(&self, span: &span::Id) -> bool { + let spans = try_lock!(self.by_id.read(), else return false); + spans.contains_key(span) + } + + fn base_interest(&self) -> Interest { + if self.has_dynamics { + Interest::sometimes() + } else { + Interest::never() + } + } +} + +impl Layer for EnvFilter { + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + if self.has_dynamics && metadata.is_span() { + // If this metadata describes a span, first, check if there is a + // dynamic filter that should be constructed for it. If so, it + // should always be enabled, since it influences filtering. + if let Some(matcher) = self.dynamics.matcher(metadata) { + let mut by_cs = try_lock!(self.by_cs.write(), else return self.base_interest()); + by_cs.insert(metadata.callsite(), matcher); + return Interest::always(); + } + } + + // Otherwise, check if any of our static filters enable this metadata. + if self.statics.enabled(metadata) { + Interest::always() + } else { + self.base_interest() + } + } + + fn max_level_hint(&self) -> Option { + if self.dynamics.has_value_filters() { + // If we perform any filtering on span field *values*, we will + // enable *all* spans, because their field values are not known + // until recording. + return Some(LevelFilter::TRACE); + } + std::cmp::max( + self.statics.max_level.into(), + self.dynamics.max_level.into(), + ) + } + + fn enabled(&self, metadata: &Metadata<'_>, _: Context<'_, S>) -> bool { + let level = metadata.level(); + + // is it possible for a dynamic filter directive to enable this event? + // if not, we can avoid the thread local access + iterating over the + // spans in the current scope. + if self.has_dynamics && self.dynamics.max_level >= *level { + if metadata.is_span() { + // If the metadata is a span, see if we care about its callsite. + let enabled_by_cs = self + .by_cs + .read() + .ok() + .map(|by_cs| by_cs.contains_key(&metadata.callsite())) + .unwrap_or(false); + if enabled_by_cs { + return true; + } + } + + let enabled_by_scope = SCOPE.with(|scope| { + for filter in scope.borrow().iter() { + if filter >= level { + return true; + } + } + false + }); + if enabled_by_scope { + return true; + } + } + + // is it possible for a static filter directive to enable this event? + if self.statics.max_level >= *level { + // Otherwise, fall back to checking if the callsite is + // statically enabled. + return self.statics.enabled(metadata); + } + + false + } + + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, _: Context<'_, S>) { + let by_cs = try_lock!(self.by_cs.read()); + if let Some(cs) = by_cs.get(&attrs.metadata().callsite()) { + let span = cs.to_span_match(attrs); + try_lock!(self.by_id.write()).insert(id.clone(), span); + } + } + + fn on_record(&self, id: &span::Id, values: &span::Record<'_>, _: Context<'_, S>) { + if let Some(span) = try_lock!(self.by_id.read()).get(id) { + span.record_update(values); + } + } + + fn on_enter(&self, id: &span::Id, _: Context<'_, S>) { + // XXX: This is where _we_ could push IDs to the stack instead, and use + // that to allow changing the filter while a span is already entered. + // But that might be much less efficient... + if let Some(span) = try_lock!(self.by_id.read()).get(id) { + SCOPE.with(|scope| scope.borrow_mut().push(span.level())); + } + } + + fn on_exit(&self, id: &span::Id, _: Context<'_, S>) { + if self.cares_about_span(id) { + SCOPE.with(|scope| scope.borrow_mut().pop()); + } + } + + fn on_close(&self, id: span::Id, _: Context<'_, S>) { + // If we don't need to acquire a write lock, avoid doing so. + if !self.cares_about_span(&id) { + return; + } + + let mut spans = try_lock!(self.by_id.write()); + spans.remove(&id); + } +} + +impl FromStr for EnvFilter { + type Err = directive::ParseError; + + fn from_str(spec: &str) -> Result { + Self::try_new(spec) + } +} + +impl From for EnvFilter +where + S: AsRef, +{ + fn from(s: S) -> Self { + Self::new(s) + } +} + +impl Default for EnvFilter { + fn default() -> Self { + Self::from_directives(std::iter::empty()) + } +} + +impl fmt::Display for EnvFilter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut statics = self.statics.iter(); + let wrote_statics = if let Some(next) = statics.next() { + fmt::Display::fmt(next, f)?; + for directive in statics { + write!(f, ",{}", directive)?; + } + true + } else { + false + }; + + let mut dynamics = self.dynamics.iter(); + if let Some(next) = dynamics.next() { + if wrote_statics { + f.write_str(",")?; + } + fmt::Display::fmt(next, f)?; + for directive in dynamics { + write!(f, ",{}", directive)?; + } + } + Ok(()) + } +} + +// ===== impl FromEnvError ===== + +impl From for FromEnvError { + fn from(p: directive::ParseError) -> Self { + Self { + kind: ErrorKind::Parse(p), + } + } +} + +impl From for FromEnvError { + fn from(v: env::VarError) -> Self { + Self { + kind: ErrorKind::Env(v), + } + } +} + +impl fmt::Display for FromEnvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.kind { + ErrorKind::Parse(ref p) => p.fmt(f), + ErrorKind::Env(ref e) => e.fmt(f), + } + } +} + +impl Error for FromEnvError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self.kind { + ErrorKind::Parse(ref p) => Some(p), + ErrorKind::Env(ref e) => Some(e), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use tracing_core::field::FieldSet; + use tracing_core::*; + + struct NoSubscriber; + impl Subscriber for NoSubscriber { + #[inline] + fn register_callsite(&self, _: &'static Metadata<'static>) -> subscriber::Interest { + subscriber::Interest::always() + } + fn new_span(&self, _: &span::Attributes<'_>) -> span::Id { + span::Id::from_u64(0xDEAD) + } + fn event(&self, _event: &Event<'_>) {} + fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {} + fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {} + + #[inline] + fn enabled(&self, _metadata: &Metadata<'_>) -> bool { + true + } + fn enter(&self, _span: &span::Id) {} + fn exit(&self, _span: &span::Id) {} + } + + struct Cs; + impl Callsite for Cs { + fn set_interest(&self, _interest: Interest) {} + fn metadata(&self) -> &Metadata<'_> { + unimplemented!() + } + } + + #[test] + fn callsite_enabled_no_span_directive() { + let filter = EnvFilter::new("app=debug").with_subscriber(NoSubscriber); + static META: &Metadata<'static> = &Metadata::new( + "mySpan", + "app", + Level::TRACE, + None, + None, + None, + FieldSet::new(&[], identify_callsite!(&Cs)), + Kind::SPAN, + ); + + let interest = filter.register_callsite(META); + assert!(interest.is_never()); + } + + #[test] + fn callsite_off() { + let filter = EnvFilter::new("app=off").with_subscriber(NoSubscriber); + static META: &Metadata<'static> = &Metadata::new( + "mySpan", + "app", + Level::ERROR, + None, + None, + None, + FieldSet::new(&[], identify_callsite!(&Cs)), + Kind::SPAN, + ); + + let interest = filter.register_callsite(META); + assert!(interest.is_never()); + } + + #[test] + fn callsite_enabled_includes_span_directive() { + let filter = EnvFilter::new("app[mySpan]=debug").with_subscriber(NoSubscriber); + static META: &Metadata<'static> = &Metadata::new( + "mySpan", + "app", + Level::TRACE, + None, + None, + None, + FieldSet::new(&[], identify_callsite!(&Cs)), + Kind::SPAN, + ); + + let interest = filter.register_callsite(META); + assert!(interest.is_always()); + } + + #[test] + fn callsite_enabled_includes_span_directive_field() { + let filter = + EnvFilter::new("app[mySpan{field=\"value\"}]=debug").with_subscriber(NoSubscriber); + static META: &Metadata<'static> = &Metadata::new( + "mySpan", + "app", + Level::TRACE, + None, + None, + None, + FieldSet::new(&["field"], identify_callsite!(&Cs)), + Kind::SPAN, + ); + + let interest = filter.register_callsite(META); + assert!(interest.is_always()); + } + + #[test] + fn callsite_enabled_includes_span_directive_multiple_fields() { + let filter = EnvFilter::new("app[mySpan{field=\"value\",field2=2}]=debug") + .with_subscriber(NoSubscriber); + static META: &Metadata<'static> = &Metadata::new( + "mySpan", + "app", + Level::TRACE, + None, + None, + None, + FieldSet::new(&["field"], identify_callsite!(&Cs)), + Kind::SPAN, + ); + + let interest = filter.register_callsite(META); + assert!(interest.is_never()); + } + + #[test] + fn roundtrip() { + let f1: EnvFilter = + "[span1{foo=1}]=error,[span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug" + .parse() + .unwrap(); + let f2: EnvFilter = format!("{}", f1).parse().unwrap(); + assert_eq!(f1.statics, f2.statics); + assert_eq!(f1.dynamics, f2.dynamics); + } + + #[test] + fn size_of_filters() { + fn print_sz(s: &str) { + let filter = s.parse::().expect("filter should parse"); + println!( + "size_of_val({:?})\n -> {}B", + s, + std::mem::size_of_val(&filter) + ); + } + + print_sz("info"); + + print_sz("foo=debug"); + + print_sz( + "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ + crate2=debug,crate3=trace,crate3::mod2::mod1=off", + ); + + print_sz("[span1{foo=1}]=error,[span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug"); + + print_sz( + "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ + crate2=debug,crate3=trace,crate3::mod2::mod1=off,[span1{foo=1}]=error,\ + [span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug", + ); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/filter_fn.rs b/vendor/tracing-subscriber-0.3.3/src/filter/filter_fn.rs new file mode 100644 index 000000000..332bf860a --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/filter_fn.rs @@ -0,0 +1,749 @@ +use crate::{ + filter::LevelFilter, + layer::{Context, Layer}, +}; +use core::{any::type_name, fmt, marker::PhantomData}; +use tracing_core::{Interest, Metadata, Subscriber}; + +/// A filter implemented by a closure or function pointer that +/// determines whether a given span or event is enabled, based on its +/// [`Metadata`]. +/// +/// This type can be used for both [per-layer filtering][plf] (using its +/// [`Filter`] implementation) and [global filtering][global] (using its +/// [`Layer`] implementation). +/// +/// See the [documentation on filtering with layers][filtering] for details. +/// +/// [`Metadata`]: tracing_core::Metadata +/// [`Filter`]: crate::layer::Filter +/// [`Layer`]: crate::layer::Layer +/// [plf]: crate::layer#per-layer-filtering +/// [global]: crate::layer#global-filtering +/// [filtering]: crate::layer#filtering-with-layers +#[derive(Clone)] +pub struct FilterFn) -> bool> { + enabled: F, + max_level_hint: Option, +} + +/// A filter implemented by a closure or function pointer that +/// determines whether a given span or event is enabled _dynamically_, +/// potentially based on the current [span context]. +/// +/// This type can be used for both [per-layer filtering][plf] (using its +/// [`Filter`] implementation) and [global filtering][global] (using its +/// [`Layer`] implementation). +/// +/// See the [documentation on filtering with layers][filtering] for details. +/// +/// [span context]: crate::layer::Context +/// [`Filter`]: crate::layer::Filter +/// [`Layer`]: crate::layer::Layer +/// [plf]: crate::layer#per-layer-filtering +/// [global]: crate::layer#global-filtering +/// [filtering]: crate::layer#filtering-with-layers +pub struct DynFilterFn< + S, + // TODO(eliza): should these just be boxed functions? + F = fn(&Metadata<'_>, &Context<'_, S>) -> bool, + R = fn(&'static Metadata<'static>) -> Interest, +> { + enabled: F, + register_callsite: Option, + max_level_hint: Option, + _s: PhantomData, +} + +// === impl FilterFn === + +/// Constructs a [`FilterFn`], from a function or closure that returns `true` if +/// a span or event should be enabled, based on its [`Metadata`]. +/// +/// The returned [`FilterFn`] can be used for both [per-layer filtering][plf] +/// (using its [`Filter`] implementation) and [global filtering][global] (using +/// its [`Layer`] implementation). +/// +/// See the [documentation on filtering with layers][filtering] for details. +/// +/// This is equivalent to calling [`FilterFn::new`]. +/// +/// [`Metadata`]: tracing_core::Metadata +/// [`Filter`]: crate::layer::Filter +/// [`Layer`]: crate::layer::Layer +/// [plf]: crate::layer#per-layer-filtering +/// [global]: crate::layer#global-filtering +/// [filtering]: crate::layer#filtering-with-layers +/// +/// # Examples +/// +/// ``` +/// use tracing_subscriber::{ +/// layer::{Layer, SubscriberExt}, +/// filter, +/// util::SubscriberInitExt, +/// }; +/// +/// let my_filter = filter::filter_fn(|metadata| { +/// // Only enable spans or events with the target "interesting_things" +/// metadata.target() == "interesting_things" +/// }); +/// +/// let my_layer = tracing_subscriber::fmt::layer(); +/// +/// tracing_subscriber::registry() +/// .with(my_layer.with_filter(my_filter)) +/// .init(); +/// +/// // This event will not be enabled. +/// tracing::warn!("something important but uninteresting happened!"); +/// +/// // This event will be enabled. +/// tracing::debug!(target: "interesting_things", "an interesting minor detail..."); +/// ``` +pub fn filter_fn(f: F) -> FilterFn +where + F: Fn(&Metadata<'_>) -> bool, +{ + FilterFn::new(f) +} + +/// Constructs a [`DynFilterFn`] from a function or closure that returns `true` +/// if a span or event should be enabled within a particular [span context][`Context`]. +/// +/// This is equivalent to calling [`DynFilterFn::new`]. +/// +/// Unlike [`filter_fn`], this function takes a closure or function pointer +/// taking the [`Metadata`] for a span or event *and* the current [`Context`]. +/// This means that a [`DynFilterFn`] can choose whether to enable spans or +/// events based on information about the _current_ span (or its parents). +/// +/// If this is *not* necessary, use [`filter_fn`] instead. +/// +/// The returned [`DynFilterFn`] can be used for both [per-layer filtering][plf] +/// (using its [`Filter`] implementation) and [global filtering][global] (using +/// its [`Layer`] implementation). +/// +/// See the [documentation on filtering with layers][filtering] for details. +/// +/// # Examples +/// +/// ``` +/// use tracing_subscriber::{ +/// layer::{Layer, SubscriberExt}, +/// filter, +/// util::SubscriberInitExt, +/// }; +/// +/// // Only enable spans or events within a span named "interesting_span". +/// let my_filter = filter::dynamic_filter_fn(|metadata, cx| { +/// // If this *is* "interesting_span", make sure to enable it. +/// if metadata.is_span() && metadata.name() == "interesting_span" { +/// return true; +/// } +/// +/// // Otherwise, are we in an interesting span? +/// if let Some(current_span) = cx.lookup_current() { +/// return current_span.name() == "interesting_span"; +/// } +/// +/// false +/// }); +/// +/// let my_layer = tracing_subscriber::fmt::layer(); +/// +/// tracing_subscriber::registry() +/// .with(my_layer.with_filter(my_filter)) +/// .init(); +/// +/// // This event will not be enabled. +/// tracing::info!("something happened"); +/// +/// tracing::info_span!("interesting_span").in_scope(|| { +/// // This event will be enabled. +/// tracing::debug!("something else happened"); +/// }); +/// ``` +/// +/// [`Filter`]: crate::layer::Filter +/// [`Layer`]: crate::layer::Layer +/// [plf]: crate::layer#per-layer-filtering +/// [global]: crate::layer#global-filtering +/// [filtering]: crate::layer#filtering-with-layers +/// [`Context`]: crate::layer::Context +/// [`Metadata`]: tracing_core::Metadata +pub fn dynamic_filter_fn(f: F) -> DynFilterFn +where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, +{ + DynFilterFn::new(f) +} + +impl FilterFn +where + F: Fn(&Metadata<'_>) -> bool, +{ + /// Constructs a [`FilterFn`] from a function or closure that returns `true` + /// if a span or event should be enabled, based on its [`Metadata`]. + /// + /// If determining whether a span or event should be enabled also requires + /// information about the current span context, use [`DynFilterFn`] instead. + /// + /// See the [documentation on per-layer filtering][plf] for details on using + /// [`Filter`]s. + /// + /// [`Filter`]: crate::layer::Filter + /// [plf]: crate::layer#per-layer-filtering + /// [`Metadata`]: tracing_core::Metadata + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::{ + /// layer::{Layer, SubscriberExt}, + /// filter::FilterFn, + /// util::SubscriberInitExt, + /// }; + /// + /// let my_filter = FilterFn::new(|metadata| { + /// // Only enable spans or events with the target "interesting_things" + /// metadata.target() == "interesting_things" + /// }); + /// + /// let my_layer = tracing_subscriber::fmt::layer(); + /// + /// tracing_subscriber::registry() + /// .with(my_layer.with_filter(my_filter)) + /// .init(); + /// + /// // This event will not be enabled. + /// tracing::warn!("something important but uninteresting happened!"); + /// + /// // This event will be enabled. + /// tracing::debug!(target: "interesting_things", "an interesting minor detail..."); + /// ``` + pub fn new(enabled: F) -> Self { + Self { + enabled, + max_level_hint: None, + } + } + + /// Sets the highest verbosity [`Level`] the filter function will enable. + /// + /// The value passed to this method will be returned by this `FilterFn`'s + /// [`Filter::max_level_hint`] method. + /// + /// If the provided function will not enable all levels, it is recommended + /// to call this method to configure it with the most verbose level it will + /// enable. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::{ + /// layer::{Layer, SubscriberExt}, + /// filter::{filter_fn, LevelFilter}, + /// util::SubscriberInitExt, + /// }; + /// use tracing_core::Level; + /// + /// let my_filter = filter_fn(|metadata| { + /// // Only enable spans or events with targets starting with `my_crate` + /// // and levels at or below `INFO`. + /// metadata.level() <= &Level::INFO && metadata.target().starts_with("my_crate") + /// }) + /// // Since the filter closure will only enable the `INFO` level and + /// // below, set the max level hint + /// .with_max_level_hint(LevelFilter::INFO); + /// + /// let my_layer = tracing_subscriber::fmt::layer(); + /// + /// tracing_subscriber::registry() + /// .with(my_layer.with_filter(my_filter)) + /// .init(); + /// ``` + /// + /// [`Level`]: tracing_core::Level + /// [`Filter::max_level_hint`]: crate::layer::Filter::max_level_hint + pub fn with_max_level_hint(self, max_level_hint: impl Into) -> Self { + Self { + max_level_hint: Some(max_level_hint.into()), + ..self + } + } + + #[inline] + pub(in crate::filter) fn is_enabled(&self, metadata: &Metadata<'_>) -> bool { + let enabled = (self.enabled)(metadata); + debug_assert!( + !enabled || self.is_below_max_level(metadata), + "FilterFn<{}> claimed it would only enable {:?} and below, \ + but it enabled metadata with the {:?} level\nmetadata={:#?}", + type_name::(), + self.max_level_hint.unwrap(), + metadata.level(), + metadata, + ); + + enabled + } + + #[inline] + pub(in crate::filter) fn is_callsite_enabled( + &self, + metadata: &'static Metadata<'static>, + ) -> Interest { + // Because `self.enabled` takes a `Metadata` only (and no `Context` + // parameter), we can reasonably assume its results are cachable, and + // just return `Interest::always`/`Interest::never`. + if (self.enabled)(metadata) { + debug_assert!( + self.is_below_max_level(metadata), + "FilterFn<{}> claimed it was only interested in {:?} and below, \ + but it enabled metadata with the {:?} level\nmetadata={:#?}", + type_name::(), + self.max_level_hint.unwrap(), + metadata.level(), + metadata, + ); + return Interest::always(); + } + + Interest::never() + } + + fn is_below_max_level(&self, metadata: &Metadata<'_>) -> bool { + self.max_level_hint + .as_ref() + .map(|hint| metadata.level() <= hint) + .unwrap_or(true) + } +} + +impl Layer for FilterFn +where + F: Fn(&Metadata<'_>) -> bool + 'static, + S: Subscriber, +{ + fn enabled(&self, metadata: &Metadata<'_>, _: Context<'_, S>) -> bool { + self.is_enabled(metadata) + } + + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + self.is_callsite_enabled(metadata) + } + + fn max_level_hint(&self) -> Option { + self.max_level_hint + } +} + +impl From for FilterFn +where + F: Fn(&Metadata<'_>) -> bool, +{ + fn from(enabled: F) -> Self { + Self::new(enabled) + } +} + +impl fmt::Debug for FilterFn { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FilterFn") + .field("enabled", &format_args!("{}", type_name::())) + .field("max_level_hint", &self.max_level_hint) + .finish() + } +} + +// === impl DynFilterFn == + +impl DynFilterFn +where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, +{ + /// Constructs a [`Filter`] from a function or closure that returns `true` + /// if a span or event should be enabled in the current [span + /// context][`Context`]. + /// + /// Unlike [`FilterFn`], a `DynFilterFn` is constructed from a closure or + /// function pointer that takes both the [`Metadata`] for a span or event + /// *and* the current [`Context`]. This means that a [`DynFilterFn`] can + /// choose whether to enable spans or events based on information about the + /// _current_ span (or its parents). + /// + /// If this is *not* necessary, use [`FilterFn`] instead. + /// + /// See the [documentation on per-layer filtering][plf] for details on using + /// [`Filter`]s. + /// + /// [`Filter`]: crate::layer::Filter + /// [plf]: crate::layer#per-layer-filtering + /// [`Context`]: crate::layer::Context + /// [`Metadata`]: tracing_core::Metadata + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::{ + /// layer::{Layer, SubscriberExt}, + /// filter::DynFilterFn, + /// util::SubscriberInitExt, + /// }; + /// + /// // Only enable spans or events within a span named "interesting_span". + /// let my_filter = DynFilterFn::new(|metadata, cx| { + /// // If this *is* "interesting_span", make sure to enable it. + /// if metadata.is_span() && metadata.name() == "interesting_span" { + /// return true; + /// } + /// + /// // Otherwise, are we in an interesting span? + /// if let Some(current_span) = cx.lookup_current() { + /// return current_span.name() == "interesting_span"; + /// } + /// + /// false + /// }); + /// + /// let my_layer = tracing_subscriber::fmt::layer(); + /// + /// tracing_subscriber::registry() + /// .with(my_layer.with_filter(my_filter)) + /// .init(); + /// + /// // This event will not be enabled. + /// tracing::info!("something happened"); + /// + /// tracing::info_span!("interesting_span").in_scope(|| { + /// // This event will be enabled. + /// tracing::debug!("something else happened"); + /// }); + /// ``` + pub fn new(enabled: F) -> Self { + Self { + enabled, + register_callsite: None, + max_level_hint: None, + _s: PhantomData, + } + } +} + +impl DynFilterFn +where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, +{ + /// Sets the highest verbosity [`Level`] the filter function will enable. + /// + /// The value passed to this method will be returned by this `DynFilterFn`'s + /// [`Filter::max_level_hint`] method. + /// + /// If the provided function will not enable all levels, it is recommended + /// to call this method to configure it with the most verbose level it will + /// enable. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::{ + /// layer::{Layer, SubscriberExt}, + /// filter::{DynFilterFn, LevelFilter}, + /// util::SubscriberInitExt, + /// }; + /// use tracing_core::Level; + /// + /// // Only enable spans or events with levels at or below `INFO`, if + /// // we are inside a span called "interesting_span". + /// let my_filter = DynFilterFn::new(|metadata, cx| { + /// // If the level is greater than INFO, disable it. + /// if metadata.level() > &Level::INFO { + /// return false; + /// } + /// + /// // If any span in the current scope is named "interesting_span", + /// // enable this span or event. + /// for span in cx.lookup_current().iter().flat_map(|span| span.scope()) { + /// if span.name() == "interesting_span" { + /// return true; + /// } + /// } + /// + /// // Otherwise, disable it. + /// false + /// }) + /// // Since the filter closure will only enable the `INFO` level and + /// // below, set the max level hint + /// .with_max_level_hint(LevelFilter::INFO); + /// + /// let my_layer = tracing_subscriber::fmt::layer(); + /// + /// tracing_subscriber::registry() + /// .with(my_layer.with_filter(my_filter)) + /// .init(); + /// ``` + /// + /// [`Level`]: tracing_core::Level + /// [`Filter::max_level_hint`]: crate::layer::Filter::max_level_hint + pub fn with_max_level_hint(self, max_level_hint: impl Into) -> Self { + Self { + max_level_hint: Some(max_level_hint.into()), + ..self + } + } + + /// Adds a function for filtering callsites to this filter. + /// + /// When this filter's [`Filter::callsite_enabled`][cse] method is called, + /// the provided function will be used rather than the default. + /// + /// By default, `DynFilterFn` assumes that, because the filter _may_ depend + /// dynamically on the current [span context], its result should never be + /// cached. However, some filtering strategies may require dynamic information + /// from the current span context in *some* cases, but are able to make + /// static filtering decisions from [`Metadata`] alone in others. + /// + /// For example, consider the filter given in the example for + /// [`DynFilterFn::new`]. That filter enables all spans named + /// "interesting_span", and any events and spans that occur inside of an + /// interesting span. Since the span's name is part of its static + /// [`Metadata`], the "interesting_span" can be enabled in + /// [`callsite_enabled`][cse]: + /// + /// ``` + /// use tracing_subscriber::{ + /// layer::{Layer, SubscriberExt}, + /// filter::DynFilterFn, + /// util::SubscriberInitExt, + /// }; + /// use tracing_core::subscriber::Interest; + /// + /// // Only enable spans or events within a span named "interesting_span". + /// let my_filter = DynFilterFn::new(|metadata, cx| { + /// // If this *is* "interesting_span", make sure to enable it. + /// if metadata.is_span() && metadata.name() == "interesting_span" { + /// return true; + /// } + /// + /// // Otherwise, are we in an interesting span? + /// if let Some(current_span) = cx.lookup_current() { + /// return current_span.name() == "interesting_span"; + /// } + /// + /// false + /// }).with_callsite_filter(|metadata| { + /// // If this is an "interesting_span", we know we will always + /// // enable it. + /// if metadata.is_span() && metadata.name() == "interesting_span" { + /// return Interest::always(); + /// } + /// + /// // Otherwise, it depends on whether or not we're in an interesting + /// // span. You'll have to ask us again for each span/event! + /// Interest::sometimes() + /// }); + /// + /// let my_layer = tracing_subscriber::fmt::layer(); + /// + /// tracing_subscriber::registry() + /// .with(my_layer.with_filter(my_filter)) + /// .init(); + /// ``` + /// + /// [cse]: crate::layer::Filter::callsite_enabled + /// [`enabled`]: crate::layer::Filter::enabled + /// [`Metadata`]: tracing_core::Metadata + /// [span context]: crate::layer::Context + pub fn with_callsite_filter(self, callsite_enabled: R2) -> DynFilterFn + where + R2: Fn(&'static Metadata<'static>) -> Interest, + { + let register_callsite = Some(callsite_enabled); + let DynFilterFn { + enabled, + max_level_hint, + _s, + .. + } = self; + DynFilterFn { + enabled, + register_callsite, + max_level_hint, + _s, + } + } + + fn default_callsite_enabled(&self, metadata: &Metadata<'_>) -> Interest { + // If it's below the configured max level, assume that `enabled` will + // never enable it... + if !is_below_max_level(&self.max_level_hint, metadata) { + debug_assert!( + !(self.enabled)(metadata, &Context::none()), + "DynFilterFn<{}> claimed it would only enable {:?} and below, \ + but it enabled metadata with the {:?} level\nmetadata={:#?}", + type_name::(), + self.max_level_hint.unwrap(), + metadata.level(), + metadata, + ); + return Interest::never(); + } + + // Otherwise, since this `enabled` function is dynamic and depends on + // the current context, we don't know whether this span or event will be + // enabled or not. Ask again every time it's recorded! + Interest::sometimes() + } +} + +impl DynFilterFn +where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, + R: Fn(&'static Metadata<'static>) -> Interest, +{ + #[inline] + fn is_enabled(&self, metadata: &Metadata<'_>, cx: &Context<'_, S>) -> bool { + let enabled = (self.enabled)(metadata, cx); + debug_assert!( + !enabled || is_below_max_level(&self.max_level_hint, metadata), + "DynFilterFn<{}> claimed it would only enable {:?} and below, \ + but it enabled metadata with the {:?} level\nmetadata={:#?}", + type_name::(), + self.max_level_hint.unwrap(), + metadata.level(), + metadata, + ); + + enabled + } + + #[inline] + fn is_callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { + let interest = self + .register_callsite + .as_ref() + .map(|callsite_enabled| callsite_enabled(metadata)) + .unwrap_or_else(|| self.default_callsite_enabled(metadata)); + debug_assert!( + interest.is_never() || is_below_max_level(&self.max_level_hint, metadata), + "DynFilterFn<{}, {}> claimed it was only interested in {:?} and below, \ + but it enabled metadata with the {:?} level\nmetadata={:#?}", + type_name::(), + type_name::(), + self.max_level_hint.unwrap(), + metadata.level(), + metadata, + ); + + interest + } +} + +impl Layer for DynFilterFn +where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool + 'static, + R: Fn(&'static Metadata<'static>) -> Interest + 'static, + S: Subscriber, +{ + fn enabled(&self, metadata: &Metadata<'_>, cx: Context<'_, S>) -> bool { + self.is_enabled(metadata, &cx) + } + + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + self.is_callsite_enabled(metadata) + } + + fn max_level_hint(&self) -> Option { + self.max_level_hint + } +} + +impl fmt::Debug for DynFilterFn { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("DynFilterFn"); + s.field("enabled", &format_args!("{}", type_name::())); + if self.register_callsite.is_some() { + s.field( + "register_callsite", + &format_args!("Some({})", type_name::()), + ); + } else { + s.field("register_callsite", &format_args!("None")); + } + + s.field("max_level_hint", &self.max_level_hint).finish() + } +} + +impl Clone for DynFilterFn +where + F: Clone, + R: Clone, +{ + fn clone(&self) -> Self { + Self { + enabled: self.enabled.clone(), + register_callsite: self.register_callsite.clone(), + max_level_hint: self.max_level_hint, + _s: PhantomData, + } + } +} + +impl From for DynFilterFn +where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, +{ + fn from(f: F) -> Self { + Self::new(f) + } +} + +// === PLF impls === + +feature! { + #![all(feature = "registry", feature = "std")] + use crate::layer::Filter; + + impl Filter for FilterFn + where + F: Fn(&Metadata<'_>) -> bool, + { + fn enabled(&self, metadata: &Metadata<'_>, _: &Context<'_, S>) -> bool { + self.is_enabled(metadata) + } + + fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { + self.is_callsite_enabled(metadata) + } + + fn max_level_hint(&self) -> Option { + self.max_level_hint + } + } + + impl Filter for DynFilterFn + where + F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, + R: Fn(&'static Metadata<'static>) -> Interest, + { + fn enabled(&self, metadata: &Metadata<'_>, cx: &Context<'_, S>) -> bool { + self.is_enabled(metadata, cx) + } + + fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { + self.is_callsite_enabled(metadata) + } + + fn max_level_hint(&self) -> Option { + self.max_level_hint + } + } +} + +fn is_below_max_level(hint: &Option, metadata: &Metadata<'_>) -> bool { + hint.as_ref() + .map(|hint| metadata.level() <= hint) + .unwrap_or(true) +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/layer_filters.rs b/vendor/tracing-subscriber-0.3.3/src/filter/layer_filters.rs new file mode 100644 index 000000000..e77fd3751 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/layer_filters.rs @@ -0,0 +1,830 @@ +//! ## Per-Layer Filtering +//! +//! Per-layer filters permit individual `Layer`s to have their own filter +//! configurations without interfering with other `Layer`s. +//! +//! This module is not public; the public APIs defined in this module are +//! re-exported in the top-level `filter` module. Therefore, this documentation +//! primarily concerns the internal implementation details. For the user-facing +//! public API documentation, see the individual public types in this module, as +//! well as the, see the `Layer` trait documentation's [per-layer filtering +//! section]][1]. +//! +//! ## How does per-layer filtering work? +//! +//! As described in the API documentation, the [`Filter`] trait defines a +//! filtering strategy for a per-layer filter. We expect there will be a variety +//! of implementations of [`Filter`], both in `tracing-subscriber` and in user +//! code. +//! +//! To actually *use* a [`Filter`] implementation, it is combined with a +//! [`Layer`] by the [`Filtered`] struct defined in this module. [`Filtered`] +//! implements [`Layer`] by calling into the wrapped [`Layer`], or not, based on +//! the filtering strategy. While there will be a variety of types that implement +//! [`Filter`], all actual *uses* of per-layer filtering will occur through the +//! [`Filtered`] struct. Therefore, most of the implementation details live +//! there. +//! +//! [1]: crate::layer#per-layer-filtering +//! [`Filter`]: crate::layer::Filter +use crate::{ + filter::LevelFilter, + layer::{self, Context, Layer}, + registry, +}; +use std::{ + any::TypeId, + cell::{Cell, RefCell}, + fmt, + marker::PhantomData, + sync::Arc, + thread_local, +}; +use tracing_core::{ + span, + subscriber::{Interest, Subscriber}, + Event, Metadata, +}; + +/// A [`Layer`] that wraps an inner [`Layer`] and adds a [`Filter`] which +/// controls what spans and events are enabled for that layer. +/// +/// This is returned by the [`Layer::with_filter`] method. See the +/// [documentation on per-layer filtering][plf] for details. +/// +/// [`Filter`]: crate::layer::Filter +/// [plf]: crate::layer#per-layer-filtering +#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] +#[derive(Clone)] +pub struct Filtered { + filter: F, + layer: L, + id: MagicPlfDowncastMarker, + _s: PhantomData, +} + +/// Uniquely identifies an individual [`Filter`] instance in the context of +/// a [`Subscriber`]. +/// +/// When adding a [`Filtered`] [`Layer`] to a [`Subscriber`], the [`Subscriber`] +/// generates a `FilterId` for that [`Filtered`] layer. The [`Filtered`] layer +/// will then use the generated ID to query whether a particular span was +/// previously enabled by that layer's [`Filter`]. +/// +/// **Note**: Currently, the [`Registry`] type provided by this crate is the +/// **only** [`Subscriber`] implementation capable of participating in per-layer +/// filtering. Therefore, the `FilterId` type cannot currently be constructed by +/// code outside of `tracing-subscriber`. In the future, new APIs will be added to `tracing-subscriber` to +/// allow non-Registry [`Subscriber`]s to also participate in per-layer +/// filtering. When those APIs are added, subscribers will be responsible +/// for generating and assigning `FilterId`s. +/// +/// [`Filter`]: crate::layer::Filter +/// [`Subscriber`]: tracing_core::Subscriber +/// [`Layer`]: crate::layer::Layer +/// [`Registry`]: crate::registry::Registry +#[cfg(feature = "registry")] +#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] +#[derive(Copy, Clone)] +pub struct FilterId(u64); + +/// A bitmap tracking which [`FilterId`]s have enabled a given span or +/// event. +/// +/// This is currently a private type that's used exclusively by the +/// [`Registry`]. However, in the future, this may become a public API, in order +/// to allow user subscribers to host [`Filter`]s. +/// +/// [`Registry`]: crate::Registry +/// [`Filter`]: crate::layer::Filter +#[derive(Default, Copy, Clone, Eq, PartialEq)] +pub(crate) struct FilterMap { + bits: u64, +} + +/// The current state of `enabled` calls to per-layer filters on this +/// thread. +/// +/// When `Filtered::enabled` is called, the filter will set the bit +/// corresponding to its ID if the filter will disable the event/span being +/// filtered. When the event or span is recorded, the per-layer filter will +/// check its bit to determine if it disabled that event or span, and skip +/// forwarding the event or span to the inner layer if the bit is set. Once +/// a span or event has been skipped by a per-layer filter, it unsets its +/// bit, so that the `FilterMap` has been cleared for the next set of +/// `enabled` calls. +/// +/// FilterState is also read by the `Registry`, for two reasons: +/// +/// 1. When filtering a span, the Registry must store the `FilterMap` +/// generated by `Filtered::enabled` calls for that span as part of the +/// span's per-span data. This allows `Filtered` layers to determine +/// whether they had previously disabled a given span, and avoid showing it +/// to the wrapped layer if it was disabled. +/// +/// This allows `Filtered` layers to also filter out the spans they +/// disable from span traversals (such as iterating over parents, etc). +/// 2. If all the bits are set, then every per-layer filter has decided it +/// doesn't want to enable that span or event. In that case, the +/// `Registry`'s `enabled` method will return `false`, so that +/// recording a span or event can be skipped entirely. +#[derive(Debug)] +pub(crate) struct FilterState { + enabled: Cell, + // TODO(eliza): `Interest`s should _probably_ be `Copy`. The only reason + // they're not is our Obsessive Commitment to Forwards-Compatibility. If + // this changes in tracing-core`, we can make this a `Cell` rather than + // `RefCell`... + interest: RefCell>, + + #[cfg(debug_assertions)] + counters: DebugCounters, +} + +/// Extra counters added to `FilterState` used only to make debug assertions. +#[cfg(debug_assertions)] +#[derive(Debug, Default)] +struct DebugCounters { + /// How many per-layer filters have participated in the current `enabled` + /// call? + in_filter_pass: Cell, + + /// How many per-layer filters have participated in the current `register_callsite` + /// call? + in_interest_pass: Cell, +} + +thread_local! { + pub(crate) static FILTERING: FilterState = FilterState::new(); +} + +// === impl Filter === +#[cfg(feature = "registry")] +#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] +impl layer::Filter for LevelFilter { + fn enabled(&self, meta: &Metadata<'_>, _: &Context<'_, S>) -> bool { + meta.level() <= self + } + + fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { + if meta.level() <= self { + Interest::always() + } else { + Interest::never() + } + } + + fn max_level_hint(&self) -> Option { + Some(*self) + } +} + +impl layer::Filter for Arc + Send + Sync + 'static> { + #[inline] + fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool { + (**self).enabled(meta, cx) + } + + #[inline] + fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { + (**self).callsite_enabled(meta) + } + + #[inline] + fn max_level_hint(&self) -> Option { + (**self).max_level_hint() + } +} + +impl layer::Filter for Box + Send + Sync + 'static> { + #[inline] + fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool { + (**self).enabled(meta, cx) + } + + #[inline] + fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { + (**self).callsite_enabled(meta) + } + + #[inline] + fn max_level_hint(&self) -> Option { + (**self).max_level_hint() + } +} + +// === impl Filtered === + +impl Filtered { + /// Wraps the provided [`Layer`] so that it is filtered by the given + /// [`Filter`]. + /// + /// This is equivalent to calling the [`Layer::with_filter`] method. + /// + /// See the [documentation on per-layer filtering][plf] for details. + /// + /// [`Filter`]: crate::layer::Filter + /// [plf]: crate::layer#per-layer-filtering + pub fn new(layer: L, filter: F) -> Self { + Self { + layer, + filter, + id: MagicPlfDowncastMarker(FilterId::disabled()), + _s: PhantomData, + } + } + + #[inline(always)] + fn id(&self) -> FilterId { + debug_assert!( + !self.id.0.is_disabled(), + "a `Filtered` layer was used, but it had no `FilterId`; \ + was it registered with the subscriber?" + ); + self.id.0 + } + + fn did_enable(&self, f: impl FnOnce()) { + FILTERING.with(|filtering| filtering.did_enable(self.id(), f)) + } +} + +impl Layer for Filtered +where + S: Subscriber + for<'span> registry::LookupSpan<'span> + 'static, + F: layer::Filter + 'static, + L: Layer, +{ + fn on_layer(&mut self, subscriber: &mut S) { + self.id = MagicPlfDowncastMarker(subscriber.register_filter()); + self.layer.on_layer(subscriber); + } + + // TODO(eliza): can we figure out a nice way to make the `Filtered` layer + // not call `is_enabled_for` in hooks that the inner layer doesn't actually + // have real implementations of? probably not... + // + // it would be cool if there was some wild rust reflection way of checking + // if a trait impl has the default impl of a trait method or not, but that's + // almsot certainly impossible...right? + + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + let interest = self.filter.callsite_enabled(metadata); + + // If the filter didn't disable the callsite, allow the inner layer to + // register it — since `register_callsite` is also used for purposes + // such as reserving/caching per-callsite data, we want the inner layer + // to be able to perform any other registration steps. However, we'll + // ignore its `Interest`. + if !interest.is_never() { + self.layer.register_callsite(metadata); + } + + // Add our `Interest` to the current sum of per-layer filter `Interest`s + // for this callsite. + FILTERING.with(|filtering| filtering.add_interest(interest)); + + // don't short circuit! if the stack consists entirely of `Layer`s with + // per-layer filters, the `Registry` will return the actual `Interest` + // value that's the sum of all the `register_callsite` calls to those + // per-layer filters. if we returned an actual `never` interest here, a + // `Layered` layer would short-circuit and not allow any `Filtered` + // layers below us if _they_ are interested in the callsite. + Interest::always() + } + + fn enabled(&self, metadata: &Metadata<'_>, cx: Context<'_, S>) -> bool { + let cx = cx.with_filter(self.id()); + let enabled = self.filter.enabled(metadata, &cx); + FILTERING.with(|filtering| filtering.set(self.id(), enabled)); + + if enabled { + // If the filter enabled this metadata, ask the wrapped layer if + // _it_ wants it --- it might have a global filter. + self.layer.enabled(metadata, cx) + } else { + // Otherwise, return `true`. The _per-layer_ filter disabled this + // metadata, but returning `false` in `Layer::enabled` will + // short-circuit and globally disable the span or event. This is + // *not* what we want for per-layer filters, as other layers may + // still want this event. Returning `true` here means we'll continue + // asking the next layer in the stack. + // + // Once all per-layer filters have been evaluated, the `Registry` + // at the root of the stack will return `false` from its `enabled` + // method if *every* per-layer filter disabled this metadata. + // Otherwise, the individual per-layer filters will skip the next + // `new_span` or `on_event` call for their layer if *they* disabled + // the span or event, but it was not globally disabled. + true + } + } + + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, cx: Context<'_, S>) { + self.did_enable(|| { + self.layer.on_new_span(attrs, id, cx.with_filter(self.id())); + }) + } + + #[doc(hidden)] + fn max_level_hint(&self) -> Option { + self.filter.max_level_hint() + } + + fn on_record(&self, span: &span::Id, values: &span::Record<'_>, cx: Context<'_, S>) { + if let Some(cx) = cx.if_enabled_for(span, self.id()) { + self.layer.on_record(span, values, cx) + } + } + + fn on_follows_from(&self, span: &span::Id, follows: &span::Id, cx: Context<'_, S>) { + // only call `on_follows_from` if both spans are enabled by us + if cx.is_enabled_for(span, self.id()) && cx.is_enabled_for(follows, self.id()) { + self.layer + .on_follows_from(span, follows, cx.with_filter(self.id())) + } + } + + fn on_event(&self, event: &Event<'_>, cx: Context<'_, S>) { + self.did_enable(|| { + self.layer.on_event(event, cx.with_filter(self.id())); + }) + } + + fn on_enter(&self, id: &span::Id, cx: Context<'_, S>) { + if let Some(cx) = cx.if_enabled_for(id, self.id()) { + self.layer.on_enter(id, cx) + } + } + + fn on_exit(&self, id: &span::Id, cx: Context<'_, S>) { + if let Some(cx) = cx.if_enabled_for(id, self.id()) { + self.layer.on_exit(id, cx) + } + } + + fn on_close(&self, id: span::Id, cx: Context<'_, S>) { + if let Some(cx) = cx.if_enabled_for(&id, self.id()) { + self.layer.on_close(id, cx) + } + } + + // XXX(eliza): the existence of this method still makes me sad... + fn on_id_change(&self, old: &span::Id, new: &span::Id, cx: Context<'_, S>) { + if let Some(cx) = cx.if_enabled_for(old, self.id()) { + self.layer.on_id_change(old, new, cx) + } + } + + #[doc(hidden)] + #[inline] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + match id { + id if id == TypeId::of::() => Some(self as *const _ as *const ()), + id if id == TypeId::of::() => Some(&self.layer as *const _ as *const ()), + id if id == TypeId::of::() => Some(&self.filter as *const _ as *const ()), + id if id == TypeId::of::() => { + Some(&self.id as *const _ as *const ()) + } + _ => self.layer.downcast_raw(id), + } + } +} + +impl fmt::Debug for Filtered +where + F: fmt::Debug, + L: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Filtered") + .field("filter", &self.filter) + .field("layer", &self.layer) + .field("id", &self.id) + .finish() + } +} + +// === impl FilterId === + +impl FilterId { + const fn disabled() -> Self { + Self(std::u64::MAX) + } + + /// Returns a `FilterId` that will consider _all_ spans enabled. + pub(crate) const fn none() -> Self { + Self(0) + } + + pub(crate) fn new(id: u8) -> Self { + assert!(id < 64, "filter IDs may not be greater than 64"); + Self(1 << id as usize) + } + + /// Combines two `FilterId`s, returning a new `FilterId` that will match a + /// [`FilterMap`] where the span was disabled by _either_ this `FilterId` + /// *or* the combined `FilterId`. + /// + /// This method is called by [`Context`]s when adding the `FilterId` of a + /// [`Filtered`] layer to the context. + /// + /// This is necessary for cases where we have a tree of nested [`Filtered`] + /// layers, like this: + /// + /// ```text + /// Filtered { + /// filter1, + /// Layered { + /// layer1, + /// Filtered { + /// filter2, + /// layer2, + /// }, + /// } + /// ``` + /// + /// We want `layer2` to be affected by both `filter1` _and_ `filter2`. + /// Without combining `FilterId`s, this works fine when filtering + /// `on_event`/`new_span`, because the outer `Filtered` layer (`filter1`) + /// won't call the inner layer's `on_event` or `new_span` callbacks if it + /// disabled the event/span. + /// + /// However, it _doesn't_ work when filtering span lookups and traversals + /// (e.g. `scope`). This is because the [`Context`] passed to `layer2` + /// would set its filter ID to the filter ID of `filter2`, and would skip + /// spans that were disabled by `filter2`. However, what if a span was + /// disabled by `filter1`? We wouldn't see it in `new_span`, but we _would_ + /// see it in lookups and traversals...which we don't want. + /// + /// When a [`Filtered`] layer adds its ID to a [`Context`], it _combines_ it + /// with any previous filter ID that the context had, rather than replacing + /// it. That way, `layer2`'s context will check if a span was disabled by + /// `filter1` _or_ `filter2`. The way we do this, instead of representing + /// `FilterId`s as a number number that we shift a 1 over by to get a mask, + /// we just store the actual mask,so we can combine them with a bitwise-OR. + /// + /// For example, if we consider the following case (pretending that the + /// masks are 8 bits instead of 64 just so i don't have to write out a bunch + /// of extra zeroes): + /// + /// - `filter1` has the filter id 1 (`0b0000_0001`) + /// - `filter2` has the filter id 2 (`0b0000_0010`) + /// + /// A span that gets disabled by filter 1 would have the [`FilterMap`] with + /// bits `0b0000_0001`. + /// + /// If the `FilterId` was internally represented as `(bits to shift + 1), + /// when `layer2`'s [`Context`] checked if it enabled the span, it would + /// make the mask `0b0000_0010` (`1 << 1`). That bit would not be set in the + /// [`FilterMap`], so it would see that it _didn't_ disable the span. Which + /// is *true*, it just doesn't reflect the tree-like shape of the actual + /// subscriber. + /// + /// By having the IDs be masks instead of shifts, though, when the + /// [`Filtered`] with `filter2` gets the [`Context`] with `filter1`'s filter ID, + /// instead of replacing it, it ors them together: + /// + /// ```ignore + /// 0b0000_0001 | 0b0000_0010 == 0b0000_0011; + /// ``` + /// + /// We then test if the span was disabled by seeing if _any_ bits in the + /// mask are `1`: + /// + /// ```ignore + /// filtermap & mask != 0; + /// 0b0000_0001 & 0b0000_0011 != 0; + /// 0b0000_0001 != 0; + /// true; + /// ``` + /// + /// [`Context`]: crate::layer::Context + pub(crate) fn and(self, FilterId(other): Self) -> Self { + // If this mask is disabled, just return the other --- otherwise, we + // would always see that every span is disabled. + if self.0 == Self::disabled().0 { + return Self(other); + } + + Self(self.0 | other) + } + + fn is_disabled(self) -> bool { + self.0 == Self::disabled().0 + } +} + +impl fmt::Debug for FilterId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // don't print a giant set of the numbers 0..63 if the filter ID is disabled. + if self.0 == Self::disabled().0 { + return f + .debug_tuple("FilterId") + .field(&format_args!("DISABLED")) + .finish(); + } + + if f.alternate() { + f.debug_struct("FilterId") + .field("ids", &format_args!("{:?}", FmtBitset(self.0))) + .field("bits", &format_args!("{:b}", self.0)) + .finish() + } else { + f.debug_tuple("FilterId").field(&FmtBitset(self.0)).finish() + } + } +} + +impl fmt::Binary for FilterId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("FilterId") + .field(&format_args!("{:b}", self.0)) + .finish() + } +} + +// === impl FilterMap === + +impl FilterMap { + pub(crate) fn set(self, FilterId(mask): FilterId, enabled: bool) -> Self { + if mask == std::u64::MAX { + return self; + } + + if enabled { + Self { + bits: self.bits & (!mask), + } + } else { + Self { + bits: self.bits | mask, + } + } + } + + #[inline] + pub(crate) fn is_enabled(self, FilterId(mask): FilterId) -> bool { + self.bits & mask == 0 + } + + #[inline] + pub(crate) fn any_enabled(self) -> bool { + self.bits != std::u64::MAX + } +} + +impl fmt::Debug for FilterMap { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let alt = f.alternate(); + let mut s = f.debug_struct("FilterMap"); + s.field("disabled_by", &format_args!("{:?}", &FmtBitset(self.bits))); + + if alt { + s.field("bits", &format_args!("{:b}", self.bits)); + } + + s.finish() + } +} + +impl fmt::Binary for FilterMap { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FilterMap") + .field("bits", &format_args!("{:b}", self.bits)) + .finish() + } +} + +// === impl FilterState === + +impl FilterState { + fn new() -> Self { + Self { + enabled: Cell::new(FilterMap::default()), + interest: RefCell::new(None), + + #[cfg(debug_assertions)] + counters: DebugCounters::default(), + } + } + + fn set(&self, filter: FilterId, enabled: bool) { + #[cfg(debug_assertions)] + { + let in_current_pass = self.counters.in_filter_pass.get(); + if in_current_pass == 0 { + debug_assert_eq!(self.enabled.get(), FilterMap::default()); + } + self.counters.in_filter_pass.set(in_current_pass + 1); + debug_assert_eq!( + self.counters.in_interest_pass.get(), + 0, + "if we are in or starting a filter pass, we must not be in an interest pass." + ) + } + + self.enabled.set(self.enabled.get().set(filter, enabled)) + } + + fn add_interest(&self, interest: Interest) { + let mut curr_interest = self.interest.borrow_mut(); + + #[cfg(debug_assertions)] + { + let in_current_pass = self.counters.in_interest_pass.get(); + if in_current_pass == 0 { + debug_assert!(curr_interest.is_none()); + } + self.counters.in_interest_pass.set(in_current_pass + 1); + } + + if let Some(curr_interest) = curr_interest.as_mut() { + if (curr_interest.is_always() && !interest.is_always()) + || (curr_interest.is_never() && !interest.is_never()) + { + *curr_interest = Interest::sometimes(); + } + // If the two interests are the same, do nothing. If the current + // interest is `sometimes`, stay sometimes. + } else { + *curr_interest = Some(interest); + } + } + + pub(crate) fn event_enabled() -> bool { + FILTERING + .try_with(|this| { + let enabled = this.enabled.get().any_enabled(); + #[cfg(debug_assertions)] + { + if this.counters.in_filter_pass.get() == 0 { + debug_assert_eq!(this.enabled.get(), FilterMap::default()); + } + + // Nothing enabled this event, we won't tick back down the + // counter in `did_enable`. Reset it. + if !enabled { + this.counters.in_filter_pass.set(0); + } + } + enabled + }) + .unwrap_or(true) + } + + /// Executes a closure if the filter with the provided ID did not disable + /// the current span/event. + /// + /// This is used to implement the `on_event` and `new_span` methods for + /// `Filtered`. + fn did_enable(&self, filter: FilterId, f: impl FnOnce()) { + let map = self.enabled.get(); + if map.is_enabled(filter) { + // If the filter didn't disable the current span/event, run the + // callback. + f(); + } else { + // Otherwise, if this filter _did_ disable the span or event + // currently being processed, clear its bit from this thread's + // `FilterState`. The bit has already been "consumed" by skipping + // this callback, and we need to ensure that the `FilterMap` for + // this thread is reset when the *next* `enabled` call occurs. + self.enabled.set(map.set(filter, true)); + } + #[cfg(debug_assertions)] + { + let in_current_pass = self.counters.in_filter_pass.get(); + if in_current_pass <= 1 { + debug_assert_eq!(self.enabled.get(), FilterMap::default()); + } + self.counters + .in_filter_pass + .set(in_current_pass.saturating_sub(1)); + debug_assert_eq!( + self.counters.in_interest_pass.get(), + 0, + "if we are in a filter pass, we must not be in an interest pass." + ) + } + } + + /// Clears the current in-progress filter state. + /// + /// This resets the [`FilterMap`] and current [`Interest`] as well as + /// clearing the debug counters. + pub(crate) fn clear_enabled() { + // Drop the `Result` returned by `try_with` --- if we are in the middle + // a panic and the thread-local has been torn down, that's fine, just + // ignore it ratehr than panicking. + let _ = FILTERING.try_with(|filtering| { + filtering.enabled.set(FilterMap::default()); + + #[cfg(debug_assertions)] + filtering.counters.in_filter_pass.set(0); + }); + } + + pub(crate) fn take_interest() -> Option { + FILTERING + .try_with(|filtering| { + #[cfg(debug_assertions)] + { + if filtering.counters.in_interest_pass.get() == 0 { + debug_assert!(filtering.interest.try_borrow().ok()?.is_none()); + } + filtering.counters.in_interest_pass.set(0); + } + filtering.interest.try_borrow_mut().ok()?.take() + }) + .ok()? + } + + pub(crate) fn filter_map(&self) -> FilterMap { + let map = self.enabled.get(); + #[cfg(debug_assertions)] + { + if self.counters.in_filter_pass.get() == 0 { + debug_assert_eq!(map, FilterMap::default()); + } + } + + map + } +} +/// This is a horrible and bad abuse of the downcasting system to expose +/// *internally* whether a layer has per-layer filtering, within +/// `tracing-subscriber`, without exposing a public API for it. +/// +/// If a `Layer` has per-layer filtering, it will downcast to a +/// `MagicPlfDowncastMarker`. Since layers which contain other layers permit +/// downcasting to recurse to their children, this will do the Right Thing with +/// layers like Reload, Option, etc. +/// +/// Why is this a wrapper around the `FilterId`, you may ask? Because +/// downcasting works by returning a pointer, and we don't want to risk +/// introducing UB by constructing pointers that _don't_ point to a valid +/// instance of the type they claim to be. In this case, we don't _intend_ for +/// this pointer to be dereferenced, so it would actually be fine to return one +/// that isn't a valid pointer...but we can't guarantee that the caller won't +/// (accidentally) dereference it, so it's better to be safe than sorry. We +/// could, alternatively, add an additional field to the type that's used only +/// for returning pointers to as as part of the evil downcasting hack, but I +/// thought it was nicer to just add a `repr(transparent)` wrapper to the +/// existing `FilterId` field, since it won't make the struct any bigger. +/// +/// Don't worry, this isn't on the test. :) +#[derive(Clone, Copy)] +#[repr(transparent)] +struct MagicPlfDowncastMarker(FilterId); +impl fmt::Debug for MagicPlfDowncastMarker { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Just pretend that `MagicPlfDowncastMarker` doesn't exist for + // `fmt::Debug` purposes...if no one *sees* it in their `Debug` output, + // they don't have to know I thought this code would be a good idea. + fmt::Debug::fmt(&self.0, f) + } +} + +pub(crate) fn is_plf_downcast_marker(type_id: TypeId) -> bool { + type_id == TypeId::of::() +} + +/// Does a type implementing `Subscriber` contain any per-layer filters? +pub(crate) fn subscriber_has_plf(subscriber: &S) -> bool +where + S: Subscriber, +{ + (subscriber as &dyn Subscriber).is::() +} + +/// Does a type implementing `Layer` contain any per-layer filters? +pub(crate) fn layer_has_plf(layer: &L) -> bool +where + L: Layer, + S: Subscriber, +{ + unsafe { + // Safety: we're not actually *doing* anything with this pointer --- we + // only care about the `Option`, which we're turning into a `bool`. So + // even if the layer decides to be evil and give us some kind of invalid + // pointer, we don't ever dereference it, so this is always safe. + layer.downcast_raw(TypeId::of::()) + } + .is_some() +} + +struct FmtBitset(u64); + +impl fmt::Debug for FmtBitset { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut set = f.debug_set(); + for bit in 0..64 { + // if the `bit`-th bit is set, add it to the debug set + if self.0 & (1 << bit) != 0 { + set.entry(&bit); + } + } + set.finish() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/level.rs b/vendor/tracing-subscriber-0.3.3/src/filter/level.rs new file mode 100644 index 000000000..0fa601260 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/level.rs @@ -0,0 +1,27 @@ +use tracing_core::{ + subscriber::{Interest, Subscriber}, + Metadata, +}; + +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use tracing_core::metadata::{LevelFilter, ParseLevelFilterError as ParseError}; + +// === impl LevelFilter === + +impl crate::Layer for LevelFilter { + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + if self >= metadata.level() { + Interest::always() + } else { + Interest::never() + } + } + + fn enabled(&self, metadata: &Metadata<'_>, _: crate::layer::Context<'_, S>) -> bool { + self >= metadata.level() + } + + fn max_level_hint(&self) -> Option { + Some(*self) + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/mod.rs b/vendor/tracing-subscriber-0.3.3/src/filter/mod.rs new file mode 100644 index 000000000..000a27195 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/mod.rs @@ -0,0 +1,66 @@ +//! [`Layer`]s that control which spans and events are enabled by the wrapped +//! subscriber. +//! +//! This module contains a number of types that provide implementations of +//! various strategies for filtering which spans and events are enabled. For +//! details on filtering spans and events using [`Layer`]s, see the +//! [`layer` module's documentation]. +//! +//! [`layer` module's documentation]: crate::layer#filtering-with-layers +//! [`Layer`]: crate::layer +mod filter_fn; + +feature! { + #![all(feature = "env-filter", feature = "std")] + mod env; + pub use self::env::*; +} + +feature! { + #![all(feature = "registry", feature = "std")] + mod layer_filters; + pub use self::layer_filters::*; +} + +mod level; + +pub use self::filter_fn::*; +pub use self::level::{LevelFilter, ParseError as LevelParseError}; + +#[cfg(not(all(feature = "registry", feature = "std")))] +pub(crate) use self::has_plf_stubs::*; + +feature! { + #![any(feature = "std", feature = "alloc")] + pub mod targets; + pub use self::targets::Targets; + + mod directive; + pub use self::directive::ParseError; +} + +/// Stub implementations of the per-layer-fitler detection functions for when the +/// `registry` feature is disabled. +#[cfg(not(all(feature = "registry", feature = "std")))] +mod has_plf_stubs { + pub(crate) fn is_plf_downcast_marker(_: core::any::TypeId) -> bool { + false + } + + /// Does a type implementing `Subscriber` contain any per-layer filters? + pub(crate) fn subscriber_has_plf(_: &S) -> bool + where + S: tracing_core::Subscriber, + { + false + } + + /// Does a type implementing `Layer` contain any per-layer filters? + pub(crate) fn layer_has_plf(_: &L) -> bool + where + L: crate::Layer, + S: tracing_core::Subscriber, + { + false + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/filter/targets.rs b/vendor/tracing-subscriber-0.3.3/src/filter/targets.rs new file mode 100644 index 000000000..e0c7fcf82 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/filter/targets.rs @@ -0,0 +1,681 @@ +//! A [filter] that enables or disables spans and events based on their [target] and [level]. +//! +//! See [`Targets`] for details. +//! +//! [target]: tracing_core::Metadata::target +//! [level]: tracing_core::Level +//! [filter]: crate::layer#filtering-with-layers + +use crate::{ + filter::{ + directive::{DirectiveSet, ParseError, StaticDirective}, + LevelFilter, + }, + layer, +}; +#[cfg(not(feature = "std"))] +use alloc::string::String; +use core::{ + iter::{Extend, FilterMap, FromIterator}, + slice, + str::FromStr, +}; +use tracing_core::{Interest, Metadata, Subscriber}; + +/// A filter that enables or disables spans and events based on their [target] +/// and [level]. +/// +/// Targets are typically equal to the Rust module path of the code where the +/// span or event was recorded, although they may be overridden. +/// +/// This type can be used for both [per-layer filtering][plf] (using its +/// [`Filter`] implementation) and [global filtering][global] (using its +/// [`Layer`] implementation). +/// +/// See the [documentation on filtering with layers][filtering] for details. +/// +/// # Filtering With `Targets` +/// +/// A `Targets` filter consists of one or more [target] prefixes, paired with +/// [`LevelFilter`]s. If a span or event's [target] begins with one of those +/// prefixes, and its [level] is at or below the [`LevelFilter`] enabled for +/// that prefix, then the span or event will be enabled. +/// +/// This is similar to the behavior implemented by the [`env_logger` crate] in +/// the `log` ecosystem. +/// +/// The [`EnvFilter`] type also provided by this crate is very similar to `Targets`, +/// but is capable of a more sophisticated form of filtering where events may +/// also be enabled or disabled based on the span they are recorded in. +/// `Targets` can be thought of as a lighter-weight form of [`EnvFilter`] that +/// can be used instead when this dynamic filtering is not required. +/// +/// # Examples +/// +/// A `Targets` filter can be constructed by programmatically adding targets and +/// levels to enable: +/// +/// ``` +/// use tracing_subscriber::{filter, prelude::*}; +/// use tracing_core::Level; +/// +/// let filter = filter::Targets::new() +/// // Enable the `INFO` level for anything in `my_crate` +/// .with_target("my_crate", Level::INFO) +/// // Enable the `DEBUG` level for a specific module. +/// .with_target("my_crate::interesting_module", Level::DEBUG); +/// +/// // Build a new subscriber with the `fmt` layer using the `Targets` +/// // filter we constructed above. +/// tracing_subscriber::registry() +/// .with(tracing_subscriber::fmt::layer()) +/// .with(filter) +/// .init(); +/// ``` +/// +/// [`LevelFilter::OFF`] can be used to disable a particular target: +/// ``` +/// use tracing_subscriber::filter::{Targets, LevelFilter}; +/// use tracing_core::Level; +/// +/// let filter = Targets::new() +/// .with_target("my_crate", Level::INFO) +/// // Disable all traces from `annoying_module`. +/// .with_target("my_crate::annoying_module", LevelFilter::OFF); +/// # drop(filter); +/// ``` +/// +/// Alternatively, `Targets` implements [`std::str::FromStr`], allowing it to be +/// parsed from a comma-delimited list of `target=level` pairs. For example: +/// +/// ```rust +/// # fn main() -> Result<(), Box> { +/// use tracing_subscriber::filter; +/// use tracing_core::Level; +/// +/// let filter = "my_crate=info,my_crate::interesting_module=trace,other_crate=debug" +/// .parse::()?; +/// +/// // The parsed filter is identical to a filter constructed using `with_target`: +/// assert_eq!( +/// filter, +/// filter::Targets::new() +/// .with_target("my_crate", Level::INFO) +/// .with_target("my_crate::interesting_module", Level::TRACE) +/// .with_target("other_crate", Level::DEBUG) +/// ); +/// # Ok(()) } +/// ``` +/// +/// This is particularly useful when the list of enabled targets is configurable +/// by the user at runtime. +/// +/// The `Targets` filter can be used as a [per-layer filter][plf] *and* as a +/// [global filter]: +/// +/// ```rust +/// use tracing_subscriber::{ +/// fmt, +/// filter::{Targets, LevelFilter}, +/// prelude::*, +/// }; +/// use tracing_core::Level; +/// use std::{sync::Arc, fs::File}; +/// # fn docs() -> Result<(), Box> { +/// +/// // A layer that logs events to stdout using the human-readable "pretty" +/// // format. +/// let stdout_log = fmt::layer().pretty(); +/// +/// // A layer that logs events to a file, using the JSON format. +/// let file = File::create("debug_log.json")?; +/// let debug_log = fmt::layer() +/// .with_writer(Arc::new(file)) +/// .json(); +/// +/// tracing_subscriber::registry() +/// // Only log INFO and above to stdout, unless the span or event +/// // has the `my_crate::cool_module` target prefix. +/// .with(stdout_log +/// .with_filter( +/// Targets::default() +/// .with_target("my_crate::cool_module", Level::DEBUG) +/// .with_default(Level::INFO) +/// ) +/// ) +/// // Log everything enabled by the global filter to `debug_log.json`. +/// .with(debug_log) +/// // Configure a global filter for the whole subscriber stack. This will +/// // control what spans and events are recorded by both the `debug_log` +/// // and the `stdout_log` layers, and `stdout_log` will *additionally* be +/// // filtered by its per-layer filter. +/// .with( +/// Targets::default() +/// .with_target("my_crate", Level::TRACE) +/// .with_target("other_crate", Level::INFO) +/// .with_target("other_crate::annoying_module", LevelFilter::OFF) +/// .with_target("third_crate", Level::DEBUG) +/// ).init(); +/// # Ok(()) } +///``` +/// +/// [target]: tracing_core::Metadata::target +/// [level]: tracing_core::Level +/// [`Filter`]: crate::layer::Filter +/// [`Layer`]: crate::layer::Layer +/// [plf]: crate::layer#per-layer-filtering +/// [global]: crate::layer#global-filtering +/// [filtering]: crate::layer#filtering-with-layers +/// [`env_logger` crate]: https://docs.rs/env_logger/0.9.0/env_logger/index.html#enabling-logging +/// [`EnvFilter`]: crate::filter::EnvFilter +#[derive(Debug, Default, Clone, PartialEq)] +pub struct Targets(DirectiveSet); + +impl Targets { + /// Returns a new `Targets` filter. + /// + /// This filter will enable no targets. Call [`with_target`] or [`with_targets`] + /// to add enabled targets, and [`with_default`] to change the default level + /// enabled for spans and events that didn't match any of the provided targets. + /// + /// [`with_target`]: Targets::with_target + /// [`with_targets`]: Targets::with_targets + /// [`with_default`]: Targets::with_default + pub fn new() -> Self { + Self::default() + } + + /// Enables spans and events with [target]s starting with the provided target + /// prefix if they are at or below the provided [`LevelFilter`]. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::filter; + /// use tracing_core::Level; + /// + /// let filter = filter::Targets::new() + /// // Enable the `INFO` level for anything in `my_crate` + /// .with_target("my_crate", Level::INFO) + /// // Enable the `DEBUG` level for a specific module. + /// .with_target("my_crate::interesting_module", Level::DEBUG); + /// # drop(filter); + /// ``` + /// + /// [`LevelFilter::OFF`] can be used to disable a particular target: + /// ``` + /// use tracing_subscriber::filter::{Targets, LevelFilter}; + /// use tracing_core::Level; + /// + /// let filter = Targets::new() + /// .with_target("my_crate", Level::INFO) + /// // Disable all traces from `annoying_module`. + /// .with_target("my_crate::interesting_module", LevelFilter::OFF); + /// # drop(filter); + /// ``` + /// + /// [target]: tracing_core::Metadata::target + pub fn with_target(mut self, target: impl Into, level: impl Into) -> Self { + self.0.add(StaticDirective::new( + Some(target.into()), + Default::default(), + level.into(), + )); + self + } + /// Adds [target]s from an iterator of [target]-[`LevelFilter`] pairs to this filter. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::filter; + /// use tracing_core::Level; + /// + /// let filter = filter::Targets::new() + /// .with_targets(vec![ + /// ("my_crate", Level::INFO), + /// ("my_crate::some_module", Level::DEBUG), + /// ("my_crate::other_module::cool_stuff", Level::TRACE), + /// ("other_crate", Level::WARN) + /// ]); + /// # drop(filter); + /// ``` + /// + /// [`LevelFilter::OFF`] can be used to disable a particular target: + /// ``` + /// use tracing_subscriber::filter::{Targets, LevelFilter}; + /// use tracing_core::Level; + /// + /// let filter = Targets::new() + /// .with_target("my_crate", Level::INFO) + /// // Disable all traces from `annoying_module`. + /// .with_target("my_crate::interesting_module", LevelFilter::OFF); + /// # drop(filter); + /// ``` + /// + /// [target]: tracing_core::Metadata::target + pub fn with_targets(mut self, targets: impl IntoIterator) -> Self + where + String: From, + LevelFilter: From, + { + self.extend(targets); + self + } + + /// Sets the default level to enable for spans and events whose targets did + /// not match any of the configured prefixes. + /// + /// By default, this is [`LevelFilter::OFF`]. This means that spans and + /// events will only be enabled if they match one of the configured target + /// prefixes. If this is changed to a different [`LevelFilter`], spans and + /// events with targets that did not match any of the configured prefixes + /// will be enabled if their level is at or below the provided level. + pub fn with_default(mut self, level: impl Into) -> Self { + self.0 + .add(StaticDirective::new(None, Default::default(), level.into())); + self + } + + /// Returns an iterator over the [target]-[`LevelFilter`] pairs in this filter. + /// + /// The order of iteration is undefined. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::filter::{Targets, LevelFilter}; + /// use tracing_core::Level; + /// + /// let filter = Targets::new() + /// .with_target("my_crate", Level::INFO) + /// .with_target("my_crate::interesting_module", Level::DEBUG); + /// + /// let mut targets: Vec<_> = filter.iter().collect(); + /// targets.sort(); + /// + /// assert_eq!(targets, vec![ + /// ("my_crate", LevelFilter::INFO), + /// ("my_crate::interesting_module", LevelFilter::DEBUG), + /// ]); + /// ``` + /// + /// [target]: tracing_core::Metadata::target + pub fn iter(&self) -> Iter<'_> { + self.into_iter() + } + + #[inline] + fn interested(&self, metadata: &'static Metadata<'static>) -> Interest { + if self.0.enabled(metadata) { + Interest::always() + } else { + Interest::never() + } + } +} + +impl Extend<(T, L)> for Targets +where + T: Into, + L: Into, +{ + fn extend>(&mut self, iter: I) { + let iter = iter.into_iter().map(|(target, level)| { + StaticDirective::new(Some(target.into()), Default::default(), level.into()) + }); + self.0.extend(iter); + } +} + +impl FromIterator<(T, L)> for Targets +where + T: Into, + L: Into, +{ + fn from_iter>(iter: I) -> Self { + let mut this = Self::default(); + this.extend(iter); + this + } +} + +impl FromStr for Targets { + type Err = ParseError; + fn from_str(s: &str) -> Result { + s.split(',') + .map(StaticDirective::from_str) + .collect::>() + .map(Self) + } +} + +impl layer::Layer for Targets +where + S: Subscriber, +{ + fn enabled(&self, metadata: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { + self.0.enabled(metadata) + } + + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + self.interested(metadata) + } + + fn max_level_hint(&self) -> Option { + Some(self.0.max_level) + } +} + +#[cfg(feature = "registry")] +#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] +impl layer::Filter for Targets { + fn enabled(&self, metadata: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool { + self.0.enabled(metadata) + } + + fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { + self.interested(metadata) + } + + fn max_level_hint(&self) -> Option { + Some(self.0.max_level) + } +} + +impl IntoIterator for Targets { + type Item = (String, LevelFilter); + + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter::new(self) + } +} + +impl<'a> IntoIterator for &'a Targets { + type Item = (&'a str, LevelFilter); + + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + Iter::new(self) + } +} + +/// An owning iterator over the [target]-[level] pairs of a `Targets` filter. +/// +/// This struct is created by the `IntoIterator` trait implementation of [`Targets`]. +/// +/// # Examples +/// +/// Merge the targets from one `Targets` with another: +/// +/// ``` +/// use tracing_subscriber::filter::Targets; +/// use tracing_core::Level; +/// +/// let mut filter = Targets::new().with_target("my_crate", Level::INFO); +/// let overrides = Targets::new().with_target("my_crate::interesting_module", Level::DEBUG); +/// +/// filter.extend(overrides); +/// # drop(filter); +/// ``` +/// +/// [target]: tracing_core::Metadata::target +/// [level]: tracing_core::Level +#[derive(Debug)] +pub struct IntoIter( + #[allow(clippy::type_complexity)] // alias indirection would probably make this more confusing + FilterMap< + as IntoIterator>::IntoIter, + fn(StaticDirective) -> Option<(String, LevelFilter)>, + >, +); + +impl IntoIter { + fn new(targets: Targets) -> Self { + Self(targets.0.into_iter().filter_map(|directive| { + let level = directive.level; + directive.target.map(|target| (target, level)) + })) + } +} + +impl Iterator for IntoIter { + type Item = (String, LevelFilter); + + fn next(&mut self) -> Option { + self.0.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +/// A borrowing iterator over the [target]-[level] pairs of a `Targets` filter. +/// +/// This struct is created by [`iter`] method of [`Targets`], or from the `IntoIterator` +/// implementation for `&Targets`. +/// +/// [target]: tracing_core::Metadata::target +/// [level]: tracing_core::Level +/// [`iter`]: Targets::iter +#[derive(Debug)] +pub struct Iter<'a>( + FilterMap< + slice::Iter<'a, StaticDirective>, + fn(&'a StaticDirective) -> Option<(&'a str, LevelFilter)>, + >, +); + +impl<'a> Iter<'a> { + fn new(targets: &'a Targets) -> Self { + Self(targets.0.iter().filter_map(|directive| { + directive + .target + .as_deref() + .map(|target| (target, directive.level)) + })) + } +} + +impl<'a> Iterator for Iter<'a> { + type Item = (&'a str, LevelFilter); + + fn next(&mut self) -> Option { + self.0.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + feature! { + #![not(feature = "std")] + use alloc::{vec, vec::Vec, string::ToString}; + + // `dbg!` is only available with `libstd`; just nop it out when testing + // with alloc only. + macro_rules! dbg { + ($x:expr) => { $x } + } + } + + fn expect_parse(s: &str) -> Targets { + match dbg!(s).parse::() { + Err(e) => panic!("string {:?} did not parse successfully: {}", s, e), + Ok(e) => e, + } + } + + fn expect_parse_ralith(s: &str) { + let dirs = expect_parse(s).0.into_vec(); + assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("server".to_string())); + assert_eq!(dirs[0].level, LevelFilter::DEBUG); + assert_eq!(dirs[0].field_names, Vec::::new()); + + assert_eq!(dirs[1].target, Some("common".to_string())); + assert_eq!(dirs[1].level, LevelFilter::INFO); + assert_eq!(dirs[1].field_names, Vec::::new()); + } + + fn expect_parse_level_directives(s: &str) { + let dirs = expect_parse(s).0.into_vec(); + assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); + + assert_eq!(dirs[0].target, Some("crate3::mod2::mod1".to_string())); + assert_eq!(dirs[0].level, LevelFilter::OFF); + assert_eq!(dirs[0].field_names, Vec::::new()); + + assert_eq!(dirs[1].target, Some("crate1::mod2::mod3".to_string())); + assert_eq!(dirs[1].level, LevelFilter::INFO); + assert_eq!(dirs[1].field_names, Vec::::new()); + + assert_eq!(dirs[2].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[2].level, LevelFilter::WARN); + assert_eq!(dirs[2].field_names, Vec::::new()); + + assert_eq!(dirs[3].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[3].level, LevelFilter::ERROR); + assert_eq!(dirs[3].field_names, Vec::::new()); + + assert_eq!(dirs[4].target, Some("crate3".to_string())); + assert_eq!(dirs[4].level, LevelFilter::TRACE); + assert_eq!(dirs[4].field_names, Vec::::new()); + + assert_eq!(dirs[5].target, Some("crate2".to_string())); + assert_eq!(dirs[5].level, LevelFilter::DEBUG); + assert_eq!(dirs[5].field_names, Vec::::new()); + } + + #[test] + fn parse_ralith() { + expect_parse_ralith("common=info,server=debug"); + } + + #[test] + fn parse_ralith_uc() { + expect_parse_ralith("common=INFO,server=DEBUG"); + } + + #[test] + fn parse_ralith_mixed() { + expect_parse("common=iNfo,server=dEbUg"); + } + + #[test] + fn expect_parse_valid() { + let dirs = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") + .0 + .into_vec(); + assert_eq!(dirs.len(), 4, "\nparsed: {:#?}", dirs); + assert_eq!(dirs[0].target, Some("crate1::mod2".to_string())); + assert_eq!(dirs[0].level, LevelFilter::TRACE); + assert_eq!(dirs[0].field_names, Vec::::new()); + + assert_eq!(dirs[1].target, Some("crate1::mod1".to_string())); + assert_eq!(dirs[1].level, LevelFilter::ERROR); + assert_eq!(dirs[1].field_names, Vec::::new()); + + assert_eq!(dirs[2].target, Some("crate3".to_string())); + assert_eq!(dirs[2].level, LevelFilter::OFF); + assert_eq!(dirs[2].field_names, Vec::::new()); + + assert_eq!(dirs[3].target, Some("crate2".to_string())); + assert_eq!(dirs[3].level, LevelFilter::DEBUG); + assert_eq!(dirs[3].field_names, Vec::::new()); + } + + #[test] + fn parse_level_directives() { + expect_parse_level_directives( + "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ + crate2=debug,crate3=trace,crate3::mod2::mod1=off", + ) + } + + #[test] + fn parse_uppercase_level_directives() { + expect_parse_level_directives( + "crate1::mod1=ERROR,crate1::mod2=WARN,crate1::mod2::mod3=INFO,\ + crate2=DEBUG,crate3=TRACE,crate3::mod2::mod1=OFF", + ) + } + + #[test] + fn parse_numeric_level_directives() { + expect_parse_level_directives( + "crate1::mod1=1,crate1::mod2=2,crate1::mod2::mod3=3,crate2=4,\ + crate3=5,crate3::mod2::mod1=0", + ) + } + + #[test] + fn targets_iter() { + let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") + .with_default(LevelFilter::WARN); + + let mut targets: Vec<_> = filter.iter().collect(); + targets.sort(); + + assert_eq!( + targets, + vec![ + ("crate1::mod1", LevelFilter::ERROR), + ("crate1::mod2", LevelFilter::TRACE), + ("crate2", LevelFilter::DEBUG), + ("crate3", LevelFilter::OFF), + ] + ); + } + + #[test] + fn targets_into_iter() { + let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") + .with_default(LevelFilter::WARN); + + let mut targets: Vec<_> = filter.into_iter().collect(); + targets.sort(); + + assert_eq!( + targets, + vec![ + ("crate1::mod1".to_string(), LevelFilter::ERROR), + ("crate1::mod2".to_string(), LevelFilter::TRACE), + ("crate2".to_string(), LevelFilter::DEBUG), + ("crate3".to_string(), LevelFilter::OFF), + ] + ); + } + + #[test] + // `println!` is only available with `libstd`. + #[cfg(feature = "std")] + fn size_of_filters() { + fn print_sz(s: &str) { + let filter = s.parse::().expect("filter should parse"); + println!( + "size_of_val({:?})\n -> {}B", + s, + std::mem::size_of_val(&filter) + ); + } + + print_sz("info"); + + print_sz("foo=debug"); + + print_sz( + "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ + crate2=debug,crate3=trace,crate3::mod2::mod1=off", + ); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/fmt_layer.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/fmt_layer.rs new file mode 100644 index 000000000..0e0d5e0eb --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/fmt_layer.rs @@ -0,0 +1,1205 @@ +use crate::{ + field::RecordFields, + fmt::{format, FormatEvent, FormatFields, MakeWriter, TestWriter}, + layer::{self, Context}, + registry::{self, LookupSpan, SpanRef}, +}; +use format::{FmtSpan, TimingDisplay}; +use std::{any::TypeId, cell::RefCell, fmt, io, marker::PhantomData, ops::Deref, time::Instant}; +use tracing_core::{ + field, + span::{Attributes, Current, Id, Record}, + Event, Metadata, Subscriber, +}; + +/// A [`Layer`] that logs formatted representations of `tracing` events. +/// +/// ## Examples +/// +/// Constructing a layer with the default configuration: +/// +/// ```rust +/// use tracing_subscriber::{fmt, Registry}; +/// use tracing_subscriber::prelude::*; +/// +/// let subscriber = Registry::default() +/// .with(fmt::Layer::default()); +/// +/// tracing::subscriber::set_global_default(subscriber).unwrap(); +/// ``` +/// +/// Overriding the layer's behavior: +/// +/// ```rust +/// use tracing_subscriber::{fmt, Registry}; +/// use tracing_subscriber::prelude::*; +/// +/// let fmt_layer = fmt::layer() +/// .with_target(false) // don't include event targets when logging +/// .with_level(false); // don't include event levels when logging +/// +/// let subscriber = Registry::default().with(fmt_layer); +/// # tracing::subscriber::set_global_default(subscriber).unwrap(); +/// ``` +/// +/// Setting a custom event formatter: +/// +/// ```rust +/// use tracing_subscriber::fmt::{self, format, time}; +/// use tracing_subscriber::prelude::*; +/// +/// let fmt = format().with_timer(time::Uptime::default()); +/// let fmt_layer = fmt::layer() +/// .event_format(fmt) +/// .with_target(false); +/// # let subscriber = fmt_layer.with_subscriber(tracing_subscriber::registry::Registry::default()); +/// # tracing::subscriber::set_global_default(subscriber).unwrap(); +/// ``` +/// +/// [`Layer`]: ../layer/trait.Layer.html +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +#[derive(Debug)] +pub struct Layer< + S, + N = format::DefaultFields, + E = format::Format, + W = fn() -> io::Stdout, +> { + make_writer: W, + fmt_fields: N, + fmt_event: E, + fmt_span: format::FmtSpanConfig, + is_ansi: bool, + _inner: PhantomData, +} + +impl Layer { + /// Returns a new [`Layer`](struct.Layer.html) with the default configuration. + pub fn new() -> Self { + Self::default() + } +} + +// This needs to be a seperate impl block because they place different bounds on the type parameters. +impl Layer +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'writer> FormatFields<'writer> + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, +{ + /// Sets the [event formatter][`FormatEvent`] that the layer will use to + /// format events. + /// + /// The event formatter may be any type implementing the [`FormatEvent`] + /// trait, which is implemented for all functions taking a [`FmtContext`], a + /// [`Writer`], and an [`Event`]. + /// + /// # Examples + /// + /// Setting a type implementing [`FormatEvent`] as the formatter: + /// ```rust + /// use tracing_subscriber::fmt::{self, format}; + /// + /// let layer = fmt::layer() + /// .event_format(format().compact()); + /// # // this is necessary for type inference. + /// # use tracing_subscriber::Layer as _; + /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); + /// ``` + /// [`FormatEvent`]: format::FormatEvent + /// [`Event`]: tracing::Event + /// [`Writer`]: crate::format::Writer + pub fn event_format(self, e: E2) -> Layer + where + E2: FormatEvent + 'static, + { + Layer { + fmt_fields: self.fmt_fields, + fmt_event: e, + fmt_span: self.fmt_span, + make_writer: self.make_writer, + is_ansi: self.is_ansi, + _inner: self._inner, + } + } +} + +// This needs to be a seperate impl block because they place different bounds on the type parameters. +impl Layer { + /// Sets the [`MakeWriter`] that the [`Layer`] being built will use to write events. + /// + /// # Examples + /// + /// Using `stderr` rather than `stdout`: + /// + /// ```rust + /// use std::io; + /// use tracing_subscriber::fmt; + /// + /// let layer = fmt::layer() + /// .with_writer(io::stderr); + /// # // this is necessary for type inference. + /// # use tracing_subscriber::Layer as _; + /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); + /// ``` + /// + /// [`MakeWriter`]: ../fmt/trait.MakeWriter.html + /// [`Layer`]: ../layer/trait.Layer.html + pub fn with_writer(self, make_writer: W2) -> Layer + where + W2: for<'writer> MakeWriter<'writer> + 'static, + { + Layer { + fmt_fields: self.fmt_fields, + fmt_event: self.fmt_event, + fmt_span: self.fmt_span, + is_ansi: self.is_ansi, + make_writer, + _inner: self._inner, + } + } + + /// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in + /// unit tests. + /// + /// See [`TestWriter`] for additional details. + /// + /// # Examples + /// + /// Using [`TestWriter`] to let `cargo test` capture test output: + /// + /// ```rust + /// use std::io; + /// use tracing_subscriber::fmt; + /// + /// let layer = fmt::layer() + /// .with_test_writer(); + /// # // this is necessary for type inference. + /// # use tracing_subscriber::Layer as _; + /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); + /// ``` + /// [capturing]: + /// https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output + /// [`TestWriter`]: writer/struct.TestWriter.html + pub fn with_test_writer(self) -> Layer { + Layer { + fmt_fields: self.fmt_fields, + fmt_event: self.fmt_event, + fmt_span: self.fmt_span, + is_ansi: self.is_ansi, + make_writer: TestWriter::default(), + _inner: self._inner, + } + } + + /// Enable ANSI terminal colors for formatted output. + #[cfg(feature = "ansi")] + #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + pub fn with_ansi(self, ansi: bool) -> Self { + Self { + is_ansi: ansi, + ..self + } + } +} + +impl Layer, W> +where + N: for<'writer> FormatFields<'writer> + 'static, +{ + /// Use the given [`timer`] for span and event timestamps. + /// + /// See the [`time` module] for the provided timer implementations. + /// + /// Note that using the `"time`"" feature flag enables the + /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the + /// [`time` crate] to provide more sophisticated timestamp formatting + /// options. + /// + /// [`timer`]: super::time::FormatTime + /// [`time` module]: mod@super::time + /// [`UtcTime`]: super::time::UtcTime + /// [`LocalTime`]: super::time::LocalTime + /// [`time` crate]: https://docs.rs/time/0.3 + pub fn with_timer(self, timer: T2) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_timer(timer), + fmt_fields: self.fmt_fields, + fmt_span: self.fmt_span, + make_writer: self.make_writer, + is_ansi: self.is_ansi, + _inner: self._inner, + } + } + + /// Do not emit timestamps with spans and event. + pub fn without_time(self) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.without_time(), + fmt_fields: self.fmt_fields, + fmt_span: self.fmt_span.without_time(), + make_writer: self.make_writer, + is_ansi: self.is_ansi, + _inner: self._inner, + } + } + + /// Configures how synthesized events are emitted at points in the [span + /// lifecycle][lifecycle]. + /// + /// The following options are available: + /// + /// - `FmtSpan::NONE`: No events will be synthesized when spans are + /// created, entered, exited, or closed. Data from spans will still be + /// included as the context for formatted events. This is the default. + /// - `FmtSpan::NEW`: An event will be synthesized when spans are created. + /// - `FmtSpan::ENTER`: An event will be synthesized when spans are entered. + /// - `FmtSpan::EXIT`: An event will be synthesized when spans are exited. + /// - `FmtSpan::CLOSE`: An event will be synthesized when a span closes. If + /// [timestamps are enabled][time] for this formatter, the generated + /// event will contain fields with the span's _busy time_ (the total + /// time for which it was entered) and _idle time_ (the total time that + /// the span existed but was not entered). + /// - `FmtSpan::ACTIVE`: Events will be synthesized when spans are entered + /// or exited. + /// - `FmtSpan::FULL`: Events will be synthesized whenever a span is + /// created, entered, exited, or closed. If timestamps are enabled, the + /// close event will contain the span's busy and idle time, as + /// described above. + /// + /// The options can be enabled in any combination. For instance, the following + /// will synthesize events whenever spans are created and closed: + /// + /// ```rust + /// use tracing_subscriber::fmt; + /// use tracing_subscriber::fmt::format::FmtSpan; + /// + /// let subscriber = fmt() + /// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) + /// .finish(); + /// ``` + /// + /// Note that the generated events will only be part of the log output by + /// this formatter; they will not be recorded by other `Subscriber`s or by + /// `Layer`s added to this subscriber. + /// + /// [lifecycle]: https://docs.rs/tracing/latest/tracing/span/index.html#the-span-lifecycle + /// [time]: #method.without_time + pub fn with_span_events(self, kind: FmtSpan) -> Self { + Layer { + fmt_span: self.fmt_span.with_kind(kind), + ..self + } + } + + /// Sets whether or not an event's target is displayed. + pub fn with_target(self, display_target: bool) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_target(display_target), + ..self + } + } + + /// Sets whether or not an event's level is displayed. + pub fn with_level(self, display_level: bool) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_level(display_level), + ..self + } + } + + /// Sets whether or not the [thread ID] of the current thread is displayed + /// when formatting events + /// + /// [thread ID]: https://doc.rust-lang.org/stable/std/thread/struct.ThreadId.html + pub fn with_thread_ids(self, display_thread_ids: bool) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_thread_ids(display_thread_ids), + ..self + } + } + + /// Sets whether or not the [name] of the current thread is displayed + /// when formatting events + /// + /// [name]: https://doc.rust-lang.org/stable/std/thread/index.html#naming-threads + pub fn with_thread_names( + self, + display_thread_names: bool, + ) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_thread_names(display_thread_names), + ..self + } + } + + /// Sets the layer being built to use a [less verbose formatter](../fmt/format/struct.Compact.html). + pub fn compact(self) -> Layer, W> + where + N: for<'writer> FormatFields<'writer> + 'static, + { + Layer { + fmt_event: self.fmt_event.compact(), + fmt_fields: self.fmt_fields, + fmt_span: self.fmt_span, + make_writer: self.make_writer, + is_ansi: self.is_ansi, + _inner: self._inner, + } + } + + /// Sets the layer being built to use an [excessively pretty, human-readable formatter](crate::fmt::format::Pretty). + #[cfg(feature = "ansi")] + #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + pub fn pretty(self) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.pretty(), + fmt_fields: format::Pretty::default(), + fmt_span: self.fmt_span, + make_writer: self.make_writer, + is_ansi: self.is_ansi, + _inner: self._inner, + } + } + + /// Sets the layer being built to use a [JSON formatter](../fmt/format/struct.Json.html). + /// + /// The full format includes fields from all entered spans. + /// + /// # Example Output + /// + /// ```ignore,json + /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate","fields":{"message":"some message", "key": "value"}} + /// ``` + /// + /// # Options + /// + /// - [`Layer::flatten_event`] can be used to enable flattening event fields into the root + /// object. + /// + /// [`Layer::flatten_event`]: #method.flatten_event + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + pub fn json(self) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.json(), + fmt_fields: format::JsonFields::new(), + fmt_span: self.fmt_span, + make_writer: self.make_writer, + // always disable ANSI escapes in JSON mode! + is_ansi: false, + _inner: self._inner, + } + } +} + +#[cfg(feature = "json")] +#[cfg_attr(docsrs, doc(cfg(feature = "json")))] +impl Layer, W> { + /// Sets the JSON layer being built to flatten event metadata. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + pub fn flatten_event( + self, + flatten_event: bool, + ) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.flatten_event(flatten_event), + fmt_fields: format::JsonFields::new(), + ..self + } + } + + /// Sets whether or not the formatter will include the current span in + /// formatted events. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + pub fn with_current_span( + self, + display_current_span: bool, + ) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_current_span(display_current_span), + fmt_fields: format::JsonFields::new(), + ..self + } + } + + /// Sets whether or not the formatter will include a list (from root to leaf) + /// of all currently entered spans in formatted events. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + pub fn with_span_list( + self, + display_span_list: bool, + ) -> Layer, W> { + Layer { + fmt_event: self.fmt_event.with_span_list(display_span_list), + fmt_fields: format::JsonFields::new(), + ..self + } + } +} + +impl Layer { + /// Sets the field formatter that the layer being built will use to record + /// fields. + pub fn fmt_fields(self, fmt_fields: N2) -> Layer + where + N2: for<'writer> FormatFields<'writer> + 'static, + { + Layer { + fmt_event: self.fmt_event, + fmt_fields, + fmt_span: self.fmt_span, + make_writer: self.make_writer, + is_ansi: self.is_ansi, + _inner: self._inner, + } + } +} + +impl Default for Layer { + fn default() -> Self { + Layer { + fmt_fields: format::DefaultFields::default(), + fmt_event: format::Format::default(), + fmt_span: format::FmtSpanConfig::default(), + make_writer: io::stdout, + is_ansi: cfg!(feature = "ansi"), + _inner: PhantomData, + } + } +} + +impl Layer +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'writer> FormatFields<'writer> + 'static, + E: FormatEvent + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, +{ + #[inline] + fn make_ctx<'a>(&'a self, ctx: Context<'a, S>, event: &'a Event<'a>) -> FmtContext<'a, S, N> { + FmtContext { + ctx, + fmt_fields: &self.fmt_fields, + event, + } + } +} + +/// A formatted representation of a span's fields stored in its [extensions]. +/// +/// Because `FormattedFields` is generic over the type of the formatter that +/// produced it, multiple versions of a span's formatted fields can be stored in +/// the [`Extensions`][extensions] type-map. This means that when multiple +/// formatters are in use, each can store its own formatted representation +/// without conflicting. +/// +/// [extensions]: ../registry/struct.Extensions.html +#[derive(Default)] +pub struct FormattedFields { + _format_fields: PhantomData, + was_ansi: bool, + /// The formatted fields of a span. + pub fields: String, +} + +impl FormattedFields { + /// Returns a new `FormattedFields`. + pub fn new(fields: String) -> Self { + Self { + fields, + was_ansi: false, + _format_fields: PhantomData, + } + } + + /// Returns a new [`format::Writer`] for writing to this `FormattedFields`. + /// + /// The returned [`format::Writer`] can be used with the + /// [`FormatFields::format_fields`] method. + pub fn as_writer(&mut self) -> format::Writer<'_> { + format::Writer::new(&mut self.fields).with_ansi(self.was_ansi) + } +} + +impl fmt::Debug for FormattedFields { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FormattedFields") + .field("fields", &self.fields) + .field("formatter", &format_args!("{}", std::any::type_name::())) + .field("was_ansi", &self.was_ansi) + .finish() + } +} + +impl fmt::Display for FormattedFields { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.fields, f) + } +} + +impl Deref for FormattedFields { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.fields + } +} + +// === impl FmtLayer === + +macro_rules! with_event_from_span { + ($id:ident, $span:ident, $($field:literal = $value:expr),*, |$event:ident| $code:block) => { + let meta = $span.metadata(); + let cs = meta.callsite(); + let fs = field::FieldSet::new(&[$($field),*], cs); + #[allow(unused)] + let mut iter = fs.iter(); + let v = [$( + (&iter.next().unwrap(), Some(&$value as &dyn field::Value)), + )*]; + let vs = fs.value_set(&v); + let $event = Event::new_child_of($id, meta, &vs); + $code + }; +} + +impl layer::Layer for Layer +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'writer> FormatFields<'writer> + 'static, + E: FormatEvent + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, +{ + fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { + let span = ctx.span(id).expect("Span not found, this is a bug"); + let mut extensions = span.extensions_mut(); + + if extensions.get_mut::>().is_none() { + let mut fields = FormattedFields::::new(String::new()); + if self + .fmt_fields + .format_fields(fields.as_writer().with_ansi(self.is_ansi), attrs) + .is_ok() + { + fields.was_ansi = self.is_ansi; + extensions.insert(fields); + } + } + + if self.fmt_span.fmt_timing + && self.fmt_span.trace_close() + && extensions.get_mut::().is_none() + { + extensions.insert(Timings::new()); + } + + if self.fmt_span.trace_new() { + with_event_from_span!(id, span, "message" = "new", |event| { + drop(extensions); + drop(span); + self.on_event(&event, ctx); + }); + } + } + + fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { + let span = ctx.span(id).expect("Span not found, this is a bug"); + let mut extensions = span.extensions_mut(); + if let Some(fields) = extensions.get_mut::>() { + let _ = self.fmt_fields.add_fields(fields, values); + return; + } + + let mut fields = FormattedFields::::new(String::new()); + if self + .fmt_fields + .format_fields(fields.as_writer().with_ansi(self.is_ansi), values) + .is_ok() + { + fields.was_ansi = self.is_ansi; + extensions.insert(fields); + } + } + + fn on_enter(&self, id: &Id, ctx: Context<'_, S>) { + if self.fmt_span.trace_enter() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing { + let span = ctx.span(id).expect("Span not found, this is a bug"); + let mut extensions = span.extensions_mut(); + if let Some(timings) = extensions.get_mut::() { + let now = Instant::now(); + timings.idle += (now - timings.last).as_nanos() as u64; + timings.last = now; + } + + if self.fmt_span.trace_enter() { + with_event_from_span!(id, span, "message" = "enter", |event| { + drop(extensions); + drop(span); + self.on_event(&event, ctx); + }); + } + } + } + + fn on_exit(&self, id: &Id, ctx: Context<'_, S>) { + if self.fmt_span.trace_exit() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing { + let span = ctx.span(id).expect("Span not found, this is a bug"); + let mut extensions = span.extensions_mut(); + if let Some(timings) = extensions.get_mut::() { + let now = Instant::now(); + timings.busy += (now - timings.last).as_nanos() as u64; + timings.last = now; + } + + if self.fmt_span.trace_exit() { + with_event_from_span!(id, span, "message" = "exit", |event| { + drop(extensions); + drop(span); + self.on_event(&event, ctx); + }); + } + } + } + + fn on_close(&self, id: Id, ctx: Context<'_, S>) { + if self.fmt_span.trace_close() { + let span = ctx.span(&id).expect("Span not found, this is a bug"); + let extensions = span.extensions(); + if let Some(timing) = extensions.get::() { + let Timings { + busy, + mut idle, + last, + } = *timing; + idle += (Instant::now() - last).as_nanos() as u64; + + let t_idle = field::display(TimingDisplay(idle)); + let t_busy = field::display(TimingDisplay(busy)); + + with_event_from_span!( + id, + span, + "message" = "close", + "time.busy" = t_busy, + "time.idle" = t_idle, + |event| { + drop(extensions); + drop(span); + self.on_event(&event, ctx); + } + ); + } else { + with_event_from_span!(id, span, "message" = "close", |event| { + drop(extensions); + drop(span); + self.on_event(&event, ctx); + }); + } + } + } + + fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { + thread_local! { + static BUF: RefCell = RefCell::new(String::new()); + } + + BUF.with(|buf| { + let borrow = buf.try_borrow_mut(); + let mut a; + let mut b; + let mut buf = match borrow { + Ok(buf) => { + a = buf; + &mut *a + } + _ => { + b = String::new(); + &mut b + } + }; + + let ctx = self.make_ctx(ctx, event); + if self + .fmt_event + .format_event( + &ctx, + format::Writer::new(&mut buf).with_ansi(self.is_ansi), + event, + ) + .is_ok() + { + let mut writer = self.make_writer.make_writer_for(event.metadata()); + let _ = io::Write::write_all(&mut writer, buf.as_bytes()); + } + + buf.clear(); + }); + } + + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + // This `downcast_raw` impl allows downcasting a `fmt` layer to any of + // its components (event formatter, field formatter, and `MakeWriter`) + // as well as to the layer's type itself. The potential use-cases for + // this *may* be somewhat niche, though... + match () { + _ if id == TypeId::of::() => Some(self as *const Self as *const ()), + _ if id == TypeId::of::() => Some(&self.fmt_event as *const E as *const ()), + _ if id == TypeId::of::() => Some(&self.fmt_fields as *const N as *const ()), + _ if id == TypeId::of::() => Some(&self.make_writer as *const W as *const ()), + _ => None, + } + } +} + +/// Provides the current span context to a formatter. +pub struct FmtContext<'a, S, N> { + pub(crate) ctx: Context<'a, S>, + pub(crate) fmt_fields: &'a N, + pub(crate) event: &'a Event<'a>, +} + +impl<'a, S, N> fmt::Debug for FmtContext<'a, S, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FmtContext").finish() + } +} + +impl<'cx, 'writer, S, N> FormatFields<'writer> for FmtContext<'cx, S, N> +where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + N: FormatFields<'writer> + 'static, +{ + fn format_fields( + &self, + writer: format::Writer<'writer>, + fields: R, + ) -> fmt::Result { + self.fmt_fields.format_fields(writer, fields) + } +} + +impl<'a, S, N> FmtContext<'a, S, N> +where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static, +{ + /// Visits every span in the current context with a closure. + /// + /// The provided closure will be called first with the current span, + /// and then with that span's parent, and then that span's parent, + /// and so on until a root span is reached. + pub fn visit_spans(&self, mut f: F) -> Result<(), E> + where + F: FnMut(&SpanRef<'_, S>) -> Result<(), E>, + { + // visit all the current spans + if let Some(scope) = self.event_scope() { + for span in scope.from_root() { + f(&span)?; + } + } + Ok(()) + } + + /// Returns metadata for the span with the given `id`, if it exists. + /// + /// If this returns `None`, then no span exists for that ID (either it has + /// closed or the ID is invalid). + #[inline] + pub fn metadata(&self, id: &Id) -> Option<&'static Metadata<'static>> + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.ctx.metadata(id) + } + + /// Returns [stored data] for the span with the given `id`, if it exists. + /// + /// If this returns `None`, then no span exists for that ID (either it has + /// closed or the ID is invalid). + /// + /// [stored data]: ../registry/struct.SpanRef.html + #[inline] + pub fn span(&self, id: &Id) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.ctx.span(id) + } + + /// Returns `true` if an active span exists for the given `Id`. + #[inline] + pub fn exists(&self, id: &Id) -> bool + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.ctx.exists(id) + } + + /// Returns [stored data] for the span that the wrapped subscriber considers + /// to be the current. + /// + /// If this returns `None`, then we are not currently within a span. + /// + /// [stored data]: ../registry/struct.SpanRef.html + #[inline] + pub fn lookup_current(&self) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.ctx.lookup_current() + } + + /// Returns the current span for this formatter. + pub fn current_span(&self) -> Current { + self.ctx.current_span() + } + + /// Returns [stored data] for the parent span of the event currently being + /// formatted. + /// + /// If the event has a contextual parent, this will return the current span. If + /// the event has an explicit parent span, this will return that span. If + /// the event does not have a parent span, this will return `None`. + /// + /// [stored data]: SpanRef + pub fn parent_span(&self) -> Option> { + self.ctx.event_span(self.event) + } + + /// Returns an iterator over the [stored data] for all the spans in the + /// current context, starting with the specified span and ending with the + /// root of the trace tree and ending with the current span. + /// + /// This is equivalent to the [`Context::span_scope`] method. + /// + ///

+ ///
+ ///
+    /// Note: Compared to scope this
+    /// returns the spans in reverse order (from leaf to root). Use
+    /// Scope::from_root
+    /// in case root-to-leaf ordering is desired.
+    /// 
+ /// + ///
+ ///
+    /// Note: This requires the wrapped subscriber to implement the
+    /// LookupSpan trait.
+    /// See the documentation on Context's
+    /// declaration for details.
+    /// 
+ /// + /// [stored data]: crate::registry::SpanRef + pub fn span_scope(&self, id: &Id) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.ctx.span_scope(id) + } + + /// Returns an iterator over the [stored data] for all the spans in the + /// event's span context, starting with its parent span and ending with the + /// root of the trace tree. + /// + /// This is equivalent to calling the [`Context::event_scope`] method and + /// passing the event currently being formatted. + /// + ///
+ ///
+    /// Note: Compared to scope this
+    /// returns the spans in reverse order (from leaf to root). Use
+    /// Scope::from_root
+    /// in case root-to-leaf ordering is desired.
+    /// 
+ /// + ///
+ ///
+    /// Note: This requires the wrapped subscriber to implement the
+    /// LookupSpan trait.
+    /// See the documentation on Context's
+    /// declaration for details.
+    /// 
+ /// + /// [stored data]: crate::registry::SpanRef + pub fn event_scope(&self) -> Option> + where + S: for<'lookup> registry::LookupSpan<'lookup>, + { + self.ctx.event_scope(self.event) + } + + /// Returns the [field formatter] configured by the subscriber invoking + /// `format_event`. + /// + /// The event formatter may use the returned field formatter to format the + /// fields of any events it records. + /// + /// [field formatter]: FormatFields + pub fn field_format(&self) -> &N { + self.fmt_fields + } +} + +struct Timings { + idle: u64, + busy: u64, + last: Instant, +} + +impl Timings { + fn new() -> Self { + Self { + idle: 0, + busy: 0, + last: Instant::now(), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::fmt::{ + self, + format::{self, test::MockTime, Format}, + layer::Layer as _, + test::{MockMakeWriter, MockWriter}, + time, + }; + use crate::Registry; + use format::FmtSpan; + use regex::Regex; + use tracing::subscriber::with_default; + use tracing_core::dispatcher::Dispatch; + + #[test] + fn impls() { + let f = Format::default().with_timer(time::Uptime::default()); + let fmt = fmt::Layer::default().event_format(f); + let subscriber = fmt.with_subscriber(Registry::default()); + let _dispatch = Dispatch::new(subscriber); + + let f = format::Format::default(); + let fmt = fmt::Layer::default().event_format(f); + let subscriber = fmt.with_subscriber(Registry::default()); + let _dispatch = Dispatch::new(subscriber); + + let f = format::Format::default().compact(); + let fmt = fmt::Layer::default().event_format(f); + let subscriber = fmt.with_subscriber(Registry::default()); + let _dispatch = Dispatch::new(subscriber); + } + + #[test] + fn fmt_layer_downcasts() { + let f = format::Format::default(); + let fmt = fmt::Layer::default().event_format(f); + let subscriber = fmt.with_subscriber(Registry::default()); + + let dispatch = Dispatch::new(subscriber); + assert!(dispatch.downcast_ref::>().is_some()); + } + + #[test] + fn fmt_layer_downcasts_to_parts() { + let f = format::Format::default(); + let fmt = fmt::Layer::default().event_format(f); + let subscriber = fmt.with_subscriber(Registry::default()); + let dispatch = Dispatch::new(subscriber); + assert!(dispatch.downcast_ref::().is_some()); + assert!(dispatch.downcast_ref::().is_some()) + } + + #[test] + fn is_lookup_span() { + fn assert_lookup_span crate::registry::LookupSpan<'a>>(_: T) {} + let fmt = fmt::Layer::default(); + let subscriber = fmt.with_subscriber(Registry::default()); + assert_lookup_span(subscriber) + } + + fn sanitize_timings(s: String) -> String { + let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap(); + re.replace_all(s.as_str(), "timing").to_string() + } + + #[test] + fn synthesize_span_none() { + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + // check that FmtSpan::NONE is the default + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("span1", x = 42); + let _e = span1.enter(); + }); + let actual = sanitize_timings(make_writer.get_string()); + assert_eq!("", actual.as_str()); + } + + #[test] + fn synthesize_span_active() { + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + .with_span_events(FmtSpan::ACTIVE) + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("span1", x = 42); + let _e = span1.enter(); + }); + let actual = sanitize_timings(make_writer.get_string()); + assert_eq!( + "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\ + fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n", + actual.as_str() + ); + } + + #[test] + fn synthesize_span_close() { + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + .with_span_events(FmtSpan::CLOSE) + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("span1", x = 42); + let _e = span1.enter(); + }); + let actual = sanitize_timings(make_writer.get_string()); + assert_eq!( + "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n", + actual.as_str() + ); + } + + #[test] + fn synthesize_span_close_no_timing() { + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + .without_time() + .with_span_events(FmtSpan::CLOSE) + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("span1", x = 42); + let _e = span1.enter(); + }); + let actual = sanitize_timings(make_writer.get_string()); + assert_eq!( + "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n", + actual.as_str() + ); + } + + #[test] + fn synthesize_span_full() { + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + .with_span_events(FmtSpan::FULL) + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("span1", x = 42); + let _e = span1.enter(); + }); + let actual = sanitize_timings(make_writer.get_string()); + assert_eq!( + "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\ + fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\ + fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\ + fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n", + actual.as_str() + ); + } + + #[test] + fn make_writer_based_on_meta() { + struct MakeByTarget { + make_writer1: MockMakeWriter, + make_writer2: MockMakeWriter, + } + + impl<'a> MakeWriter<'a> for MakeByTarget { + type Writer = MockWriter; + + fn make_writer(&'a self) -> Self::Writer { + self.make_writer1.make_writer() + } + + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + if meta.target() == "writer2" { + return self.make_writer2.make_writer(); + } + self.make_writer() + } + } + + let make_writer1 = MockMakeWriter::default(); + let make_writer2 = MockMakeWriter::default(); + + let make_writer = MakeByTarget { + make_writer1: make_writer1.clone(), + make_writer2: make_writer2.clone(), + }; + + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer) + .with_level(false) + .with_target(false) + .with_ansi(false) + .with_timer(MockTime) + .with_span_events(FmtSpan::CLOSE) + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("writer1_span", x = 42); + let _e = span1.enter(); + tracing::info!(target: "writer2", "hello writer2!"); + let span2 = tracing::info_span!(target: "writer2", "writer2_span"); + let _e = span2.enter(); + tracing::warn!(target: "writer1", "hello writer1!"); + }); + + let actual = sanitize_timings(make_writer1.get_string()); + assert_eq!( + "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\ + fake time writer1_span{x=42}: close timing timing\n", + actual.as_str() + ); + let actual = sanitize_timings(make_writer2.get_string()); + assert_eq!( + "fake time writer1_span{x=42}: hello writer2!\n\ + fake time writer1_span{x=42}:writer2_span: close timing timing\n", + actual.as_str() + ); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/format/json.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/format/json.rs new file mode 100644 index 000000000..cc86f03c7 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/format/json.rs @@ -0,0 +1,750 @@ +use super::{Format, FormatEvent, FormatFields, FormatTime, Writer}; +use crate::{ + field::{RecordFields, VisitOutput}, + fmt::{ + fmt_layer::{FmtContext, FormattedFields}, + writer::WriteAdaptor, + }, + registry::LookupSpan, +}; +use serde::ser::{SerializeMap, Serializer as _}; +use serde_json::Serializer; +use std::{ + collections::BTreeMap, + fmt::{self, Write}, +}; +use tracing_core::{ + field::{self, Field}, + span::Record, + Event, Subscriber, +}; +use tracing_serde::AsSerde; + +#[cfg(feature = "tracing-log")] +use tracing_log::NormalizeEvent; + +/// Marker for `Format` that indicates that the verbose JSON log format should be used. +/// +/// The full format includes fields from all entered spans. +/// +/// # Example Output +/// +/// ```json +/// { +/// "timestamp":"Feb 20 11:28:15.096", +/// "level":"INFO", +/// "fields":{"message":"some message","key":"value"} +/// "target":"mycrate", +/// "span":{name":"leaf"}, +/// "spans":[{"name":"root"},{"name":"leaf"}], +/// } +/// ``` +/// +/// # Options +/// +/// - [`Json::flatten_event`] can be used to enable flattening event fields into +/// the root +/// - [`Json::with_current_span`] can be used to control logging of the current +/// span +/// - [`Json::with_span_list`] can be used to control logging of the span list +/// object. +/// +/// By default, event fields are not flattened, and both current span and span +/// list are logged. +/// +/// [`Json::flatten_event`]: #method.flatten_event +/// [`Json::with_current_span`]: #method.with_current_span +/// [`Json::with_span_list`]: #method.with_span_list +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct Json { + pub(crate) flatten_event: bool, + pub(crate) display_current_span: bool, + pub(crate) display_span_list: bool, +} + +impl Json { + /// If set to `true` event metadata will be flattened into the root object. + pub fn flatten_event(&mut self, flatten_event: bool) { + self.flatten_event = flatten_event; + } + + /// If set to `false`, formatted events won't contain a field for the current span. + pub fn with_current_span(&mut self, display_current_span: bool) { + self.display_current_span = display_current_span; + } + + /// If set to `false`, formatted events won't contain a list of all currently + /// entered spans. Spans are logged in a list from root to leaf. + pub fn with_span_list(&mut self, display_span_list: bool) { + self.display_span_list = display_span_list; + } +} + +struct SerializableContext<'a, 'b, Span, N>( + &'b crate::layer::Context<'a, Span>, + std::marker::PhantomData, +) +where + Span: Subscriber + for<'lookup> crate::registry::LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static; + +impl<'a, 'b, Span, N> serde::ser::Serialize for SerializableContext<'a, 'b, Span, N> +where + Span: Subscriber + for<'lookup> crate::registry::LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static, +{ + fn serialize(&self, serializer_o: Ser) -> Result + where + Ser: serde::ser::Serializer, + { + use serde::ser::SerializeSeq; + let mut serializer = serializer_o.serialize_seq(None)?; + + if let Some(leaf_span) = self.0.lookup_current() { + for span in leaf_span.scope().from_root() { + serializer.serialize_element(&SerializableSpan(&span, self.1))?; + } + } + + serializer.end() + } +} + +struct SerializableSpan<'a, 'b, Span, N>( + &'b crate::registry::SpanRef<'a, Span>, + std::marker::PhantomData, +) +where + Span: for<'lookup> crate::registry::LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static; + +impl<'a, 'b, Span, N> serde::ser::Serialize for SerializableSpan<'a, 'b, Span, N> +where + Span: for<'lookup> crate::registry::LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static, +{ + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::ser::Serializer, + { + let mut serializer = serializer.serialize_map(None)?; + + let ext = self.0.extensions(); + let data = ext + .get::>() + .expect("Unable to find FormattedFields in extensions; this is a bug"); + + // TODO: let's _not_ do this, but this resolves + // https://github.com/tokio-rs/tracing/issues/391. + // We should probably rework this to use a `serde_json::Value` or something + // similar in a JSON-specific layer, but I'd (david) + // rather have a uglier fix now rather than shipping broken JSON. + match serde_json::from_str::(data) { + Ok(serde_json::Value::Object(fields)) => { + for field in fields { + serializer.serialize_entry(&field.0, &field.1)?; + } + } + // We have fields for this span which are valid JSON but not an object. + // This is probably a bug, so panic if we're in debug mode + Ok(_) if cfg!(debug_assertions) => panic!( + "span '{}' had malformed fields! this is a bug.\n error: invalid JSON object\n fields: {:?}", + self.0.metadata().name(), + data + ), + // If we *aren't* in debug mode, it's probably best not to + // crash the program, let's log the field found but also an + // message saying it's type is invalid + Ok(value) => { + serializer.serialize_entry("field", &value)?; + serializer.serialize_entry("field_error", "field was no a valid object")? + } + // We have previously recorded fields for this span + // should be valid JSON. However, they appear to *not* + // be valid JSON. This is almost certainly a bug, so + // panic if we're in debug mode + Err(e) if cfg!(debug_assertions) => panic!( + "span '{}' had malformed fields! this is a bug.\n error: {}\n fields: {:?}", + self.0.metadata().name(), + e, + data + ), + // If we *aren't* in debug mode, it's probably best not + // crash the program, but let's at least make sure it's clear + // that the fields are not supposed to be missing. + Err(e) => serializer.serialize_entry("field_error", &format!("{}", e))?, + }; + serializer.serialize_entry("name", self.0.metadata().name())?; + serializer.end() + } +} + +impl FormatEvent for Format +where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static, + T: FormatTime, +{ + fn format_event( + &self, + ctx: &FmtContext<'_, S, N>, + mut writer: Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result + where + S: Subscriber + for<'a> LookupSpan<'a>, + { + let mut timestamp = String::new(); + self.timer.format_time(&mut Writer::new(&mut timestamp))?; + + #[cfg(feature = "tracing-log")] + let normalized_meta = event.normalized_metadata(); + #[cfg(feature = "tracing-log")] + let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); + #[cfg(not(feature = "tracing-log"))] + let meta = event.metadata(); + + let mut visit = || { + let mut serializer = Serializer::new(WriteAdaptor::new(&mut writer)); + + let mut serializer = serializer.serialize_map(None)?; + + if self.display_timestamp { + serializer.serialize_entry("timestamp", ×tamp)?; + } + + if self.display_level { + serializer.serialize_entry("level", &meta.level().as_serde())?; + } + + let format_field_marker: std::marker::PhantomData = std::marker::PhantomData; + + let current_span = if self.format.display_current_span || self.format.display_span_list + { + event + .parent() + .and_then(|id| ctx.span(id)) + .or_else(|| ctx.lookup_current()) + } else { + None + }; + + if self.format.flatten_event { + let mut visitor = tracing_serde::SerdeMapVisitor::new(serializer); + event.record(&mut visitor); + + serializer = visitor.take_serializer()?; + } else { + use tracing_serde::fields::AsMap; + serializer.serialize_entry("fields", &event.field_map())?; + }; + + if self.display_target { + serializer.serialize_entry("target", meta.target())?; + } + + if self.format.display_current_span { + if let Some(ref span) = current_span { + serializer + .serialize_entry("span", &SerializableSpan(span, format_field_marker)) + .unwrap_or(()); + } + } + + if self.format.display_span_list && current_span.is_some() { + serializer.serialize_entry( + "spans", + &SerializableContext(&ctx.ctx, format_field_marker), + )?; + } + + if self.display_thread_name { + let current_thread = std::thread::current(); + match current_thread.name() { + Some(name) => { + serializer.serialize_entry("threadName", name)?; + } + // fall-back to thread id when name is absent and ids are not enabled + None if !self.display_thread_id => { + serializer + .serialize_entry("threadName", &format!("{:?}", current_thread.id()))?; + } + _ => {} + } + } + + if self.display_thread_id { + serializer + .serialize_entry("threadId", &format!("{:?}", std::thread::current().id()))?; + } + + serializer.end() + }; + + visit().map_err(|_| fmt::Error)?; + writeln!(writer) + } +} + +impl Default for Json { + fn default() -> Json { + Json { + flatten_event: false, + display_current_span: true, + display_span_list: true, + } + } +} + +/// The JSON [`FormatFields`] implementation. +/// +/// [`FormatFields`]: trait.FormatFields.html +#[derive(Debug)] +pub struct JsonFields { + // reserve the ability to add fields to this without causing a breaking + // change in the future. + _private: (), +} + +impl JsonFields { + /// Returns a new JSON [`FormatFields`] implementation. + /// + /// [`FormatFields`]: trait.FormatFields.html + pub fn new() -> Self { + Self { _private: () } + } +} + +impl Default for JsonFields { + fn default() -> Self { + Self::new() + } +} + +impl<'a> FormatFields<'a> for JsonFields { + /// Format the provided `fields` to the provided `writer`, returning a result. + fn format_fields(&self, mut writer: Writer<'_>, fields: R) -> fmt::Result { + let mut v = JsonVisitor::new(&mut writer); + fields.record(&mut v); + v.finish() + } + + /// Record additional field(s) on an existing span. + /// + /// By default, this appends a space to the current set of fields if it is + /// non-empty, and then calls `self.format_fields`. If different behavior is + /// required, the default implementation of this method can be overridden. + fn add_fields( + &self, + current: &'a mut FormattedFields, + fields: &Record<'_>, + ) -> fmt::Result { + if current.is_empty() { + // If there are no previously recorded fields, we can just reuse the + // existing string. + let mut writer = current.as_writer(); + let mut v = JsonVisitor::new(&mut writer); + fields.record(&mut v); + v.finish()?; + return Ok(()); + } + + // If fields were previously recorded on this span, we need to parse + // the current set of fields as JSON, add the new fields, and + // re-serialize them. Otherwise, if we just appended the new fields + // to a previously serialized JSON object, we would end up with + // malformed JSON. + // + // XXX(eliza): this is far from efficient, but unfortunately, it is + // necessary as long as the JSON formatter is implemented on top of + // an interface that stores all formatted fields as strings. + // + // We should consider reimplementing the JSON formatter as a + // separate layer, rather than a formatter for the `fmt` layer — + // then, we could store fields as JSON values, and add to them + // without having to parse and re-serialize. + let mut new = String::new(); + let map: BTreeMap<&'_ str, serde_json::Value> = + serde_json::from_str(current).map_err(|_| fmt::Error)?; + let mut v = JsonVisitor::new(&mut new); + v.values = map; + fields.record(&mut v); + v.finish()?; + current.fields = new; + + Ok(()) + } +} + +/// The [visitor] produced by [`JsonFields`]'s [`MakeVisitor`] implementation. +/// +/// [visitor]: ../../field/trait.Visit.html +/// [`JsonFields`]: struct.JsonFields.html +/// [`MakeVisitor`]: ../../field/trait.MakeVisitor.html +pub struct JsonVisitor<'a> { + values: BTreeMap<&'a str, serde_json::Value>, + writer: &'a mut dyn Write, +} + +impl<'a> fmt::Debug for JsonVisitor<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("JsonVisitor {{ values: {:?} }}", self.values)) + } +} + +impl<'a> JsonVisitor<'a> { + /// Returns a new default visitor that formats to the provided `writer`. + /// + /// # Arguments + /// - `writer`: the writer to format to. + /// - `is_empty`: whether or not any fields have been previously written to + /// that writer. + pub fn new(writer: &'a mut dyn Write) -> Self { + Self { + values: BTreeMap::new(), + writer, + } + } +} + +impl<'a> crate::field::VisitFmt for JsonVisitor<'a> { + fn writer(&mut self) -> &mut dyn fmt::Write { + self.writer + } +} + +impl<'a> crate::field::VisitOutput for JsonVisitor<'a> { + fn finish(self) -> fmt::Result { + let inner = || { + let mut serializer = Serializer::new(WriteAdaptor::new(self.writer)); + let mut ser_map = serializer.serialize_map(None)?; + + for (k, v) in self.values { + ser_map.serialize_entry(k, &v)?; + } + + ser_map.end() + }; + + if inner().is_err() { + Err(fmt::Error) + } else { + Ok(()) + } + } +} + +impl<'a> field::Visit for JsonVisitor<'a> { + /// Visit a double precision floating point value. + fn record_f64(&mut self, field: &Field, value: f64) { + self.values + .insert(field.name(), serde_json::Value::from(value)); + } + + /// Visit a signed 64-bit integer value. + fn record_i64(&mut self, field: &Field, value: i64) { + self.values + .insert(field.name(), serde_json::Value::from(value)); + } + + /// Visit an unsigned 64-bit integer value. + fn record_u64(&mut self, field: &Field, value: u64) { + self.values + .insert(field.name(), serde_json::Value::from(value)); + } + + /// Visit a boolean value. + fn record_bool(&mut self, field: &Field, value: bool) { + self.values + .insert(field.name(), serde_json::Value::from(value)); + } + + /// Visit a string value. + fn record_str(&mut self, field: &Field, value: &str) { + self.values + .insert(field.name(), serde_json::Value::from(value)); + } + + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + match field.name() { + // Skip fields that are actually log metadata that have already been handled + #[cfg(feature = "tracing-log")] + name if name.starts_with("log.") => (), + name if name.starts_with("r#") => { + self.values + .insert(&name[2..], serde_json::Value::from(format!("{:?}", value))); + } + name => { + self.values + .insert(name, serde_json::Value::from(format!("{:?}", value))); + } + }; + } +} +#[cfg(test)] +mod test { + use super::*; + use crate::fmt::{format::FmtSpan, test::MockMakeWriter, time::FormatTime, SubscriberBuilder}; + use tracing::{self, subscriber::with_default}; + + use std::fmt; + + struct MockTime; + impl FormatTime for MockTime { + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + write!(w, "fake time") + } + } + + fn subscriber() -> SubscriberBuilder> { + SubscriberBuilder::default().json() + } + + #[test] + fn json() { + let expected = + "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; + let subscriber = subscriber() + .flatten_event(false) + .with_current_span(true) + .with_span_list(true); + test_json(expected, subscriber, || { + let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); + let _guard = span.enter(); + tracing::info!("some json test"); + }); + } + + #[test] + fn json_flattened_event() { + let expected = + "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"message\":\"some json test\"}\n"; + + let subscriber = subscriber() + .flatten_event(true) + .with_current_span(true) + .with_span_list(true); + test_json(expected, subscriber, || { + let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); + let _guard = span.enter(); + tracing::info!("some json test"); + }); + } + + #[test] + fn json_disabled_current_span_event() { + let expected = + "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; + let subscriber = subscriber() + .flatten_event(false) + .with_current_span(false) + .with_span_list(true); + test_json(expected, subscriber, || { + let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); + let _guard = span.enter(); + tracing::info!("some json test"); + }); + } + + #[test] + fn json_disabled_span_list_event() { + let expected = + "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; + let subscriber = subscriber() + .flatten_event(false) + .with_current_span(true) + .with_span_list(false); + test_json(expected, subscriber, || { + let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); + let _guard = span.enter(); + tracing::info!("some json test"); + }); + } + + #[test] + fn json_nested_span() { + let expected = + "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":43,\"name\":\"nested_json_span\",\"number\":4},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3},{\"answer\":43,\"name\":\"nested_json_span\",\"number\":4}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; + let subscriber = subscriber() + .flatten_event(false) + .with_current_span(true) + .with_span_list(true); + test_json(expected, subscriber, || { + let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); + let _guard = span.enter(); + let span = tracing::span!( + tracing::Level::INFO, + "nested_json_span", + answer = 43, + number = 4 + ); + let _guard = span.enter(); + tracing::info!("some json test"); + }); + } + + #[test] + fn json_no_span() { + let expected = + "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; + let subscriber = subscriber() + .flatten_event(false) + .with_current_span(true) + .with_span_list(true); + test_json(expected, subscriber, || { + tracing::info!("some json test"); + }); + } + + #[test] + fn record_works() { + // This test reproduces issue #707, where using `Span::record` causes + // any events inside the span to be ignored. + + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt() + .json() + .with_writer(make_writer.clone()) + .finish(); + + with_default(subscriber, || { + tracing::info!("an event outside the root span"); + assert_eq!( + parse_as_json(&make_writer)["fields"]["message"], + "an event outside the root span" + ); + + let span = tracing::info_span!("the span", na = tracing::field::Empty); + span.record("na", &"value"); + let _enter = span.enter(); + + tracing::info!("an event inside the root span"); + assert_eq!( + parse_as_json(&make_writer)["fields"]["message"], + "an event inside the root span" + ); + }); + } + + #[test] + fn json_span_event_show_correct_context() { + let buffer = MockMakeWriter::default(); + let subscriber = subscriber() + .with_writer(buffer.clone()) + .flatten_event(false) + .with_current_span(true) + .with_span_list(false) + .with_span_events(FmtSpan::FULL) + .finish(); + + with_default(subscriber, || { + let context = "parent"; + let parent_span = tracing::info_span!("parent_span", context); + + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "new"); + assert_eq!(event["span"]["context"], "parent"); + + let _parent_enter = parent_span.enter(); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "enter"); + assert_eq!(event["span"]["context"], "parent"); + + let context = "child"; + let child_span = tracing::info_span!("child_span", context); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "new"); + assert_eq!(event["span"]["context"], "child"); + + let _child_enter = child_span.enter(); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "enter"); + assert_eq!(event["span"]["context"], "child"); + + drop(_child_enter); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "exit"); + assert_eq!(event["span"]["context"], "child"); + + drop(child_span); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "close"); + assert_eq!(event["span"]["context"], "child"); + + drop(_parent_enter); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "exit"); + assert_eq!(event["span"]["context"], "parent"); + + drop(parent_span); + let event = parse_as_json(&buffer); + assert_eq!(event["fields"]["message"], "close"); + assert_eq!(event["span"]["context"], "parent"); + }); + } + + #[test] + fn json_span_event_with_no_fields() { + // Check span events serialize correctly. + // Discussion: https://github.com/tokio-rs/tracing/issues/829#issuecomment-661984255 + let buffer = MockMakeWriter::default(); + let subscriber = subscriber() + .with_writer(buffer.clone()) + .flatten_event(false) + .with_current_span(false) + .with_span_list(false) + .with_span_events(FmtSpan::FULL) + .finish(); + + with_default(subscriber, || { + let span = tracing::info_span!("valid_json"); + assert_eq!(parse_as_json(&buffer)["fields"]["message"], "new"); + + let _enter = span.enter(); + assert_eq!(parse_as_json(&buffer)["fields"]["message"], "enter"); + + drop(_enter); + assert_eq!(parse_as_json(&buffer)["fields"]["message"], "exit"); + + drop(span); + assert_eq!(parse_as_json(&buffer)["fields"]["message"], "close"); + }); + } + + fn parse_as_json(buffer: &MockMakeWriter) -> serde_json::Value { + let buf = String::from_utf8(buffer.buf().to_vec()).unwrap(); + let json = buf + .lines() + .last() + .expect("expected at least one line to be written!"); + match serde_json::from_str(json) { + Ok(v) => v, + Err(e) => panic!( + "assertion failed: JSON shouldn't be malformed\n error: {}\n json: {}", + e, json + ), + } + } + + fn test_json( + expected: &str, + builder: crate::fmt::SubscriberBuilder>, + producer: impl FnOnce() -> T, + ) { + let make_writer = MockMakeWriter::default(); + let subscriber = builder + .with_writer(make_writer.clone()) + .with_timer(MockTime) + .finish(); + + with_default(subscriber, producer); + + let buf = make_writer.buf(); + let actual = std::str::from_utf8(&buf[..]).unwrap(); + assert_eq!( + serde_json::from_str::>(expected) + .unwrap(), + serde_json::from_str(actual).unwrap() + ); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/format/mod.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/format/mod.rs new file mode 100644 index 000000000..9001e102e --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/format/mod.rs @@ -0,0 +1,1798 @@ +//! Formatters for logging `tracing` events. +use super::time::{FormatTime, SystemTime}; +use crate::{ + field::{MakeOutput, MakeVisitor, RecordFields, VisitFmt, VisitOutput}, + fmt::fmt_layer::FmtContext, + fmt::fmt_layer::FormattedFields, + registry::LookupSpan, +}; + +use std::fmt::{self, Debug, Display, Write}; +use tracing_core::{ + field::{self, Field, Visit}, + span, Event, Level, Subscriber, +}; + +#[cfg(feature = "tracing-log")] +use tracing_log::NormalizeEvent; + +#[cfg(feature = "ansi")] +use ansi_term::{Colour, Style}; + +#[cfg(feature = "json")] +mod json; +#[cfg(feature = "json")] +#[cfg_attr(docsrs, doc(cfg(feature = "json")))] +pub use json::*; + +#[cfg(feature = "ansi")] +mod pretty; +#[cfg(feature = "ansi")] +#[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] +pub use pretty::*; + +/// A type that can format a tracing [`Event`] to a [`Writer`]. +/// +/// `FormatEvent` is primarily used in the context of [`fmt::Subscriber`] or +/// [`fmt::Layer`]. Each time an event is dispatched to [`fmt::Subscriber`] or +/// [`fmt::Layer`], the subscriber or layer +/// forwards it to its associated `FormatEvent` to emit a log message. +/// +/// This trait is already implemented for function pointers with the same +/// signature as `format_event`. +/// +/// # Arguments +/// +/// The following arguments are passed to `FormatEvent::format_event`: +/// +/// * A [`FmtContext`]. This is an extension of the [`layer::Context`] type, +/// which can be used for accessing stored information such as the current +/// span context an event occurred in. +/// +/// In addition, [`FmtContext`] exposes access to the [`FormatFields`] +/// implementation that the subscriber was configured to use via the +/// [`FmtContext::field_format`] method. This can be used when the +/// [`FormatEvent`] implementation needs to format the event's fields. +/// +/// For convenience, [`FmtContext`] also [implements `FormatFields`], +/// forwarding to the configured [`FormatFields`] type. +/// +/// * A [`Writer`] to which the formatted representation of the event is +/// written. This type implements the [`std::fmt::Write`] trait, and therefore +/// can be used with the [`std::write!`] and [`std::writeln!`] macros, as well +/// as calling [`std::fmt::Write`] methods directly. +/// +/// The [`Writer`] type also implements additional methods that provide +/// information about how the event should be formatted. The +/// [`Writer::has_ansi_escapes`] method indicates whether [ANSI terminal +/// escape codes] are supported by the underlying I/O writer that the event +/// will be written to. If this returns `true`, the formatter is permitted to +/// use ANSI escape codes to add colors and other text formatting to its +/// output. If it returns `false`, the event will be written to an output that +/// does not support ANSI escape codes (such as a log file), and they should +/// not be emitted. +/// +/// Crates like [`ansi_term`] and [`owo-colors`] can be used to add ANSI +/// escape codes to formatted output. +/// +/// * The actual [`Event`] to be formatted. +/// +/// # Examples +/// +/// This example re-implements a simiplified version of this crate's [default +/// formatter]: +/// +/// ```rust +/// use std::fmt; +/// use tracing_core::{Subscriber, Event}; +/// use tracing_subscriber::fmt::{ +/// format::{self, FormatEvent, FormatFields}, +/// FmtContext, +/// FormattedFields, +/// }; +/// use tracing_subscriber::registry::LookupSpan; +/// +/// struct MyFormatter; +/// +/// impl FormatEvent for MyFormatter +/// where +/// S: Subscriber + for<'a> LookupSpan<'a>, +/// N: for<'a> FormatFields<'a> + 'static, +/// { +/// fn format_event( +/// &self, +/// ctx: &FmtContext<'_, S, N>, +/// mut writer: format::Writer<'_>, +/// event: &Event<'_>, +/// ) -> fmt::Result { +/// // Format values from the event's's metadata: +/// let metadata = event.metadata(); +/// write!(&mut writer, "{} {}: ", metadata.level(), metadata.target())?; +/// +/// // Format all the spans in the event's span context. +/// if let Some(scope) = ctx.event_scope() { +/// for span in scope.from_root() { +/// write!(writer, "{}", span.name())?; +/// +/// // `FormattedFields` is a formatted representation of the span's +/// // fields, which is stored in its extensions by the `fmt` layer's +/// // `new_span` method. The fields will have been formatted +/// // by the same field formatter that's provided to the event +/// // formatter in the `FmtContext`. +/// let ext = span.extensions(); +/// let fields = &ext +/// .get::>() +/// .expect("will never be `None`"); +/// +/// // Skip formatting the fields if the span had no fields. +/// if !fields.is_empty() { +/// write!(writer, "{{{}}}", fields)?; +/// } +/// write!(writer, ": ")?; +/// } +/// } +/// +/// // Write fields on the event +/// ctx.field_format().format_fields(writer.by_ref(), event)?; +/// +/// writeln!(writer) +/// } +/// } +/// +/// let _subscriber = tracing_subscriber::fmt() +/// .event_format(MyFormatter) +/// .init(); +/// +/// let _span = tracing::info_span!("my_span", answer = 42).entered(); +/// tracing::info!(question = "life, the universe, and everything", "hello world"); +/// ``` +/// +/// This formatter will print events like this: +/// +/// ```text +/// DEBUG yak_shaving::shaver: some-span{field-on-span=foo}: started shaving yak +/// ``` +/// +/// [`fmt::Layer`]: super::Layer +/// [`fmt::Subscriber`]: super::Subscriber +/// [`Event`]: tracing::Event +/// [implements `FormatFields`]: super::FmtContext#impl-FormatFields<'writer> +/// [ANSI terminal escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code +/// [`Writer::has_ansi_escapes`]: Writer::has_ansi_escapes +/// [`ansi_term`]: https://crates.io/crates/ansi_term +/// [`owo-colors`]: https://crates.io/crates/owo-colors +/// [default formatter]: Full +pub trait FormatEvent +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'a> FormatFields<'a> + 'static, +{ + /// Write a log message for `Event` in `Context` to the given [`Writer`]. + fn format_event( + &self, + ctx: &FmtContext<'_, S, N>, + writer: Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result; +} + +impl FormatEvent + for fn(ctx: &FmtContext<'_, S, N>, Writer<'_>, &Event<'_>) -> fmt::Result +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'a> FormatFields<'a> + 'static, +{ + fn format_event( + &self, + ctx: &FmtContext<'_, S, N>, + writer: Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result { + (*self)(ctx, writer, event) + } +} +/// A type that can format a [set of fields] to a [`Writer`]. +/// +/// `FormatFields` is primarily used in the context of [`FmtSubscriber`]. Each +/// time a span or event with fields is recorded, the subscriber will format +/// those fields with its associated `FormatFields` implementation. +/// +/// [set of fields]: ../field/trait.RecordFields.html +/// [`FmtSubscriber`]: ../fmt/struct.Subscriber.html +pub trait FormatFields<'writer> { + /// Format the provided `fields` to the provided [`Writer`], returning a result. + fn format_fields(&self, writer: Writer<'writer>, fields: R) -> fmt::Result; + + /// Record additional field(s) on an existing span. + /// + /// By default, this appends a space to the current set of fields if it is + /// non-empty, and then calls `self.format_fields`. If different behavior is + /// required, the default implementation of this method can be overridden. + fn add_fields( + &self, + current: &'writer mut FormattedFields, + fields: &span::Record<'_>, + ) -> fmt::Result { + if !current.fields.is_empty() { + current.fields.push(' '); + } + self.format_fields(current.as_writer(), fields) + } +} + +/// Returns the default configuration for an [event formatter]. +/// +/// Methods on the returned event formatter can be used for further +/// configuration. For example: +/// +/// ```rust +/// let format = tracing_subscriber::fmt::format() +/// .without_time() // Don't include timestamps +/// .with_target(false) // Don't include event targets. +/// .with_level(false) // Don't include event levels. +/// .compact(); // Use a more compact, abbreviated format. +/// +/// // Use the configured formatter when building a new subscriber. +/// tracing_subscriber::fmt() +/// .event_format(format) +/// .init(); +/// ``` +pub fn format() -> Format { + Format::default() +} + +/// Returns the default configuration for a JSON [event formatter]. +#[cfg(feature = "json")] +#[cfg_attr(docsrs, doc(cfg(feature = "json")))] +pub fn json() -> Format { + format().json() +} + +/// Returns a [`FormatFields`] implementation that formats fields using the +/// provided function or closure. +/// +/// [`FormatFields`]: trait.FormatFields.html +pub fn debug_fn(f: F) -> FieldFn +where + F: Fn(&mut Writer<'_>, &Field, &dyn fmt::Debug) -> fmt::Result + Clone, +{ + FieldFn(f) +} + +/// A writer to which formatted representations of spans and events are written. +/// +/// This type is provided as input to the [`FormatEvent::format_event`] and +/// [`FormatFields::format_fields`] methods, which will write formatted +/// representations of [`Event`]s and [fields] to the `Writer`. +/// +/// This type implements the [`std::fmt::Write`] trait, allowing it to be used +/// with any function that takes an instance of [`std::fmt::Write`]. +/// Additionally, it can be used with the standard library's [`std::write!`] and +/// [`std::writeln!`] macros. +/// +/// Additionally, a `Writer` may expose additional `tracing`-specific +/// information to the formatter implementation. +pub struct Writer<'writer> { + writer: &'writer mut dyn fmt::Write, + // TODO(eliza): add ANSI support + is_ansi: bool, +} + +/// A [`FormatFields`] implementation that formats fields by calling a function +/// or closure. +/// +/// [`FormatFields`]: trait.FormatFields.html +#[derive(Debug, Clone)] +pub struct FieldFn(F); +/// The [visitor] produced by [`FieldFn`]'s [`MakeVisitor`] implementation. +/// +/// [visitor]: ../../field/trait.Visit.html +/// [`FieldFn`]: struct.FieldFn.html +/// [`MakeVisitor`]: ../../field/trait.MakeVisitor.html +pub struct FieldFnVisitor<'a, F> { + f: F, + writer: Writer<'a>, + result: fmt::Result, +} +/// Marker for `Format` that indicates that the compact log format should be used. +/// +/// The compact format only includes the fields from the most recently entered span. +#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +pub struct Compact; + +/// Marker for `Format` that indicates that the verbose log format should be used. +/// +/// The full format includes fields from all entered spans. +#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +pub struct Full; + +/// A pre-configured event formatter. +/// +/// You will usually want to use this as the `FormatEvent` for a `FmtSubscriber`. +/// +/// The default logging format, [`Full`] includes all fields in each event and its containing +/// spans. The [`Compact`] logging format includes only the fields from the most-recently-entered +/// span. +#[derive(Debug, Clone)] +pub struct Format { + format: F, + pub(crate) timer: T, + pub(crate) ansi: Option, + pub(crate) display_timestamp: bool, + pub(crate) display_target: bool, + pub(crate) display_level: bool, + pub(crate) display_thread_id: bool, + pub(crate) display_thread_name: bool, +} + +// === impl Writer === + +impl<'writer> Writer<'writer> { + // TODO(eliza): consider making this a public API? + // We may not want to do that if we choose to expose specialized + // constructors instead (e.g. `from_string` that stores whether the string + // is empty...?) + pub(crate) fn new(writer: &'writer mut impl fmt::Write) -> Self { + Self { + writer: writer as &mut dyn fmt::Write, + is_ansi: false, + } + } + + // TODO(eliza): consider making this a public API? + pub(crate) fn with_ansi(self, is_ansi: bool) -> Self { + Self { is_ansi, ..self } + } + + /// Return a new `Writer` that mutably borrows `self`. + /// + /// This can be used to temporarily borrow a `Writer` to pass a new `Writer` + /// to a function that takes a `Writer` by value, allowing the original writer + /// to still be used once that function returns. + pub fn by_ref(&mut self) -> Writer<'_> { + let is_ansi = self.is_ansi; + Writer { + writer: self as &mut dyn fmt::Write, + is_ansi, + } + } + + /// Writes a string slice into this `Writer`, returning whether the write succeeded. + /// + /// This method can only succeed if the entire string slice was successfully + /// written, and this method will not return until all data has been written + /// or an error occurs. + /// + /// This is identical to calling the [`write_str` method] from the `Writer`'s + /// [`std::fmt::Write`] implementation. However, it is also provided as an + /// inherent method, so that `Writer`s can be used without needing to import the + /// [`std::fmt::Write`] trait. + /// + /// # Errors + /// + /// This function will return an instance of [`std::fmt::Error`] on error. + /// + /// [`write_str` method]: std::fmt::Write::write_str + #[inline] + pub fn write_str(&mut self, s: &str) -> fmt::Result { + self.writer.write_str(s) + } + + /// Writes a [`char`] into this writer, returning whether the write succeeded. + /// + /// A single [`char`] may be encoded as more than one byte. + /// This method can only succeed if the entire byte sequence was successfully + /// written, and this method will not return until all data has been + /// written or an error occurs. + /// + /// This is identical to calling the [`write_char` method] from the `Writer`'s + /// [`std::fmt::Write`] implementation. However, it is also provided as an + /// inherent method, so that `Writer`s can be used without needing to import the + /// [`std::fmt::Write`] trait. + /// + /// # Errors + /// + /// This function will return an instance of [`std::fmt::Error`] on error. + /// + /// [`write_char` method]: std::fmt::Write::write_char + #[inline] + pub fn write_char(&mut self, c: char) -> fmt::Result { + self.writer.write_char(c) + } + + /// Glue for usage of the [`write!`] macro with `Writer`s. + /// + /// This method should generally not be invoked manually, but rather through + /// the [`write!`] macro itself. + /// + /// This is identical to calling the [`write_fmt` method] from the `Writer`'s + /// [`std::fmt::Write`] implementation. However, it is also provided as an + /// inherent method, so that `Writer`s can be used with the [`write!` macro] + /// without needing to import the + /// [`std::fmt::Write`] trait. + /// + /// [`write_fmt` method]: std::fmt::Write::write_fmt + pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { + self.writer.write_fmt(args) + } + + /// Returns `true` if [ANSI escape codes] may be used to add colors + /// and other formatting when writing to this `Writer`. + /// + /// If this returns `false`, formatters should not emit ANSI escape codes. + /// + /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code + pub fn has_ansi_escapes(&self) -> bool { + self.is_ansi + } + + pub(in crate::fmt::format) fn bold(&self) -> Style { + #[cfg(feature = "ansi")] + { + if self.is_ansi { + return Style::new().bold(); + } + } + + Style::new() + } + + pub(in crate::fmt::format) fn dimmed(&self) -> Style { + #[cfg(feature = "ansi")] + { + if self.is_ansi { + return Style::new().dimmed(); + } + } + + Style::new() + } + + pub(in crate::fmt::format) fn italic(&self) -> Style { + #[cfg(feature = "ansi")] + { + if self.is_ansi { + return Style::new().italic(); + } + } + + Style::new() + } +} + +impl fmt::Write for Writer<'_> { + #[inline] + fn write_str(&mut self, s: &str) -> fmt::Result { + Writer::write_str(self, s) + } + + #[inline] + fn write_char(&mut self, c: char) -> fmt::Result { + Writer::write_char(self, c) + } + + #[inline] + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { + Writer::write_fmt(self, args) + } +} + +impl fmt::Debug for Writer<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Writer") + .field("writer", &format_args!("<&mut dyn fmt::Write>")) + .field("is_ansi", &self.is_ansi) + .finish() + } +} + +// === impl Format === + +impl Default for Format { + fn default() -> Self { + Format { + format: Full, + timer: SystemTime, + ansi: None, + display_timestamp: true, + display_target: true, + display_level: true, + display_thread_id: false, + display_thread_name: false, + } + } +} + +impl Format { + /// Use a less verbose output format. + /// + /// See [`Compact`]. + pub fn compact(self) -> Format { + Format { + format: Compact, + timer: self.timer, + ansi: self.ansi, + display_target: self.display_target, + display_timestamp: self.display_timestamp, + display_level: self.display_level, + display_thread_id: self.display_thread_id, + display_thread_name: self.display_thread_name, + } + } + + /// Use an excessively pretty, human-readable output format. + /// + /// See [`Pretty`]. + /// + /// Note that this requires the "ansi" feature to be enabled. + /// + /// # Options + /// + /// [`Format::with_ansi`] can be used to disable ANSI terminal escape codes (which enable + /// formatting such as colors, bold, italic, etc) in event formatting. However, a field + /// formatter must be manually provided to avoid ANSI in the formatting of parent spans, like + /// so: + /// + /// ``` + /// # use tracing_subscriber::fmt::format; + /// tracing_subscriber::fmt() + /// .pretty() + /// .with_ansi(false) + /// .fmt_fields(format::PrettyFields::new().with_ansi(false)) + /// // ... other settings ... + /// .init(); + /// ``` + #[cfg(feature = "ansi")] + #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + pub fn pretty(self) -> Format { + Format { + format: Pretty::default(), + timer: self.timer, + ansi: self.ansi, + display_target: self.display_target, + display_timestamp: self.display_timestamp, + display_level: self.display_level, + display_thread_id: self.display_thread_id, + display_thread_name: self.display_thread_name, + } + } + + /// Use the full JSON format. + /// + /// The full format includes fields from all entered spans. + /// + /// # Example Output + /// + /// ```ignore,json + /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate","fields":{"message":"some message", "key": "value"}} + /// ``` + /// + /// # Options + /// + /// - [`Format::flatten_event`] can be used to enable flattening event fields into the root + /// object. + /// + /// [`Format::flatten_event`]: #method.flatten_event + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + pub fn json(self) -> Format { + Format { + format: Json::default(), + timer: self.timer, + ansi: self.ansi, + display_target: self.display_target, + display_timestamp: self.display_timestamp, + display_level: self.display_level, + display_thread_id: self.display_thread_id, + display_thread_name: self.display_thread_name, + } + } + + /// Use the given [`timer`] for log message timestamps. + /// + /// See [`time` module] for the provided timer implementations. + /// + /// Note that using the `"time"` feature flag enables the + /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the + /// [`time` crate] to provide more sophisticated timestamp formatting + /// options. + /// + /// [`timer`]: super::time::FormatTime + /// [`time` module]: mod@super::time + /// [`UtcTime`]: super::time::UtcTime + /// [`LocalTime`]: super::time::LocalTime + /// [`time` crate]: https://docs.rs/time/0.3 + pub fn with_timer(self, timer: T2) -> Format { + Format { + format: self.format, + timer, + ansi: self.ansi, + display_target: self.display_target, + display_timestamp: self.display_timestamp, + display_level: self.display_level, + display_thread_id: self.display_thread_id, + display_thread_name: self.display_thread_name, + } + } + + /// Do not emit timestamps with log messages. + pub fn without_time(self) -> Format { + Format { + format: self.format, + timer: (), + ansi: self.ansi, + display_timestamp: false, + display_target: self.display_target, + display_level: self.display_level, + display_thread_id: self.display_thread_id, + display_thread_name: self.display_thread_name, + } + } + + /// Enable ANSI terminal colors for formatted output. + pub fn with_ansi(self, ansi: bool) -> Format { + Format { + ansi: Some(ansi), + ..self + } + } + + /// Sets whether or not an event's target is displayed. + pub fn with_target(self, display_target: bool) -> Format { + Format { + display_target, + ..self + } + } + + /// Sets whether or not an event's level is displayed. + pub fn with_level(self, display_level: bool) -> Format { + Format { + display_level, + ..self + } + } + + /// Sets whether or not the [thread ID] of the current thread is displayed + /// when formatting events + /// + /// [thread ID]: https://doc.rust-lang.org/stable/std/thread/struct.ThreadId.html + pub fn with_thread_ids(self, display_thread_id: bool) -> Format { + Format { + display_thread_id, + ..self + } + } + + /// Sets whether or not the [name] of the current thread is displayed + /// when formatting events + /// + /// [name]: https://doc.rust-lang.org/stable/std/thread/index.html#naming-threads + pub fn with_thread_names(self, display_thread_name: bool) -> Format { + Format { + display_thread_name, + ..self + } + } + + #[inline] + fn format_timestamp(&self, writer: &mut Writer<'_>) -> fmt::Result + where + T: FormatTime, + { + // If timestamps are disabled, do nothing. + if !self.display_timestamp { + return Ok(()); + } + + // If ANSI color codes are enabled, format the timestamp with ANSI + // colors. + #[cfg(feature = "ansi")] + { + if writer.has_ansi_escapes() { + let style = Style::new().dimmed(); + write!(writer, "{}", style.prefix())?; + self.timer.format_time(writer)?; + write!(writer, "{} ", style.suffix())?; + return Ok(()); + } + } + + // Otherwise, just format the timestamp without ANSI formatting. + self.timer.format_time(writer)?; + writer.write_char(' ') + } +} + +#[cfg(feature = "json")] +#[cfg_attr(docsrs, doc(cfg(feature = "json")))] +impl Format { + /// Use the full JSON format with the event's event fields flattened. + /// + /// # Example Output + /// + /// ```ignore,json + /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate", "message":"some message", "key": "value"} + /// ``` + /// See [`Json`](../format/struct.Json.html). + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + pub fn flatten_event(mut self, flatten_event: bool) -> Format { + self.format.flatten_event(flatten_event); + self + } + + /// Sets whether or not the formatter will include the current span in + /// formatted events. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + pub fn with_current_span(mut self, display_current_span: bool) -> Format { + self.format.with_current_span(display_current_span); + self + } + + /// Sets whether or not the formatter will include a list (from root to + /// leaf) of all currently entered spans in formatted events. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + pub fn with_span_list(mut self, display_span_list: bool) -> Format { + self.format.with_span_list(display_span_list); + self + } +} + +impl FormatEvent for Format +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'a> FormatFields<'a> + 'static, + T: FormatTime, +{ + fn format_event( + &self, + ctx: &FmtContext<'_, S, N>, + mut writer: Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result { + #[cfg(feature = "tracing-log")] + let normalized_meta = event.normalized_metadata(); + #[cfg(feature = "tracing-log")] + let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); + #[cfg(not(feature = "tracing-log"))] + let meta = event.metadata(); + + // if the `Format` struct *also* has an ANSI color configuration, + // override the writer...the API for configuring ANSI color codes on the + // `Format` struct is deprecated, but we still need to honor those + // configurations. + if let Some(ansi) = self.ansi { + writer = writer.with_ansi(ansi); + } + + self.format_timestamp(&mut writer)?; + + if self.display_level { + let fmt_level = { + #[cfg(feature = "ansi")] + { + FmtLevel::new(meta.level(), writer.has_ansi_escapes()) + } + #[cfg(not(feature = "ansi"))] + { + FmtLevel::new(meta.level()) + } + }; + write!(writer, "{} ", fmt_level)?; + } + + if self.display_thread_name { + let current_thread = std::thread::current(); + match current_thread.name() { + Some(name) => { + write!(writer, "{} ", FmtThreadName::new(name))?; + } + // fall-back to thread id when name is absent and ids are not enabled + None if !self.display_thread_id => { + write!(writer, "{:0>2?} ", current_thread.id())?; + } + _ => {} + } + } + + if self.display_thread_id { + write!(writer, "{:0>2?} ", std::thread::current().id())?; + } + + let dimmed = writer.dimmed(); + + if let Some(scope) = ctx.event_scope() { + let bold = writer.bold(); + + let mut seen = false; + + for span in scope.from_root() { + write!(writer, "{}", bold.paint(span.metadata().name()))?; + seen = true; + + let ext = span.extensions(); + if let Some(fields) = &ext.get::>() { + if !fields.is_empty() { + write!(writer, "{}{}{}", bold.paint("{"), fields, bold.paint("}"))?; + } + } + write!(writer, "{}", dimmed.paint(":"))?; + } + + if seen { + writer.write_char(' ')?; + } + }; + + if self.display_target { + write!( + writer, + "{}{} ", + dimmed.paint(meta.target()), + dimmed.paint(":") + )?; + } + + ctx.format_fields(writer.by_ref(), event)?; + writeln!(writer) + } +} + +impl FormatEvent for Format +where + S: Subscriber + for<'a> LookupSpan<'a>, + N: for<'a> FormatFields<'a> + 'static, + T: FormatTime, +{ + fn format_event( + &self, + ctx: &FmtContext<'_, S, N>, + mut writer: Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result { + #[cfg(feature = "tracing-log")] + let normalized_meta = event.normalized_metadata(); + #[cfg(feature = "tracing-log")] + let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); + #[cfg(not(feature = "tracing-log"))] + let meta = event.metadata(); + + // if the `Format` struct *also* has an ANSI color configuration, + // override the writer...the API for configuring ANSI color codes on the + // `Format` struct is deprecated, but we still need to honor those + // configurations. + if let Some(ansi) = self.ansi { + writer = writer.with_ansi(ansi); + } + + self.format_timestamp(&mut writer)?; + + if self.display_level { + let fmt_level = { + #[cfg(feature = "ansi")] + { + FmtLevel::new(meta.level(), writer.has_ansi_escapes()) + } + #[cfg(not(feature = "ansi"))] + { + FmtLevel::new(meta.level()) + } + }; + write!(writer, "{} ", fmt_level)?; + } + + if self.display_thread_name { + let current_thread = std::thread::current(); + match current_thread.name() { + Some(name) => { + write!(writer, "{} ", FmtThreadName::new(name))?; + } + // fall-back to thread id when name is absent and ids are not enabled + None if !self.display_thread_id => { + write!(writer, "{:0>2?} ", current_thread.id())?; + } + _ => {} + } + } + + if self.display_thread_id { + write!(writer, "{:0>2?} ", std::thread::current().id())?; + } + + let fmt_ctx = { + #[cfg(feature = "ansi")] + { + FmtCtx::new(ctx, event.parent(), writer.has_ansi_escapes()) + } + #[cfg(not(feature = "ansi"))] + { + FmtCtx::new(&ctx, event.parent()) + } + }; + write!(writer, "{}", fmt_ctx)?; + + if self.display_target { + write!( + writer, + "{}{} ", + writer.bold().paint(meta.target()), + writer.dimmed().paint(":") + )?; + } + + ctx.format_fields(writer.by_ref(), event)?; + + let dimmed = writer.dimmed(); + for span in ctx + .event_scope() + .into_iter() + .map(crate::registry::Scope::from_root) + .flatten() + { + let exts = span.extensions(); + if let Some(fields) = exts.get::>() { + if !fields.is_empty() { + write!(writer, " {}", dimmed.paint(&fields.fields))?; + } + } + } + writeln!(writer) + } +} + +// === impl FormatFields === +impl<'writer, M> FormatFields<'writer> for M +where + M: MakeOutput, fmt::Result>, + M::Visitor: VisitFmt + VisitOutput, +{ + fn format_fields(&self, writer: Writer<'writer>, fields: R) -> fmt::Result { + let mut v = self.make_visitor(writer); + fields.record(&mut v); + v.finish() + } +} + +/// The default [`FormatFields`] implementation. +/// +/// [`FormatFields`]: trait.FormatFields.html +#[derive(Debug)] +pub struct DefaultFields { + // reserve the ability to add fields to this without causing a breaking + // change in the future. + _private: (), +} + +/// The [visitor] produced by [`DefaultFields`]'s [`MakeVisitor`] implementation. +/// +/// [visitor]: super::super::field::Visit +/// [`MakeVisitor`]: super::super::field::MakeVisitor +#[derive(Debug)] +pub struct DefaultVisitor<'a> { + writer: Writer<'a>, + is_empty: bool, + result: fmt::Result, +} + +impl DefaultFields { + /// Returns a new default [`FormatFields`] implementation. + /// + /// [`FormatFields`]: trait.FormatFields.html + pub fn new() -> Self { + Self { _private: () } + } +} + +impl Default for DefaultFields { + fn default() -> Self { + Self::new() + } +} + +impl<'a> MakeVisitor> for DefaultFields { + type Visitor = DefaultVisitor<'a>; + + #[inline] + fn make_visitor(&self, target: Writer<'a>) -> Self::Visitor { + DefaultVisitor::new(target, true) + } +} + +// === impl DefaultVisitor === + +impl<'a> DefaultVisitor<'a> { + /// Returns a new default visitor that formats to the provided `writer`. + /// + /// # Arguments + /// - `writer`: the writer to format to. + /// - `is_empty`: whether or not any fields have been previously written to + /// that writer. + pub fn new(writer: Writer<'a>, is_empty: bool) -> Self { + Self { + writer, + is_empty, + result: Ok(()), + } + } + + fn maybe_pad(&mut self) { + if self.is_empty { + self.is_empty = false; + } else { + self.result = write!(self.writer, " "); + } + } +} + +impl<'a> field::Visit for DefaultVisitor<'a> { + fn record_str(&mut self, field: &Field, value: &str) { + if self.result.is_err() { + return; + } + + if field.name() == "message" { + self.record_debug(field, &format_args!("{}", value)) + } else { + self.record_debug(field, &value) + } + } + + fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { + if let Some(source) = value.source() { + let italic = self.writer.italic(); + self.record_debug( + field, + &format_args!( + "{} {}{}{}{}", + value, + italic.paint(field.name()), + italic.paint(".sources"), + self.writer.dimmed().paint("="), + ErrorSourceList(source) + ), + ) + } else { + self.record_debug(field, &format_args!("{}", value)) + } + } + + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + if self.result.is_err() { + return; + } + + self.maybe_pad(); + self.result = match field.name() { + "message" => write!(self.writer, "{:?}", value), + // Skip fields that are actually log metadata that have already been handled + #[cfg(feature = "tracing-log")] + name if name.starts_with("log.") => Ok(()), + name if name.starts_with("r#") => write!( + self.writer, + "{}{}{:?}", + self.writer.italic().paint(&name[2..]), + self.writer.dimmed().paint("="), + value + ), + name => write!( + self.writer, + "{}{}{:?}", + self.writer.italic().paint(name), + self.writer.dimmed().paint("="), + value + ), + }; + } +} + +impl<'a> crate::field::VisitOutput for DefaultVisitor<'a> { + fn finish(self) -> fmt::Result { + self.result + } +} + +impl<'a> crate::field::VisitFmt for DefaultVisitor<'a> { + fn writer(&mut self) -> &mut dyn fmt::Write { + &mut self.writer + } +} + +/// Renders an error into a list of sources, *including* the error +struct ErrorSourceList<'a>(&'a (dyn std::error::Error + 'static)); + +impl<'a> Display for ErrorSourceList<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut list = f.debug_list(); + let mut curr = Some(self.0); + while let Some(curr_err) = curr { + list.entry(&format_args!("{}", curr_err)); + curr = curr_err.source(); + } + list.finish() + } +} + +struct FmtCtx<'a, S, N> { + ctx: &'a FmtContext<'a, S, N>, + span: Option<&'a span::Id>, + #[cfg(feature = "ansi")] + ansi: bool, +} + +impl<'a, S, N: 'a> FmtCtx<'a, S, N> +where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static, +{ + #[cfg(feature = "ansi")] + pub(crate) fn new( + ctx: &'a FmtContext<'_, S, N>, + span: Option<&'a span::Id>, + ansi: bool, + ) -> Self { + Self { ctx, span, ansi } + } + + #[cfg(not(feature = "ansi"))] + pub(crate) fn new(ctx: &'a FmtContext<'_, S, N>, span: Option<&'a span::Id>) -> Self { + Self { ctx, span } + } + + fn bold(&self) -> Style { + #[cfg(feature = "ansi")] + { + if self.ansi { + return Style::new().bold(); + } + } + + Style::new() + } +} + +impl<'a, S, N: 'a> fmt::Display for FmtCtx<'a, S, N> +where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + N: for<'writer> FormatFields<'writer> + 'static, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let bold = self.bold(); + let mut seen = false; + + let span = self + .span + .and_then(|id| self.ctx.ctx.span(id)) + .or_else(|| self.ctx.ctx.lookup_current()); + + let scope = span.into_iter().flat_map(|span| span.scope().from_root()); + + for span in scope { + seen = true; + write!(f, "{}:", bold.paint(span.metadata().name()))?; + } + + if seen { + f.write_char(' ')?; + } + Ok(()) + } +} + +#[cfg(not(feature = "ansi"))] +struct Style; + +#[cfg(not(feature = "ansi"))] +impl Style { + fn new() -> Self { + Style + } + + fn bold(self) -> Self { + self + } + + fn paint(&self, d: impl fmt::Display) -> impl fmt::Display { + d + } +} + +struct FmtThreadName<'a> { + name: &'a str, +} + +impl<'a> FmtThreadName<'a> { + pub(crate) fn new(name: &'a str) -> Self { + Self { name } + } +} + +impl<'a> fmt::Display for FmtThreadName<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use std::sync::atomic::{ + AtomicUsize, + Ordering::{AcqRel, Acquire, Relaxed}, + }; + + // Track the longest thread name length we've seen so far in an atomic, + // so that it can be updated by any thread. + static MAX_LEN: AtomicUsize = AtomicUsize::new(0); + let len = self.name.len(); + // Snapshot the current max thread name length. + let mut max_len = MAX_LEN.load(Relaxed); + + while len > max_len { + // Try to set a new max length, if it is still the value we took a + // snapshot of. + match MAX_LEN.compare_exchange(max_len, len, AcqRel, Acquire) { + // We successfully set the new max value + Ok(_) => break, + // Another thread set a new max value since we last observed + // it! It's possible that the new length is actually longer than + // ours, so we'll loop again and check whether our length is + // still the longest. If not, we'll just use the newer value. + Err(actual) => max_len = actual, + } + } + + // pad thread name using `max_len` + write!(f, "{:>width$}", self.name, width = max_len) + } +} + +struct FmtLevel<'a> { + level: &'a Level, + #[cfg(feature = "ansi")] + ansi: bool, +} + +impl<'a> FmtLevel<'a> { + #[cfg(feature = "ansi")] + pub(crate) fn new(level: &'a Level, ansi: bool) -> Self { + Self { level, ansi } + } + + #[cfg(not(feature = "ansi"))] + pub(crate) fn new(level: &'a Level) -> Self { + Self { level } + } +} + +const TRACE_STR: &str = "TRACE"; +const DEBUG_STR: &str = "DEBUG"; +const INFO_STR: &str = " INFO"; +const WARN_STR: &str = " WARN"; +const ERROR_STR: &str = "ERROR"; + +#[cfg(not(feature = "ansi"))] +impl<'a> fmt::Display for FmtLevel<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self.level { + Level::TRACE => f.pad(TRACE_STR), + Level::DEBUG => f.pad(DEBUG_STR), + Level::INFO => f.pad(INFO_STR), + Level::WARN => f.pad(WARN_STR), + Level::ERROR => f.pad(ERROR_STR), + } + } +} + +#[cfg(feature = "ansi")] +impl<'a> fmt::Display for FmtLevel<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.ansi { + match *self.level { + Level::TRACE => write!(f, "{}", Colour::Purple.paint(TRACE_STR)), + Level::DEBUG => write!(f, "{}", Colour::Blue.paint(DEBUG_STR)), + Level::INFO => write!(f, "{}", Colour::Green.paint(INFO_STR)), + Level::WARN => write!(f, "{}", Colour::Yellow.paint(WARN_STR)), + Level::ERROR => write!(f, "{}", Colour::Red.paint(ERROR_STR)), + } + } else { + match *self.level { + Level::TRACE => f.pad(TRACE_STR), + Level::DEBUG => f.pad(DEBUG_STR), + Level::INFO => f.pad(INFO_STR), + Level::WARN => f.pad(WARN_STR), + Level::ERROR => f.pad(ERROR_STR), + } + } + } +} + +// === impl FieldFn === + +impl<'a, F> MakeVisitor> for FieldFn +where + F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result + Clone, +{ + type Visitor = FieldFnVisitor<'a, F>; + + fn make_visitor(&self, writer: Writer<'a>) -> Self::Visitor { + FieldFnVisitor { + writer, + f: self.0.clone(), + result: Ok(()), + } + } +} + +impl<'a, F> Visit for FieldFnVisitor<'a, F> +where + F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result, +{ + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + if self.result.is_ok() { + self.result = (self.f)(&mut self.writer, field, value) + } + } +} + +impl<'a, F> VisitOutput for FieldFnVisitor<'a, F> +where + F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result, +{ + fn finish(self) -> fmt::Result { + self.result + } +} + +impl<'a, F> VisitFmt for FieldFnVisitor<'a, F> +where + F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result, +{ + fn writer(&mut self) -> &mut dyn fmt::Write { + &mut self.writer + } +} + +impl<'a, F> fmt::Debug for FieldFnVisitor<'a, F> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FieldFnVisitor") + .field("f", &format_args!("{}", std::any::type_name::())) + .field("writer", &self.writer) + .field("result", &self.result) + .finish() + } +} + +// === printing synthetic Span events === + +/// Configures what points in the span lifecycle are logged as events. +/// +/// See also [`with_span_events`](../struct.SubscriberBuilder.html#method.with_span_events). +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)] +pub struct FmtSpan(u8); + +impl FmtSpan { + /// one event when span is created + pub const NEW: FmtSpan = FmtSpan(1 << 0); + /// one event per enter of a span + pub const ENTER: FmtSpan = FmtSpan(1 << 1); + /// one event per exit of a span + pub const EXIT: FmtSpan = FmtSpan(1 << 2); + /// one event when the span is dropped + pub const CLOSE: FmtSpan = FmtSpan(1 << 3); + + /// spans are ignored (this is the default) + pub const NONE: FmtSpan = FmtSpan(0); + /// one event per enter/exit of a span + pub const ACTIVE: FmtSpan = FmtSpan(FmtSpan::ENTER.0 | FmtSpan::EXIT.0); + /// events at all points (new, enter, exit, drop) + pub const FULL: FmtSpan = + FmtSpan(FmtSpan::NEW.0 | FmtSpan::ENTER.0 | FmtSpan::EXIT.0 | FmtSpan::CLOSE.0); + + /// Check whether or not a certain flag is set for this [`FmtSpan`] + fn contains(&self, other: FmtSpan) -> bool { + self.clone() & other.clone() == other + } +} + +macro_rules! impl_fmt_span_bit_op { + ($trait:ident, $func:ident, $op:tt) => { + impl std::ops::$trait for FmtSpan { + type Output = FmtSpan; + + fn $func(self, rhs: Self) -> Self::Output { + FmtSpan(self.0 $op rhs.0) + } + } + }; +} + +macro_rules! impl_fmt_span_bit_assign_op { + ($trait:ident, $func:ident, $op:tt) => { + impl std::ops::$trait for FmtSpan { + fn $func(&mut self, rhs: Self) { + *self = FmtSpan(self.0 $op rhs.0) + } + } + }; +} + +impl_fmt_span_bit_op!(BitAnd, bitand, &); +impl_fmt_span_bit_op!(BitOr, bitor, |); +impl_fmt_span_bit_op!(BitXor, bitxor, ^); + +impl_fmt_span_bit_assign_op!(BitAndAssign, bitand_assign, &); +impl_fmt_span_bit_assign_op!(BitOrAssign, bitor_assign, |); +impl_fmt_span_bit_assign_op!(BitXorAssign, bitxor_assign, ^); + +impl Debug for FmtSpan { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut wrote_flag = false; + let mut write_flags = |flag, flag_str| -> fmt::Result { + if self.contains(flag) { + if wrote_flag { + f.write_str(" | ")?; + } + + f.write_str(flag_str)?; + wrote_flag = true; + } + + Ok(()) + }; + + if FmtSpan::NONE | self.clone() == FmtSpan::NONE { + f.write_str("FmtSpan::NONE")?; + } else { + write_flags(FmtSpan::NEW, "FmtSpan::NEW")?; + write_flags(FmtSpan::ENTER, "FmtSpan::ENTER")?; + write_flags(FmtSpan::EXIT, "FmtSpan::EXIT")?; + write_flags(FmtSpan::CLOSE, "FmtSpan::CLOSE")?; + } + + Ok(()) + } +} + +pub(super) struct FmtSpanConfig { + pub(super) kind: FmtSpan, + pub(super) fmt_timing: bool, +} + +impl FmtSpanConfig { + pub(super) fn without_time(self) -> Self { + Self { + kind: self.kind, + fmt_timing: false, + } + } + pub(super) fn with_kind(self, kind: FmtSpan) -> Self { + Self { + kind, + fmt_timing: self.fmt_timing, + } + } + pub(super) fn trace_new(&self) -> bool { + self.kind.contains(FmtSpan::NEW) + } + pub(super) fn trace_enter(&self) -> bool { + self.kind.contains(FmtSpan::ENTER) + } + pub(super) fn trace_exit(&self) -> bool { + self.kind.contains(FmtSpan::EXIT) + } + pub(super) fn trace_close(&self) -> bool { + self.kind.contains(FmtSpan::CLOSE) + } +} + +impl Debug for FmtSpanConfig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.kind.fmt(f) + } +} + +impl Default for FmtSpanConfig { + fn default() -> Self { + Self { + kind: FmtSpan::NONE, + fmt_timing: true, + } + } +} + +pub(super) struct TimingDisplay(pub(super) u64); +impl Display for TimingDisplay { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut t = self.0 as f64; + for unit in ["ns", "µs", "ms", "s"].iter() { + if t < 10.0 { + return write!(f, "{:.2}{}", t, unit); + } else if t < 100.0 { + return write!(f, "{:.1}{}", t, unit); + } else if t < 1000.0 { + return write!(f, "{:.0}{}", t, unit); + } + t /= 1000.0; + } + write!(f, "{:.0}s", t * 1000.0) + } +} + +#[cfg(test)] +pub(super) mod test { + use crate::fmt::{test::MockMakeWriter, time::FormatTime}; + use tracing::{ + self, + dispatcher::{set_default, Dispatch}, + subscriber::with_default, + }; + + use super::*; + use std::fmt; + + pub(crate) struct MockTime; + impl FormatTime for MockTime { + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + write!(w, "fake time") + } + } + + #[test] + fn disable_everything() { + // This test reproduces https://github.com/tokio-rs/tracing/issues/1354 + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .with_writer(make_writer.clone()) + .without_time() + .with_level(false) + .with_target(false) + .with_thread_ids(false) + .with_thread_names(false); + #[cfg(feature = "ansi")] + let subscriber = subscriber.with_ansi(false); + run_test(subscriber, make_writer, "hello\n") + } + + fn test_ansi( + is_ansi: bool, + expected: &str, + builder: crate::fmt::SubscriberBuilder>, + ) where + Format: FormatEvent, + T: Send + Sync + 'static, + { + let make_writer = MockMakeWriter::default(); + let subscriber = builder + .with_writer(make_writer.clone()) + .with_ansi(is_ansi) + .with_timer(MockTime); + run_test(subscriber, make_writer, expected) + } + + #[cfg(not(feature = "ansi"))] + fn test_without_ansi( + expected: &str, + builder: crate::fmt::SubscriberBuilder>, + ) where + Format: FormatEvent, + T: Send + Sync, + { + let make_writer = MockMakeWriter::default(); + let subscriber = builder.with_writer(make_writer).with_timer(MockTime); + run_test(subscriber, make_writer, expected) + } + + fn test_without_level( + expected: &str, + builder: crate::fmt::SubscriberBuilder>, + ) where + Format: FormatEvent, + T: Send + Sync + 'static, + { + let make_writer = MockMakeWriter::default(); + let subscriber = builder + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime); + run_test(subscriber, make_writer, expected); + } + + fn test_overridden_parents( + expected: &str, + builder: crate::fmt::SubscriberBuilder>, + ) where + Format: FormatEvent, + T: Send + Sync + 'static, + { + let make_writer = MockMakeWriter::default(); + let collector = builder + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + .finish(); + + with_default(collector, || { + let span1 = tracing::info_span!("span1", span = 1); + let span2 = tracing::info_span!(parent: &span1, "span2", span = 2); + tracing::info!(parent: &span2, "hello"); + }); + assert_eq!(expected, make_writer.get_string()); + } + + fn test_overridden_parents_in_scope( + expected1: &str, + expected2: &str, + builder: crate::fmt::SubscriberBuilder>, + ) where + Format: FormatEvent, + T: Send + Sync + 'static, + { + let make_writer = MockMakeWriter::default(); + let subscriber = builder + .with_writer(make_writer.clone()) + .with_level(false) + .with_ansi(false) + .with_timer(MockTime) + .finish(); + + with_default(subscriber, || { + let span1 = tracing::info_span!("span1", span = 1); + let span2 = tracing::info_span!(parent: &span1, "span2", span = 2); + let span3 = tracing::info_span!("span3", span = 3); + let _e3 = span3.enter(); + + tracing::info!("hello"); + assert_eq!(expected1, make_writer.get_string().as_str()); + + tracing::info!(parent: &span2, "hello"); + assert_eq!(expected2, make_writer.get_string().as_str()); + }); + } + + fn run_test(subscriber: impl Into, buf: MockMakeWriter, expected: &str) { + let _default = set_default(&subscriber.into()); + tracing::info!("hello"); + assert_eq!(expected, buf.get_string()) + } + + mod default { + use super::*; + #[cfg(feature = "ansi")] + #[test] + fn with_ansi_true() { + let expected = "\u{1b}[2mfake time\u{1b}[0m \u{1b}[32m INFO\u{1b}[0m \u{1b}[2mtracing_subscriber::fmt::format::test\u{1b}[0m\u{1b}[2m:\u{1b}[0m hello\n"; + test_ansi(true, expected, crate::fmt::Subscriber::builder()); + } + + #[cfg(feature = "ansi")] + #[test] + fn with_ansi_false() { + let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; + test_ansi(false, expected, crate::fmt::Subscriber::builder()); + } + + #[cfg(not(feature = "ansi"))] + #[test] + fn without_ansi() { + let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; + test_without_ansi(expected, crate::fmt::Subscriber::builder()) + } + + #[test] + fn without_level() { + let expected = "fake time tracing_subscriber::fmt::format::test: hello\n"; + test_without_level(expected, crate::fmt::Subscriber::builder()) + } + + #[test] + fn overridden_parents() { + let expected = "fake time span1{span=1}:span2{span=2}: tracing_subscriber::fmt::format::test: hello\n"; + test_overridden_parents(expected, crate::fmt::Subscriber::builder()) + } + + #[test] + fn overridden_parents_in_scope() { + test_overridden_parents_in_scope( + "fake time span3{span=3}: tracing_subscriber::fmt::format::test: hello\n", + "fake time span1{span=1}:span2{span=2}: tracing_subscriber::fmt::format::test: hello\n", + crate::fmt::Subscriber::builder(), + ) + } + } + + mod compact { + use super::*; + + #[cfg(feature = "ansi")] + #[test] + fn with_ansi_true() { + let expected = "\u{1b}[2mfake time\u{1b}[0m \u{1b}[32m INFO\u{1b}[0m \u{1b}[1mtracing_subscriber::fmt::format::test\u{1b}[0m\u{1b}[2m:\u{1b}[0m hello\n"; + test_ansi(true, expected, crate::fmt::Subscriber::builder().compact()) + } + + #[cfg(feature = "ansi")] + #[test] + fn with_ansi_false() { + let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; + test_ansi(false, expected, crate::fmt::Subscriber::builder().compact()); + } + + #[cfg(not(feature = "ansi"))] + #[test] + fn without_ansi() { + let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; + test_without_ansi(expected, crate::fmt::Subscriber::builder().compact()) + } + + #[test] + fn without_level() { + let expected = "fake time tracing_subscriber::fmt::format::test: hello\n"; + test_without_level(expected, crate::fmt::Subscriber::builder().compact()); + } + + #[test] + fn overridden_parents() { + let expected = "fake time span1:span2: tracing_subscriber::fmt::format::test: hello span=1 span=2\n"; + test_overridden_parents(expected, crate::fmt::Subscriber::builder().compact()) + } + + #[test] + fn overridden_parents_in_scope() { + test_overridden_parents_in_scope( + "fake time span3: tracing_subscriber::fmt::format::test: hello span=3\n", + "fake time span1:span2: tracing_subscriber::fmt::format::test: hello span=1 span=2\n", + crate::fmt::Subscriber::builder().compact(), + ) + } + } + + #[test] + fn format_nanos() { + fn fmt(t: u64) -> String { + TimingDisplay(t).to_string() + } + + assert_eq!(fmt(1), "1.00ns"); + assert_eq!(fmt(12), "12.0ns"); + assert_eq!(fmt(123), "123ns"); + assert_eq!(fmt(1234), "1.23µs"); + assert_eq!(fmt(12345), "12.3µs"); + assert_eq!(fmt(123456), "123µs"); + assert_eq!(fmt(1234567), "1.23ms"); + assert_eq!(fmt(12345678), "12.3ms"); + assert_eq!(fmt(123456789), "123ms"); + assert_eq!(fmt(1234567890), "1.23s"); + assert_eq!(fmt(12345678901), "12.3s"); + assert_eq!(fmt(123456789012), "123s"); + assert_eq!(fmt(1234567890123), "1235s"); + } + + #[test] + fn fmt_span_combinations() { + let f = FmtSpan::NONE; + assert!(!f.contains(FmtSpan::NEW)); + assert!(!f.contains(FmtSpan::ENTER)); + assert!(!f.contains(FmtSpan::EXIT)); + assert!(!f.contains(FmtSpan::CLOSE)); + + let f = FmtSpan::ACTIVE; + assert!(!f.contains(FmtSpan::NEW)); + assert!(f.contains(FmtSpan::ENTER)); + assert!(f.contains(FmtSpan::EXIT)); + assert!(!f.contains(FmtSpan::CLOSE)); + + let f = FmtSpan::FULL; + assert!(f.contains(FmtSpan::NEW)); + assert!(f.contains(FmtSpan::ENTER)); + assert!(f.contains(FmtSpan::EXIT)); + assert!(f.contains(FmtSpan::CLOSE)); + + let f = FmtSpan::NEW | FmtSpan::CLOSE; + assert!(f.contains(FmtSpan::NEW)); + assert!(!f.contains(FmtSpan::ENTER)); + assert!(!f.contains(FmtSpan::EXIT)); + assert!(f.contains(FmtSpan::CLOSE)); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/format/pretty.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/format/pretty.rs new file mode 100644 index 000000000..3e47e2d93 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/format/pretty.rs @@ -0,0 +1,415 @@ +use super::*; +use crate::{ + field::{VisitFmt, VisitOutput}, + fmt::fmt_layer::{FmtContext, FormattedFields}, + registry::LookupSpan, +}; + +use std::fmt; +use tracing_core::{ + field::{self, Field}, + Event, Level, Subscriber, +}; + +#[cfg(feature = "tracing-log")] +use tracing_log::NormalizeEvent; + +use ansi_term::{Colour, Style}; + +/// An excessively pretty, human-readable event formatter. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Pretty { + display_location: bool, +} + +/// The [visitor] produced by [`Pretty`]'s [`MakeVisitor`] implementation. +/// +/// [visitor]: field::Visit +/// [`MakeVisitor`]: crate::field::MakeVisitor +#[derive(Debug)] +pub struct PrettyVisitor<'a> { + writer: Writer<'a>, + is_empty: bool, + style: Style, + result: fmt::Result, +} + +/// An excessively pretty, human-readable [`MakeVisitor`] implementation. +/// +/// [`MakeVisitor`]: crate::field::MakeVisitor +#[derive(Debug)] +pub struct PrettyFields { + /// A value to override the provided `Writer`'s ANSI formatting + /// configuration. + /// + /// If this is `Some`, we override the `Writer`'s ANSI setting. This is + /// necessary in order to continue supporting the deprecated + /// `PrettyFields::with_ansi` method. If it is `None`, we don't override the + /// ANSI formatting configuration (because the deprecated method was not + /// called). + // TODO: when `PrettyFields::with_ansi` is removed, we can get rid + // of this entirely. + ansi: Option, +} + +// === impl Pretty === + +impl Default for Pretty { + fn default() -> Self { + Self { + display_location: true, + } + } +} + +impl Pretty { + fn style_for(level: &Level) -> Style { + match *level { + Level::TRACE => Style::new().fg(Colour::Purple), + Level::DEBUG => Style::new().fg(Colour::Blue), + Level::INFO => Style::new().fg(Colour::Green), + Level::WARN => Style::new().fg(Colour::Yellow), + Level::ERROR => Style::new().fg(Colour::Red), + } + } + + /// Sets whether the event's source code location is displayed. + /// + /// This defaults to `true`. + pub fn with_source_location(self, display_location: bool) -> Self { + Self { + display_location, + ..self + } + } +} + +impl Format { + /// Sets whether or not the source code location from which an event + /// originated is displayed. + /// + /// This defaults to `true`. + pub fn with_source_location(mut self, display_location: bool) -> Self { + self.format = self.format.with_source_location(display_location); + self + } +} + +impl FormatEvent for Format +where + C: Subscriber + for<'a> LookupSpan<'a>, + N: for<'a> FormatFields<'a> + 'static, + T: FormatTime, +{ + fn format_event( + &self, + ctx: &FmtContext<'_, C, N>, + mut writer: Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result { + #[cfg(feature = "tracing-log")] + let normalized_meta = event.normalized_metadata(); + #[cfg(feature = "tracing-log")] + let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); + #[cfg(not(feature = "tracing-log"))] + let meta = event.metadata(); + write!(&mut writer, " ")?; + + // if the `Format` struct *also* has an ANSI color configuration, + // override the writer...the API for configuring ANSI color codes on the + // `Format` struct is deprecated, but we still need to honor those + // configurations. + if let Some(ansi) = self.ansi { + writer = writer.with_ansi(ansi); + } + + self.format_timestamp(&mut writer)?; + + let style = if self.display_level && writer.has_ansi_escapes() { + Pretty::style_for(meta.level()) + } else { + Style::new() + }; + + if self.display_level { + write!( + writer, + "{} ", + super::FmtLevel::new(meta.level(), writer.has_ansi_escapes()) + )?; + } + + if self.display_target { + let target_style = if writer.has_ansi_escapes() { + style.bold() + } else { + style + }; + write!( + writer, + "{}{}{}: ", + target_style.prefix(), + meta.target(), + target_style.infix(style) + )?; + } + let mut v = PrettyVisitor::new(writer.by_ref(), true).with_style(style); + event.record(&mut v); + v.finish()?; + writer.write_char('\n')?; + + let dimmed = if writer.has_ansi_escapes() { + Style::new().dimmed().italic() + } else { + Style::new() + }; + let thread = self.display_thread_name || self.display_thread_id; + if let (true, Some(file), Some(line)) = + (self.format.display_location, meta.file(), meta.line()) + { + write!( + writer, + " {} {}:{}{}", + dimmed.paint("at"), + file, + line, + dimmed.paint(if thread { " " } else { "\n" }) + )?; + } else if thread { + write!(writer, " ")?; + } + + if thread { + write!(writer, "{} ", dimmed.paint("on"))?; + let thread = std::thread::current(); + if self.display_thread_name { + if let Some(name) = thread.name() { + write!(writer, "{}", name)?; + if self.display_thread_id { + write!(writer, " ({:?})", thread.id())?; + } + } else if !self.display_thread_id { + write!(writer, " {:?}", thread.id())?; + } + } else if self.display_thread_id { + write!(writer, " {:?}", thread.id())?; + } + writer.write_char('\n')?; + } + + let bold = writer.bold(); + let span = event + .parent() + .and_then(|id| ctx.span(id)) + .or_else(|| ctx.lookup_current()); + + let scope = span.into_iter().flat_map(|span| span.scope()); + + for span in scope { + let meta = span.metadata(); + if self.display_target { + write!( + writer, + " {} {}::{}", + dimmed.paint("in"), + meta.target(), + bold.paint(meta.name()), + )?; + } else { + write!( + writer, + " {} {}", + dimmed.paint("in"), + bold.paint(meta.name()), + )?; + } + + let ext = span.extensions(); + let fields = &ext + .get::>() + .expect("Unable to find FormattedFields in extensions; this is a bug"); + if !fields.is_empty() { + write!(writer, " {} {}", dimmed.paint("with"), fields)?; + } + writer.write_char('\n')?; + } + + writer.write_char('\n') + } +} + +impl<'writer> FormatFields<'writer> for Pretty { + fn format_fields(&self, writer: Writer<'writer>, fields: R) -> fmt::Result { + let mut v = PrettyVisitor::new(writer, false); + fields.record(&mut v); + v.finish() + } + + fn add_fields( + &self, + current: &'writer mut FormattedFields, + fields: &span::Record<'_>, + ) -> fmt::Result { + let empty = current.is_empty(); + let writer = current.as_writer(); + let mut v = PrettyVisitor::new(writer, empty); + fields.record(&mut v); + v.finish() + } +} + +// === impl PrettyFields === + +impl Default for PrettyFields { + fn default() -> Self { + Self::new() + } +} + +impl PrettyFields { + /// Returns a new default [`PrettyFields`] implementation. + pub fn new() -> Self { + // By default, don't override the `Writer`'s ANSI colors + // configuration. We'll only do this if the user calls the + // deprecated `PrettyFields::with_ansi` method. + Self { ansi: None } + } + + /// Enable ANSI encoding for formatted fields. + #[deprecated( + since = "0.3.3", + note = "Use `fmt::Subscriber::with_ansi` or `fmt::Layer::with_ansi` instead." + )] + pub fn with_ansi(self, ansi: bool) -> Self { + Self { + ansi: Some(ansi), + ..self + } + } +} + +impl<'a> MakeVisitor> for PrettyFields { + type Visitor = PrettyVisitor<'a>; + + #[inline] + fn make_visitor(&self, mut target: Writer<'a>) -> Self::Visitor { + if let Some(ansi) = self.ansi { + target = target.with_ansi(ansi); + } + PrettyVisitor::new(target, true) + } +} + +// === impl PrettyVisitor === + +impl<'a> PrettyVisitor<'a> { + /// Returns a new default visitor that formats to the provided `writer`. + /// + /// # Arguments + /// - `writer`: the writer to format to. + /// - `is_empty`: whether or not any fields have been previously written to + /// that writer. + pub fn new(writer: Writer<'a>, is_empty: bool) -> Self { + Self { + writer, + is_empty, + style: Style::default(), + result: Ok(()), + } + } + + pub(crate) fn with_style(self, style: Style) -> Self { + Self { style, ..self } + } + + fn write_padded(&mut self, value: &impl fmt::Debug) { + let padding = if self.is_empty { + self.is_empty = false; + "" + } else { + ", " + }; + self.result = write!(self.writer, "{}{:?}", padding, value); + } + + fn bold(&self) -> Style { + if self.writer.has_ansi_escapes() { + self.style.bold() + } else { + Style::new() + } + } +} + +impl<'a> field::Visit for PrettyVisitor<'a> { + fn record_str(&mut self, field: &Field, value: &str) { + if self.result.is_err() { + return; + } + + if field.name() == "message" { + self.record_debug(field, &format_args!("{}", value)) + } else { + self.record_debug(field, &value) + } + } + + fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { + if let Some(source) = value.source() { + let bold = self.bold(); + self.record_debug( + field, + &format_args!( + "{}, {}{}.sources{}: {}", + value, + bold.prefix(), + field, + bold.infix(self.style), + ErrorSourceList(source), + ), + ) + } else { + self.record_debug(field, &format_args!("{}", value)) + } + } + + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + if self.result.is_err() { + return; + } + let bold = self.bold(); + match field.name() { + "message" => self.write_padded(&format_args!("{}{:?}", self.style.prefix(), value,)), + // Skip fields that are actually log metadata that have already been handled + #[cfg(feature = "tracing-log")] + name if name.starts_with("log.") => self.result = Ok(()), + name if name.starts_with("r#") => self.write_padded(&format_args!( + "{}{}{}: {:?}", + bold.prefix(), + &name[2..], + bold.infix(self.style), + value + )), + name => self.write_padded(&format_args!( + "{}{}{}: {:?}", + bold.prefix(), + name, + bold.infix(self.style), + value + )), + }; + } +} + +impl<'a> VisitOutput for PrettyVisitor<'a> { + fn finish(mut self) -> fmt::Result { + write!(&mut self.writer, "{}", self.style.suffix())?; + self.result + } +} + +impl<'a> VisitFmt for PrettyVisitor<'a> { + fn writer(&mut self) -> &mut dyn fmt::Write { + &mut self.writer + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/mod.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/mod.rs new file mode 100644 index 000000000..d5deb8f0c --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/mod.rs @@ -0,0 +1,1275 @@ +//! A `Subscriber` for formatting and logging `tracing` data. +//! +//! # Overview +//! +//! [`tracing`] is a framework for instrumenting Rust programs with context-aware, +//! structured, event-based diagnostic information. This crate provides an +//! implementation of the [`Subscriber`] trait that records `tracing`'s `Event`s +//! and `Span`s by formatting them as text and logging them to stdout. +//! +//! # Usage +//! +//! First, add this to your `Cargo.toml` file: +//! +//! ```toml +//! [dependencies] +//! tracing-subscriber = "0.2" +//! ``` +//! +//! *Compiler support: requires rustc 1.39+* +//! +//! Add the following to your executable to initialize the default subscriber: +//! ```rust +//! use tracing_subscriber; +//! +//! tracing_subscriber::fmt::init(); +//! ``` +//! +//! ## Filtering Events with Environment Variables +//! +//! The default subscriber installed by `init` enables you to filter events +//! at runtime using environment variables (using the [`EnvFilter`]). +//! +//! The filter syntax is a superset of the [`env_logger`] syntax. +//! +//! For example: +//! - Setting `RUST_LOG=debug` enables all `Span`s and `Event`s +//! set to the log level `DEBUG` or higher +//! - Setting `RUST_LOG=my_crate=trace` enables `Span`s and `Event`s +//! in `my_crate` at all log levels +//! +//! **Note**: This should **not** be called by libraries. Libraries should use +//! [`tracing`] to publish `tracing` `Event`s. +//! +//! # Configuration +//! +//! You can configure a subscriber instead of using the defaults with +//! the following functions: +//! +//! ### Subscriber +//! +//! The [`FmtSubscriber`] formats and records `tracing` events as line-oriented logs. +//! You can create one by calling: +//! +//! ```rust +//! let subscriber = tracing_subscriber::fmt() +//! // ... add configuration +//! .finish(); +//! ``` +//! +//! You can find the configuration methods for [`FmtSubscriber`] in +//! [`SubscriberBuilder`]. +//! +//! ## Formatters +//! +//! The output format used by the layer and subscriber in this module is +//! represented by implementing the [`FormatEvent`] trait, and can be +//! customized. This module provides a number of formatter implementations: +//! +//! * [`format::Full`]: The default formatter. This emits human-readable, +//! single-line logs for each event that occurs, with the current span context +//! displayed before the formatted representation of the event. +//! +//! For example: +//!
    Finished dev [unoptimized + debuginfo] target(s) in 1.59s
+//!        Running `target/debug/examples/fmt`
+//!   Oct 24 12:55:47.814  INFO fmt: preparing to shave yaks number_of_yaks=3
+//!   Oct 24 12:55:47.814  INFO shaving_yaks{yaks=3}: fmt::yak_shave: shaving yaks
+//!   Oct 24 12:55:47.814 TRACE shaving_yaks{yaks=3}:shave{yak=1}: fmt::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
+//!   Oct 24 12:55:47.814 TRACE shaving_yaks{yaks=3}:shave{yak=1}: fmt::yak_shave: yak shaved successfully
+//!   Oct 24 12:55:47.814 DEBUG shaving_yaks{yaks=3}: yak_events: yak=1 shaved=true
+//!   Oct 24 12:55:47.814 TRACE shaving_yaks{yaks=3}: fmt::yak_shave: yaks_shaved=1
+//!   Oct 24 12:55:47.815 TRACE shaving_yaks{yaks=3}:shave{yak=2}: fmt::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
+//!   Oct 24 12:55:47.815 TRACE shaving_yaks{yaks=3}:shave{yak=2}: fmt::yak_shave: yak shaved successfully
+//!   Oct 24 12:55:47.815 DEBUG shaving_yaks{yaks=3}: yak_events: yak=2 shaved=true
+//!   Oct 24 12:55:47.815 TRACE shaving_yaks{yaks=3}: fmt::yak_shave: yaks_shaved=2
+//!   Oct 24 12:55:47.815 TRACE shaving_yaks{yaks=3}:shave{yak=3}: fmt::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
+//!   Oct 24 12:55:47.815  WARN shaving_yaks{yaks=3}:shave{yak=3}: fmt::yak_shave: could not locate yak
+//!   Oct 24 12:55:47.815 DEBUG shaving_yaks{yaks=3}: yak_events: yak=3 shaved=false
+//!   Oct 24 12:55:47.815 ERROR shaving_yaks{yaks=3}: fmt::yak_shave: failed to shave yak yak=3 error=missing yak
+//!   Oct 24 12:55:47.815 TRACE shaving_yaks{yaks=3}: fmt::yak_shave: yaks_shaved=2
+//!   Oct 24 12:55:47.815  INFO fmt: yak shaving completed all_yaks_shaved=false
+//!   
+//! +//! * [`format::Pretty`]: Emits excessively pretty, multi-line logs, optimized +//! for human readability. This is primarily intended to be used in local +//! development and debugging, or for command-line applications, where +//! automated analysis and compact storage of logs is less of a priority than +//! readability and visual appeal. +//! +//! For example: +//!
    Finished dev [unoptimized + debuginfo] target(s) in 1.61s
+//!        Running `target/debug/examples/fmt-pretty`
+//!   Oct 24 12:57:29.386 fmt_pretty: preparing to shave yaks, number_of_yaks: 3
+//!     at examples/examples/fmt-pretty.rs:16 on main
+//!
+//!   Oct 24 12:57:29.386 fmt_pretty::yak_shave: shaving yaks
+//!     at examples/examples/fmt/yak_shave.rs:38 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: hello! I'm gonna shave a yak, excitement: "yay!"
+//!     at examples/examples/fmt/yak_shave.rs:14 on main
+//!     in fmt_pretty::yak_shave::shave with yak: 1
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: yak shaved successfully
+//!     at examples/examples/fmt/yak_shave.rs:22 on main
+//!     in fmt_pretty::yak_shave::shave with yak: 1
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 yak_events: yak: 1, shaved: true
+//!     at examples/examples/fmt/yak_shave.rs:43 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: yaks_shaved: 1
+//!     at examples/examples/fmt/yak_shave.rs:52 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: hello! I'm gonna shave a yak, excitement: "yay!"
+//!     at examples/examples/fmt/yak_shave.rs:14 on main
+//!     in fmt_pretty::yak_shave::shave with yak: 2
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: yak shaved successfully
+//!     at examples/examples/fmt/yak_shave.rs:22 on main
+//!     in fmt_pretty::yak_shave::shave with yak: 2
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 yak_events: yak: 2, shaved: true
+//!     at examples/examples/fmt/yak_shave.rs:43 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: yaks_shaved: 2
+//!     at examples/examples/fmt/yak_shave.rs:52 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: hello! I'm gonna shave a yak, excitement: "yay!"
+//!     at examples/examples/fmt/yak_shave.rs:14 on main
+//!     in fmt_pretty::yak_shave::shave with yak: 3
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: could not locate yak
+//!     at examples/examples/fmt/yak_shave.rs:16 on main
+//!     in fmt_pretty::yak_shave::shave with yak: 3
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 yak_events: yak: 3, shaved: false
+//!     at examples/examples/fmt/yak_shave.rs:43 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: failed to shave yak, yak: 3, error: missing yak
+//!     at examples/examples/fmt/yak_shave.rs:48 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty::yak_shave: yaks_shaved: 2
+//!     at examples/examples/fmt/yak_shave.rs:52 on main
+//!     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
+//!
+//!   Oct 24 12:57:29.387 fmt_pretty: yak shaving completed, all_yaks_shaved: false
+//!     at examples/examples/fmt-pretty.rs:19 on main
+//!   
+//! +//! * [`format::Json`]: Outputs newline-delimited JSON logs. This is intended +//! for production use with systems where structured logs are consumed as JSON +//! by analysis and viewing tools. The JSON output, as seen below, is *not* +//! optimized for human readability. +//! +//! For example: +//!
    Finished dev [unoptimized + debuginfo] target(s) in 1.58s
+//!        Running `target/debug/examples/fmt-json`
+//!   {"timestamp":"Oct 24 13:00:00.873","level":"INFO","fields":{"message":"preparing to shave yaks","number_of_yaks":3},"target":"fmt_json"}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"INFO","fields":{"message":"shaving yaks"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"message":"hello! I'm gonna shave a yak","excitement":"yay!"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":"1","name":"shave"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"message":"yak shaved successfully"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":"1","name":"shave"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"DEBUG","fields":{"yak":1,"shaved":true},"target":"yak_events","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"yaks_shaved":1},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"message":"hello! I'm gonna shave a yak","excitement":"yay!"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":"2","name":"shave"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"message":"yak shaved successfully"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":"2","name":"shave"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"DEBUG","fields":{"yak":2,"shaved":true},"target":"yak_events","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"yaks_shaved":2},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.874","level":"TRACE","fields":{"message":"hello! I'm gonna shave a yak","excitement":"yay!"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":"3","name":"shave"}]}
+//!   {"timestamp":"Oct 24 13:00:00.875","level":"WARN","fields":{"message":"could not locate yak"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":"3","name":"shave"}]}
+//!   {"timestamp":"Oct 24 13:00:00.875","level":"DEBUG","fields":{"yak":3,"shaved":false},"target":"yak_events","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.875","level":"ERROR","fields":{"message":"failed to shave yak","yak":3,"error":"missing yak"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.875","level":"TRACE","fields":{"yaks_shaved":2},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
+//!   {"timestamp":"Oct 24 13:00:00.875","level":"INFO","fields":{"message":"yak shaving completed","all_yaks_shaved":false},"target":"fmt_json"}
+//!   
+//! +//! ### Customizing Formatters +//! +//! The formatting of log lines for spans and events is controlled by two +//! traits, [`FormatEvent`] and [`FormatFields`]. The [`FormatEvent`] trait +//! determines the overall formatting of the log line, such as what information +//! from the event's metadata and span context is included and in what order. +//! The [`FormatFields`] trait determines how fields — both the event's +//! fields and fields on spans — are formatted. +//! +//! The [`fmt::format`] module provides several types which implement these traits, +//! many of which expose additional configuration options to customize their +//! output. The [`format::Format`] type implements common configuration used by +//! all the formatters provided in this crate, and can be used as a builder to +//! set specific formatting settings. For example: +//! +//! ``` +//! use tracing_subscriber::fmt; +//! +//! // Configure a custom event formatter +//! let format = fmt::format() +//! .with_level(false) // don't include levels in formatted output +//! .with_target(false) // don't include targets +//! .with_thread_ids(true) // include the thread ID of the current thread +//! .with_thread_names(true) // include the name of the current thread +//! .compact(); // use the `Compact` formatting style. +//! +//! // Create a `fmt` collector that uses our custom event format, and set it +//! // as the default. +//! tracing_subscriber::fmt() +//! .event_format(format) +//! .init(); +//! ``` +//! +//! However, if a specific output format is needed, other crates can +//! also implement [`FormatEvent`] and [`FormatFields`]. See those traits' +//! documentation for details on how to implement them. +//! +//! ## Filters +//! +//! If you want to filter the `tracing` `Events` based on environment +//! variables, you can use the [`EnvFilter`] as follows: +//! +//! ```rust +//! use tracing_subscriber::EnvFilter; +//! +//! let filter = EnvFilter::from_default_env(); +//! ``` +//! +//! As mentioned above, the [`EnvFilter`] allows `Span`s and `Event`s to +//! be filtered at runtime by setting the `RUST_LOG` environment variable. +//! +//! You can find the other available [`filter`]s in the documentation. +//! +//! ### Using Your Subscriber +//! +//! Finally, once you have configured your `Subscriber`, you need to +//! configure your executable to use it. +//! +//! A subscriber can be installed globally using: +//! ```rust +//! use tracing; +//! use tracing_subscriber::FmtSubscriber; +//! +//! let subscriber = FmtSubscriber::new(); +//! +//! tracing::subscriber::set_global_default(subscriber) +//! .map_err(|_err| eprintln!("Unable to set global default subscriber")); +//! // Note this will only fail if you try to set the global default +//! // subscriber multiple times +//! ``` +//! +//! ### Composing Layers +//! +//! Composing an [`EnvFilter`] `Layer` and a [format `Layer`](../fmt/struct.Layer.html): +//! +//! ```rust +//! use tracing_subscriber::{fmt, EnvFilter}; +//! use tracing_subscriber::prelude::*; +//! +//! let fmt_layer = fmt::layer() +//! .with_target(false); +//! let filter_layer = EnvFilter::try_from_default_env() +//! .or_else(|_| EnvFilter::try_new("info")) +//! .unwrap(); +//! +//! tracing_subscriber::registry() +//! .with(filter_layer) +//! .with(fmt_layer) +//! .init(); +//! ``` +//! +//! [`EnvFilter`]: ../filter/struct.EnvFilter.html +//! [`env_logger`]: https://docs.rs/env_logger/ +//! [`filter`]: ../filter/index.html +//! [`SubscriberBuilder`]: ./struct.SubscriberBuilder.html +//! [`FmtSubscriber`]: ./struct.Subscriber.html +//! [`Subscriber`]: +//! https://docs.rs/tracing/latest/tracing/trait.Subscriber.html +//! [`tracing`]: https://crates.io/crates/tracing +//! [`fmt::format`]: mod@crate::fmt::format +use std::{any::TypeId, error::Error, io}; +use tracing_core::{span, subscriber::Interest, Event, Metadata}; + +mod fmt_layer; +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +pub mod format; +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +pub mod time; +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +pub mod writer; + +pub use fmt_layer::{FmtContext, FormattedFields, Layer}; + +use crate::layer::Layer as _; +use crate::{ + filter::LevelFilter, + layer, + registry::{LookupSpan, Registry}, +}; + +#[doc(inline)] +pub use self::{ + format::{format, FormatEvent, FormatFields}, + time::time, + writer::{MakeWriter, TestWriter}, +}; + +/// A `Subscriber` that logs formatted representations of `tracing` events. +/// +/// This consists of an inner `Formatter` wrapped in a layer that performs filtering. +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +#[derive(Debug)] +pub struct Subscriber< + N = format::DefaultFields, + E = format::Format, + F = LevelFilter, + W = fn() -> io::Stdout, +> { + inner: layer::Layered>, +} + +/// A `Subscriber` that logs formatted representations of `tracing` events. +/// This type only logs formatted events; it does not perform any filtering. +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +pub type Formatter< + N = format::DefaultFields, + E = format::Format, + W = fn() -> io::Stdout, +> = layer::Layered, Registry>; + +/// Configures and constructs `Subscriber`s. +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +#[derive(Debug)] +pub struct SubscriberBuilder< + N = format::DefaultFields, + E = format::Format, + F = LevelFilter, + W = fn() -> io::Stdout, +> { + filter: F, + inner: Layer, +} + +/// Returns a new [`SubscriberBuilder`] for configuring a [formatting subscriber]. +/// +/// This is essentially shorthand for [`SubscriberBuilder::default()]`. +/// +/// # Examples +/// +/// Using [`init`] to set the default subscriber: +/// +/// ```rust +/// tracing_subscriber::fmt().init(); +/// ``` +/// +/// Configuring the output format: +/// +/// ```rust +/// +/// tracing_subscriber::fmt() +/// // Configure formatting settings. +/// .with_target(false) +/// .with_timer(tracing_subscriber::fmt::time::uptime()) +/// .with_level(true) +/// // Set the subscriber as the default. +/// .init(); +/// ``` +/// +/// [`try_init`] returns an error if the default subscriber could not be set: +/// +/// ```rust +/// use std::error::Error; +/// +/// fn init_subscriber() -> Result<(), Box> { +/// tracing_subscriber::fmt() +/// // Configure the subscriber to emit logs in JSON format. +/// .json() +/// // Configure the subscriber to flatten event fields in the output JSON objects. +/// .flatten_event(true) +/// // Set the subscriber as the default, returning an error if this fails. +/// .try_init()?; +/// +/// Ok(()) +/// } +/// ``` +/// +/// Rather than setting the subscriber as the default, [`finish`] _returns_ the +/// constructed subscriber, which may then be passed to other functions: +/// +/// ```rust +/// let subscriber = tracing_subscriber::fmt() +/// .with_max_level(tracing::Level::DEBUG) +/// .compact() +/// .finish(); +/// +/// tracing::subscriber::with_default(subscriber, || { +/// // the subscriber will only be set as the default +/// // inside this closure... +/// }) +/// ``` +/// +/// [formatting subscriber]: Subscriber +/// [`SubscriberBuilder::default()`]: SubscriberBuilder::default() +/// [`init`]: SubscriberBuilder::init() +/// [`try_init`]: SubscriberBuilder::try_init() +/// [`finish`]: SubscriberBuilder::finish() +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +pub fn fmt() -> SubscriberBuilder { + SubscriberBuilder::default() +} + +/// Returns a new [formatting layer] that can be [composed] with other layers to +/// construct a [`Subscriber`]. +/// +/// This is a shorthand for the equivalent [`Layer::default`] function. +/// +/// [formatting layer]: Layer +/// [composed]: crate::layer +#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] +pub fn layer() -> Layer { + Layer::default() +} + +impl Subscriber { + /// The maximum [verbosity level] that is enabled by a `Subscriber` by + /// default. + /// + /// This can be overridden with the [`SubscriberBuilder::with_max_level`] method. + /// + /// [verbosity level]: https://docs.rs/tracing-core/0.1.5/tracing_core/struct.Level.html + /// [`SubscriberBuilder::with_max_level`]: struct.SubscriberBuilder.html#method.with_max_level + pub const DEFAULT_MAX_LEVEL: LevelFilter = LevelFilter::INFO; + + /// Returns a new `SubscriberBuilder` for configuring a format subscriber. + pub fn builder() -> SubscriberBuilder { + SubscriberBuilder::default() + } + + /// Returns a new format subscriber with the default configuration. + pub fn new() -> Self { + Default::default() + } +} + +impl Default for Subscriber { + fn default() -> Self { + SubscriberBuilder::default().finish() + } +} + +// === impl Subscriber === + +impl tracing_core::Subscriber for Subscriber +where + N: for<'writer> FormatFields<'writer> + 'static, + E: FormatEvent + 'static, + F: layer::Layer> + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, + layer::Layered>: tracing_core::Subscriber, + fmt_layer::Layer: layer::Layer, +{ + #[inline] + fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest { + self.inner.register_callsite(meta) + } + + #[inline] + fn enabled(&self, meta: &Metadata<'_>) -> bool { + self.inner.enabled(meta) + } + + #[inline] + fn new_span(&self, attrs: &span::Attributes<'_>) -> span::Id { + self.inner.new_span(attrs) + } + + #[inline] + fn record(&self, span: &span::Id, values: &span::Record<'_>) { + self.inner.record(span, values) + } + + #[inline] + fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { + self.inner.record_follows_from(span, follows) + } + + #[inline] + fn event(&self, event: &Event<'_>) { + self.inner.event(event); + } + + #[inline] + fn enter(&self, id: &span::Id) { + // TODO: add on_enter hook + self.inner.enter(id); + } + + #[inline] + fn exit(&self, id: &span::Id) { + self.inner.exit(id); + } + + #[inline] + fn current_span(&self) -> span::Current { + self.inner.current_span() + } + + #[inline] + fn clone_span(&self, id: &span::Id) -> span::Id { + self.inner.clone_span(id) + } + + #[inline] + fn try_close(&self, id: span::Id) -> bool { + self.inner.try_close(id) + } + + #[inline] + fn max_level_hint(&self) -> Option { + self.inner.max_level_hint() + } + + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + if id == TypeId::of::() { + Some(self as *const Self as *const ()) + } else { + self.inner.downcast_raw(id) + } + } +} + +impl<'a, N, E, F, W> LookupSpan<'a> for Subscriber +where + layer::Layered>: LookupSpan<'a>, +{ + type Data = > as LookupSpan<'a>>::Data; + + fn span_data(&'a self, id: &span::Id) -> Option { + self.inner.span_data(id) + } +} + +// ===== impl SubscriberBuilder ===== + +impl Default for SubscriberBuilder { + fn default() -> Self { + SubscriberBuilder { + filter: Subscriber::DEFAULT_MAX_LEVEL, + inner: Default::default(), + } + } +} + +impl SubscriberBuilder +where + N: for<'writer> FormatFields<'writer> + 'static, + E: FormatEvent + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, + F: layer::Layer> + Send + Sync + 'static, + fmt_layer::Layer: layer::Layer + Send + Sync + 'static, +{ + /// Finish the builder, returning a new `FmtSubscriber`. + pub fn finish(self) -> Subscriber { + let subscriber = self.inner.with_subscriber(Registry::default()); + Subscriber { + inner: self.filter.with_subscriber(subscriber), + } + } + + /// Install this Subscriber as the global default if one is + /// not already set. + /// + /// If the `tracing-log` feature is enabled, this will also install + /// the LogTracer to convert `Log` records into `tracing` `Event`s. + /// + /// # Errors + /// Returns an Error if the initialization was unsuccessful, likely + /// because a global subscriber was already installed by another + /// call to `try_init`. + pub fn try_init(self) -> Result<(), Box> { + use crate::util::SubscriberInitExt; + self.finish().try_init()?; + + Ok(()) + } + + /// Install this Subscriber as the global default. + /// + /// If the `tracing-log` feature is enabled, this will also install + /// the LogTracer to convert `Log` records into `tracing` `Event`s. + /// + /// # Panics + /// Panics if the initialization was unsuccessful, likely because a + /// global subscriber was already installed by another call to `try_init`. + pub fn init(self) { + self.try_init() + .expect("Unable to install global subscriber") + } +} + +impl From> for tracing_core::Dispatch +where + N: for<'writer> FormatFields<'writer> + 'static, + E: FormatEvent + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, + F: layer::Layer> + Send + Sync + 'static, + fmt_layer::Layer: layer::Layer + Send + Sync + 'static, +{ + fn from(builder: SubscriberBuilder) -> tracing_core::Dispatch { + tracing_core::Dispatch::new(builder.finish()) + } +} + +impl SubscriberBuilder, F, W> +where + N: for<'writer> FormatFields<'writer> + 'static, +{ + /// Use the given [`timer`] for log message timestamps. + /// + /// See the [`time` module] for the provided timer implementations. + /// + /// Note that using the `"time`"" feature flag enables the + /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the + /// [`time` crate] to provide more sophisticated timestamp formatting + /// options. + /// + /// [`timer`]: time::FormatTime + /// [`time` module]: mod@time + /// [`UtcTime`]: time::UtcTime + /// [`LocalTime`]: time::LocalTime + /// [`time` crate]: https://docs.rs/time/0.3 + pub fn with_timer(self, timer: T2) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.with_timer(timer), + } + } + + /// Do not emit timestamps with log messages. + pub fn without_time(self) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.without_time(), + } + } + + /// Configures how synthesized events are emitted at points in the [span + /// lifecycle][lifecycle]. + /// + /// The following options are available: + /// + /// - `FmtSpan::NONE`: No events will be synthesized when spans are + /// created, entered, exited, or closed. Data from spans will still be + /// included as the context for formatted events. This is the default. + /// - `FmtSpan::NEW`: An event will be synthesized when spans are created. + /// - `FmtSpan::ENTER`: An event will be synthesized when spans are entered. + /// - `FmtSpan::EXIT`: An event will be synthesized when spans are exited. + /// - `FmtSpan::CLOSE`: An event will be synthesized when a span closes. If + /// [timestamps are enabled][time] for this formatter, the generated + /// event will contain fields with the span's _busy time_ (the total + /// time for which it was entered) and _idle time_ (the total time that + /// the span existed but was not entered). + /// - `FmtSpan::ACTIVE`: An event will be synthesized when spans are entered + /// or exited. + /// - `FmtSpan::FULL`: Events will be synthesized whenever a span is + /// created, entered, exited, or closed. If timestamps are enabled, the + /// close event will contain the span's busy and idle time, as + /// described above. + /// + /// The options can be enabled in any combination. For instance, the following + /// will synthesize events whenever spans are created and closed: + /// + /// ```rust + /// use tracing_subscriber::fmt::format::FmtSpan; + /// use tracing_subscriber::fmt; + /// + /// let subscriber = fmt() + /// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) + /// .finish(); + /// ``` + /// + /// Note that the generated events will only be part of the log output by + /// this formatter; they will not be recorded by other `Subscriber`s or by + /// `Layer`s added to this subscriber. + /// + /// [lifecycle]: https://docs.rs/tracing/latest/tracing/span/index.html#the-span-lifecycle + /// [time]: #method.without_time + pub fn with_span_events(self, kind: format::FmtSpan) -> Self { + SubscriberBuilder { + inner: self.inner.with_span_events(kind), + ..self + } + } + + /// Enable ANSI encoding for formatted events. + #[cfg(feature = "ansi")] + #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + pub fn with_ansi(self, ansi: bool) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + inner: self.inner.with_ansi(ansi), + ..self + } + } + + /// Sets whether or not an event's target is displayed. + pub fn with_target( + self, + display_target: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + inner: self.inner.with_target(display_target), + ..self + } + } + + /// Sets whether or not an event's level is displayed. + pub fn with_level( + self, + display_level: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + inner: self.inner.with_level(display_level), + ..self + } + } + + /// Sets whether or not the [name] of the current thread is displayed + /// when formatting events + /// + /// [name]: https://doc.rust-lang.org/stable/std/thread/index.html#naming-threads + pub fn with_thread_names( + self, + display_thread_names: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + inner: self.inner.with_thread_names(display_thread_names), + ..self + } + } + + /// Sets whether or not the [thread ID] of the current thread is displayed + /// when formatting events + /// + /// [thread ID]: https://doc.rust-lang.org/stable/std/thread/struct.ThreadId.html + pub fn with_thread_ids( + self, + display_thread_ids: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + inner: self.inner.with_thread_ids(display_thread_ids), + ..self + } + } + + /// Sets the subscriber being built to use a less verbose formatter. + /// + /// See [`format::Compact`]. + pub fn compact(self) -> SubscriberBuilder, F, W> + where + N: for<'writer> FormatFields<'writer> + 'static, + { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.compact(), + } + } + + /// Sets the subscriber being built to use an [excessively pretty, human-readable formatter](crate::fmt::format::Pretty). + #[cfg(feature = "ansi")] + #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] + pub fn pretty( + self, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.pretty(), + } + } + + /// Sets the subscriber being built to use a JSON formatter. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + pub fn json( + self, + ) -> SubscriberBuilder, F, W> + where + N: for<'writer> FormatFields<'writer> + 'static, + { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.json(), + } + } +} + +#[cfg(feature = "json")] +#[cfg_attr(docsrs, doc(cfg(feature = "json")))] +impl SubscriberBuilder, F, W> { + /// Sets the json subscriber being built to flatten event metadata. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + pub fn flatten_event( + self, + flatten_event: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.flatten_event(flatten_event), + } + } + + /// Sets whether or not the JSON subscriber being built will include the current span + /// in formatted events. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + pub fn with_current_span( + self, + display_current_span: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.with_current_span(display_current_span), + } + } + + /// Sets whether or not the JSON subscriber being built will include a list (from + /// root to leaf) of all currently entered spans in formatted events. + /// + /// See [`format::Json`](../fmt/format/struct.Json.html) + pub fn with_span_list( + self, + display_span_list: bool, + ) -> SubscriberBuilder, F, W> { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.with_span_list(display_span_list), + } + } +} + +#[cfg(feature = "env-filter")] +#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] +impl SubscriberBuilder +where + Formatter: tracing_core::Subscriber + 'static, +{ + /// Configures the subscriber being built to allow filter reloading at + /// runtime. + pub fn with_filter_reloading( + self, + ) -> SubscriberBuilder>, W> + { + let (filter, _) = crate::reload::Layer::new(self.filter); + SubscriberBuilder { + filter, + inner: self.inner, + } + } +} + +#[cfg(feature = "env-filter")] +#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] +impl SubscriberBuilder>, W> +where + Formatter: tracing_core::Subscriber + 'static, +{ + /// Returns a `Handle` that may be used to reload the constructed subscriber's + /// filter. + pub fn reload_handle(&self) -> crate::reload::Handle> { + self.filter.handle() + } +} + +impl SubscriberBuilder { + /// Sets the Visitor that the subscriber being built will use to record + /// fields. + /// + /// For example: + /// ```rust + /// use tracing_subscriber::fmt::format; + /// use tracing_subscriber::prelude::*; + /// + /// let formatter = + /// // Construct a custom formatter for `Debug` fields + /// format::debug_fn(|writer, field, value| write!(writer, "{}: {:?}", field, value)) + /// // Use the `tracing_subscriber::MakeFmtExt` trait to wrap the + /// // formatter so that a delimiter is added between fields. + /// .delimited(", "); + /// + /// let subscriber = tracing_subscriber::fmt() + /// .fmt_fields(formatter) + /// .finish(); + /// # drop(subscriber) + /// ``` + pub fn fmt_fields(self, fmt_fields: N2) -> SubscriberBuilder + where + N2: for<'writer> FormatFields<'writer> + 'static, + { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.fmt_fields(fmt_fields), + } + } + + /// Sets the [`EnvFilter`] that the subscriber will use to determine if + /// a span or event is enabled. + /// + /// Note that this method requires the "env-filter" feature flag to be enabled. + /// + /// If a filter was previously set, or a maximum level was set by the + /// [`with_max_level`] method, that value is replaced by the new filter. + /// + /// # Examples + /// + /// Setting a filter based on the value of the `RUST_LOG` environment + /// variable: + /// ```rust + /// use tracing_subscriber::{fmt, EnvFilter}; + /// + /// fmt() + /// .with_env_filter(EnvFilter::from_default_env()) + /// .init(); + /// ``` + /// + /// Setting a filter based on a pre-set filter directive string: + /// ```rust + /// use tracing_subscriber::fmt; + /// + /// fmt() + /// .with_env_filter("my_crate=info,my_crate::my_mod=debug,[my_span]=trace") + /// .init(); + /// ``` + /// + /// Adding additional directives to a filter constructed from an env var: + /// ```rust + /// use tracing_subscriber::{fmt, filter::{EnvFilter, LevelFilter}}; + /// + /// # fn filter() -> Result<(), Box> { + /// let filter = EnvFilter::try_from_env("MY_CUSTOM_FILTER_ENV_VAR")? + /// // Set the base level when not matched by other directives to WARN. + /// .add_directive(LevelFilter::WARN.into()) + /// // Set the max level for `my_crate::my_mod` to DEBUG, overriding + /// // any directives parsed from the env variable. + /// .add_directive("my_crate::my_mod=debug".parse()?); + /// + /// fmt() + /// .with_env_filter(filter) + /// .try_init()?; + /// # Ok(())} + /// ``` + /// [`EnvFilter`]: ../filter/struct.EnvFilter.html + /// [`with_max_level`]: #method.with_max_level + #[cfg(feature = "env-filter")] + #[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] + pub fn with_env_filter( + self, + filter: impl Into, + ) -> SubscriberBuilder + where + Formatter: tracing_core::Subscriber + 'static, + { + let filter = filter.into(); + SubscriberBuilder { + filter, + inner: self.inner, + } + } + + /// Sets the maximum [verbosity level] that will be enabled by the + /// subscriber. + /// + /// If the max level has already been set, or a [`EnvFilter`] was added by + /// [`with_filter`], this replaces that configuration with the new + /// maximum level. + /// + /// # Examples + /// + /// Enable up to the `DEBUG` verbosity level: + /// ```rust + /// use tracing_subscriber::fmt; + /// use tracing::Level; + /// + /// fmt() + /// .with_max_level(Level::DEBUG) + /// .init(); + /// ``` + /// This subscriber won't record any spans or events! + /// ```rust + /// use tracing_subscriber::{fmt, filter::LevelFilter}; + /// + /// let subscriber = fmt() + /// .with_max_level(LevelFilter::OFF) + /// .finish(); + /// ``` + /// [verbosity level]: https://docs.rs/tracing-core/0.1.5/tracing_core/struct.Level.html + /// [`EnvFilter`]: ../filter/struct.EnvFilter.html + /// [`with_filter`]: #method.with_filter + pub fn with_max_level( + self, + filter: impl Into, + ) -> SubscriberBuilder { + let filter = filter.into(); + SubscriberBuilder { + filter, + inner: self.inner, + } + } + + /// Sets the function that the subscriber being built should use to format + /// events that occur. + pub fn event_format(self, fmt_event: E2) -> SubscriberBuilder + where + E2: FormatEvent + 'static, + N: for<'writer> FormatFields<'writer> + 'static, + W: for<'writer> MakeWriter<'writer> + 'static, + { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.event_format(fmt_event), + } + } + + /// Sets the [`MakeWriter`] that the subscriber being built will use to write events. + /// + /// # Examples + /// + /// Using `stderr` rather than `stdout`: + /// + /// ```rust + /// use tracing_subscriber::fmt; + /// use std::io; + /// + /// fmt() + /// .with_writer(io::stderr) + /// .init(); + /// ``` + /// + /// [`MakeWriter`]: trait.MakeWriter.html + pub fn with_writer(self, make_writer: W2) -> SubscriberBuilder + where + W2: for<'writer> MakeWriter<'writer> + 'static, + { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.with_writer(make_writer), + } + } + + /// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in + /// unit tests. + /// + /// See [`TestWriter`] for additional details. + /// + /// # Examples + /// + /// Using [`TestWriter`] to let `cargo test` capture test output. Note that we do not install it + /// globally as it may cause conflicts. + /// + /// ```rust + /// use tracing_subscriber::fmt; + /// use tracing::subscriber; + /// + /// subscriber::set_default( + /// fmt() + /// .with_test_writer() + /// .finish() + /// ); + /// ``` + /// + /// [capturing]: + /// https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output + /// [`TestWriter`]: writer/struct.TestWriter.html + pub fn with_test_writer(self) -> SubscriberBuilder { + SubscriberBuilder { + filter: self.filter, + inner: self.inner.with_writer(TestWriter::default()), + } + } +} + +/// Install a global tracing subscriber that listens for events and +/// filters based on the value of the [`RUST_LOG` environment variable], +/// if one is not already set. +/// +/// If the `tracing-log` feature is enabled, this will also install +/// the [`LogTracer`] to convert `log` records into `tracing` `Event`s. +/// +/// This is shorthand for +/// +/// ```rust +/// # fn doc() -> Result<(), Box> { +/// tracing_subscriber::fmt().try_init() +/// # } +/// ``` +/// +/// +/// # Errors +/// +/// Returns an Error if the initialization was unsuccessful, +/// likely because a global subscriber was already installed by another +/// call to `try_init`. +/// +/// [`LogTracer`]: +/// https://docs.rs/tracing-log/0.1.0/tracing_log/struct.LogTracer.html +/// [`RUST_LOG` environment variable]: +/// ../filter/struct.EnvFilter.html#associatedconstant.DEFAULT_ENV +pub fn try_init() -> Result<(), Box> { + let builder = Subscriber::builder(); + + #[cfg(feature = "env-filter")] + let builder = builder.with_env_filter(crate::EnvFilter::from_default_env()); + + builder.try_init() +} + +/// Install a global tracing subscriber that listens for events and +/// filters based on the value of the [`RUST_LOG` environment variable]. +/// +/// If the `tracing-log` feature is enabled, this will also install +/// the LogTracer to convert `Log` records into `tracing` `Event`s. +/// +/// This is shorthand for +/// +/// ```rust +/// tracing_subscriber::fmt().init() +/// ``` +/// +/// # Panics +/// Panics if the initialization was unsuccessful, likely because a +/// global subscriber was already installed by another call to `try_init`. +/// +/// [`RUST_LOG` environment variable]: +/// ../filter/struct.EnvFilter.html#associatedconstant.DEFAULT_ENV +pub fn init() { + try_init().expect("Unable to install global subscriber") +} + +#[cfg(test)] +mod test { + use crate::{ + filter::LevelFilter, + fmt::{ + format::{self, Format}, + time, + writer::MakeWriter, + Subscriber, + }, + }; + use std::{ + io, + sync::{Arc, Mutex, MutexGuard, TryLockError}, + }; + use tracing_core::dispatcher::Dispatch; + + pub(crate) struct MockWriter { + buf: Arc>>, + } + + impl MockWriter { + pub(crate) fn new(buf: Arc>>) -> Self { + Self { buf } + } + + pub(crate) fn map_error(err: TryLockError) -> io::Error { + match err { + TryLockError::WouldBlock => io::Error::from(io::ErrorKind::WouldBlock), + TryLockError::Poisoned(_) => io::Error::from(io::ErrorKind::Other), + } + } + + pub(crate) fn buf(&self) -> io::Result>> { + self.buf.try_lock().map_err(Self::map_error) + } + } + + impl io::Write for MockWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.buf()?.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.buf()?.flush() + } + } + + #[derive(Clone, Default)] + pub(crate) struct MockMakeWriter { + buf: Arc>>, + } + + impl MockMakeWriter { + pub(crate) fn new(buf: Arc>>) -> Self { + Self { buf } + } + + #[cfg(feature = "json")] + pub(crate) fn buf(&self) -> MutexGuard<'_, Vec> { + self.buf.lock().unwrap() + } + + pub(crate) fn get_string(&self) -> String { + let mut buf = self.buf.lock().expect("lock shouldn't be poisoned"); + let string = std::str::from_utf8(&buf[..]) + .expect("formatter should not have produced invalid utf-8") + .to_owned(); + buf.clear(); + string + } + } + + impl<'a> MakeWriter<'a> for MockMakeWriter { + type Writer = MockWriter; + + fn make_writer(&'a self) -> Self::Writer { + MockWriter::new(self.buf.clone()) + } + } + + #[test] + fn impls() { + let f = Format::default().with_timer(time::Uptime::default()); + let subscriber = Subscriber::builder().event_format(f).finish(); + let _dispatch = Dispatch::new(subscriber); + + let f = format::Format::default(); + let subscriber = Subscriber::builder().event_format(f).finish(); + let _dispatch = Dispatch::new(subscriber); + + let f = format::Format::default().compact(); + let subscriber = Subscriber::builder().event_format(f).finish(); + let _dispatch = Dispatch::new(subscriber); + } + + #[test] + fn subscriber_downcasts() { + let subscriber = Subscriber::builder().finish(); + let dispatch = Dispatch::new(subscriber); + assert!(dispatch.downcast_ref::().is_some()); + } + + #[test] + fn subscriber_downcasts_to_parts() { + let subscriber = Subscriber::new(); + let dispatch = Dispatch::new(subscriber); + assert!(dispatch.downcast_ref::().is_some()); + assert!(dispatch.downcast_ref::().is_some()); + assert!(dispatch.downcast_ref::().is_some()) + } + + #[test] + fn is_lookup_span() { + fn assert_lookup_span crate::registry::LookupSpan<'a>>(_: T) {} + let subscriber = Subscriber::new(); + assert_lookup_span(subscriber) + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/time/datetime.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/time/datetime.rs new file mode 100644 index 000000000..531331687 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/time/datetime.rs @@ -0,0 +1,410 @@ +// musl as a whole is licensed under the following standard MIT license: +// +// ---------------------------------------------------------------------- +// Copyright © 2005-2020 Rich Felker, et al. +// +// 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. +// ---------------------------------------------------------------------- +// +// Authors/contributors include: +// +// A. Wilcox +// Ada Worcester +// Alex Dowad +// Alex Suykov +// Alexander Monakov +// Andre McCurdy +// Andrew Kelley +// Anthony G. Basile +// Aric Belsito +// Arvid Picciani +// Bartosz Brachaczek +// Benjamin Peterson +// Bobby Bingham +// Boris Brezillon +// Brent Cook +// Chris Spiegel +// Clément Vasseur +// Daniel Micay +// Daniel Sabogal +// Daurnimator +// David Carlier +// David Edelsohn +// Denys Vlasenko +// Dmitry Ivanov +// Dmitry V. Levin +// Drew DeVault +// Emil Renner Berthing +// Fangrui Song +// Felix Fietkau +// Felix Janda +// Gianluca Anzolin +// Hauke Mehrtens +// He X +// Hiltjo Posthuma +// Isaac Dunham +// Jaydeep Patil +// Jens Gustedt +// Jeremy Huntwork +// Jo-Philipp Wich +// Joakim Sindholt +// John Spencer +// Julien Ramseier +// Justin Cormack +// Kaarle Ritvanen +// Khem Raj +// Kylie McClain +// Leah Neukirchen +// Luca Barbato +// Luka Perkov +// M Farkas-Dyck (Strake) +// Mahesh Bodapati +// Markus Wichmann +// Masanori Ogino +// Michael Clark +// Michael Forney +// Mikhail Kremnyov +// Natanael Copa +// Nicholas J. Kain +// orc +// Pascal Cuoq +// Patrick Oppenlander +// Petr Hosek +// Petr Skocik +// Pierre Carrier +// Reini Urban +// Rich Felker +// Richard Pennington +// Ryan Fairfax +// Samuel Holland +// Segev Finer +// Shiz +// sin +// Solar Designer +// Stefan Kristiansson +// Stefan O'Rear +// Szabolcs Nagy +// Timo Teräs +// Trutz Behn +// Valentin Ochs +// Will Dietz +// William Haddon +// William Pitcock +// +// Portions of this software are derived from third-party works licensed +// under terms compatible with the above MIT license: +// +// The TRE regular expression implementation (src/regex/reg* and +// src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed +// under a 2-clause BSD license (license text in the source files). The +// included version has been heavily modified by Rich Felker in 2012, in +// the interests of size, simplicity, and namespace cleanliness. +// +// Much of the math library code (src/math/* and src/complex/*) is +// Copyright © 1993,2004 Sun Microsystems or +// Copyright © 2003-2011 David Schultz or +// Copyright © 2003-2009 Steven G. Kargl or +// Copyright © 2003-2009 Bruce D. Evans or +// Copyright © 2008 Stephen L. Moshier or +// Copyright © 2017-2018 Arm Limited +// and labelled as such in comments in the individual source files. All +// have been licensed under extremely permissive terms. +// +// The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008 +// The Android Open Source Project and is licensed under a two-clause BSD +// license. It was taken from Bionic libc, used on Android. +// +// The AArch64 memcpy and memset code (src/string/aarch64/*) are +// Copyright © 1999-2019, Arm Limited. +// +// The implementation of DES for crypt (src/crypt/crypt_des.c) is +// Copyright © 1994 David Burren. It is licensed under a BSD license. +// +// The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was +// originally written by Solar Designer and placed into the public +// domain. The code also comes with a fallback permissive license for use +// in jurisdictions that may not recognize the public domain. +// +// The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 +// Valentin Ochs and is licensed under an MIT-style license. +// +// The x86_64 port was written by Nicholas J. Kain and is licensed under +// the standard MIT terms. +// +// The mips and microblaze ports were originally written by Richard +// Pennington for use in the ellcc project. The original code was adapted +// by Rich Felker for build system and code conventions during upstream +// integration. It is licensed under the standard MIT terms. +// +// The mips64 port was contributed by Imagination Technologies and is +// licensed under the standard MIT terms. +// +// The powerpc port was also originally written by Richard Pennington, +// and later supplemented and integrated by John Spencer. It is licensed +// under the standard MIT terms. +// +// All other files which have no copyright comments are original works +// produced specifically for use as part of this library, written either +// by Rich Felker, the main author of the library, or by one or more +// contibutors listed above. Details on authorship of individual files +// can be found in the git version control history of the project. The +// omission of copyright and license comments in each file is in the +// interest of source tree size. +// +// In addition, permission is hereby granted for all public header files +// (include/* and arch/*/bits/*) and crt files intended to be linked into +// applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit +// the copyright notice and permission notice otherwise required by the +// license, and to use these files without any requirement of +// attribution. These files include substantial contributions from: +// +// Bobby Bingham +// John Spencer +// Nicholas J. Kain +// Rich Felker +// Richard Pennington +// Stefan Kristiansson +// Szabolcs Nagy +// +// all of whom have explicitly granted such permission. +// +// This file previously contained text expressing a belief that most of +// the files covered by the above exception were sufficiently trivial not +// to be subject to copyright, resulting in confusion over whether it +// negated the permissions granted in the license. In the spirit of +// permissive licensing, and of not having licensing issues being an +// obstacle to adoption, that text has been removed. + + +use std::fmt; + +/// A date/time type which exists primarily to convert `SystemTime` timestamps into an ISO 8601 +/// formatted string. +/// +/// Yes, this exists. Before you have a heart attack, understand that the meat of this is musl's +/// [`__secs_to_tm`][1] converted to Rust via [c2rust][2] and then cleaned up by hand as part of +/// the [kudu-rs project][3], [released under MIT][4]. +/// +/// [1] http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c +/// [2] https://c2rust.com/ +/// [3] https://github.com/danburkert/kudu-rs/blob/c9660067e5f4c1a54143f169b5eeb49446f82e54/src/timestamp.rs#L5-L18 +/// [4] https://github.com/tokio-rs/tracing/issues/1644#issuecomment-963888244 +/// +/// All existing `strftime`-like APIs I found were unable to handle the full range of timestamps representable +/// by `SystemTime`, including `strftime` itself, since tm.tm_year is an int. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct DateTime { + year: i64, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + nanos: u32, +} + +impl fmt::Display for DateTime { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.year > 9999 { + write!(f, "+{}", self.year)?; + } else if self.year < 0 { + write!(f, "{:05}", self.year)?; + } else { + write!(f, "{:04}", self.year)?; + } + + write!( + f, + "-{:02}-{:02}T{:02}:{:02}:{:02}.{:06}Z", + self.month, + self.day, + self.hour, + self.minute, + self.second, + self.nanos / 1_000 + ) + } +} + +impl From for DateTime { + fn from(timestamp: std::time::SystemTime) -> DateTime { + let (t, nanos) = match timestamp.duration_since(std::time::UNIX_EPOCH) { + Ok(duration) => { + debug_assert!(duration.as_secs() <= std::i64::MAX as u64); + (duration.as_secs() as i64, duration.subsec_nanos()) + } + Err(error) => { + let duration = error.duration(); + debug_assert!(duration.as_secs() <= std::i64::MAX as u64); + let (secs, nanos) = (duration.as_secs() as i64, duration.subsec_nanos()); + if nanos == 0 { + (-secs, 0) + } else { + (-secs - 1, 1_000_000_000 - nanos) + } + } + }; + + // 2000-03-01 (mod 400 year, immediately after feb29 + const LEAPOCH: i64 = 946_684_800 + 86400 * (31 + 29); + const DAYS_PER_400Y: i32 = 365 * 400 + 97; + const DAYS_PER_100Y: i32 = 365 * 100 + 24; + const DAYS_PER_4Y: i32 = 365 * 4 + 1; + static DAYS_IN_MONTH: [i8; 12] = [31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29]; + + // Note(dcb): this bit is rearranged slightly to avoid integer overflow. + let mut days: i64 = (t / 86_400) - (LEAPOCH / 86_400); + let mut remsecs: i32 = (t % 86_400) as i32; + if remsecs < 0i32 { + remsecs += 86_400; + days -= 1 + } + + let mut qc_cycles: i32 = (days / i64::from(DAYS_PER_400Y)) as i32; + let mut remdays: i32 = (days % i64::from(DAYS_PER_400Y)) as i32; + if remdays < 0 { + remdays += DAYS_PER_400Y; + qc_cycles -= 1; + } + + let mut c_cycles: i32 = remdays / DAYS_PER_100Y; + if c_cycles == 4 { + c_cycles -= 1; + } + remdays -= c_cycles * DAYS_PER_100Y; + + let mut q_cycles: i32 = remdays / DAYS_PER_4Y; + if q_cycles == 25 { + q_cycles -= 1; + } + remdays -= q_cycles * DAYS_PER_4Y; + + let mut remyears: i32 = remdays / 365; + if remyears == 4 { + remyears -= 1; + } + remdays -= remyears * 365; + + let mut years: i64 = i64::from(remyears) + + 4 * i64::from(q_cycles) + + 100 * i64::from(c_cycles) + + 400 * i64::from(qc_cycles); + + let mut months: i32 = 0; + while i32::from(DAYS_IN_MONTH[months as usize]) <= remdays { + remdays -= i32::from(DAYS_IN_MONTH[months as usize]); + months += 1 + } + + if months >= 10 { + months -= 12; + years += 1; + } + + DateTime { + year: years + 2000, + month: (months + 3) as u8, + day: (remdays + 1) as u8, + hour: (remsecs / 3600) as u8, + minute: (remsecs / 60 % 60) as u8, + second: (remsecs % 60) as u8, + nanos, + } + } +} + +#[cfg(test)] +mod tests { + use std::i32; + use std::time::{Duration, UNIX_EPOCH}; + + use super::*; + + #[test] + fn test_datetime() { + let case = |expected: &str, secs: i64, micros: u32| { + let timestamp = if secs >= 0 { + UNIX_EPOCH + Duration::new(secs as u64, micros * 1_000) + } else { + (UNIX_EPOCH - Duration::new(!secs as u64 + 1, 0)) + Duration::new(0, micros * 1_000) + }; + assert_eq!( + expected, + format!("{}", DateTime::from(timestamp)), + "secs: {}, micros: {}", + secs, + micros + ) + }; + + // Mostly generated with: + // - date -jur +"%Y-%m-%dT%H:%M:%S.000000Z" + // - http://unixtimestamp.50x.eu/ + + case("1970-01-01T00:00:00.000000Z", 0, 0); + + case("1970-01-01T00:00:00.000001Z", 0, 1); + case("1970-01-01T00:00:00.500000Z", 0, 500_000); + case("1970-01-01T00:00:01.000001Z", 1, 1); + case("1970-01-01T00:01:01.000001Z", 60 + 1, 1); + case("1970-01-01T01:01:01.000001Z", 60 * 60 + 60 + 1, 1); + case( + "1970-01-02T01:01:01.000001Z", + 24 * 60 * 60 + 60 * 60 + 60 + 1, + 1, + ); + + case("1969-12-31T23:59:59.000000Z", -1, 0); + case("1969-12-31T23:59:59.000001Z", -1, 1); + case("1969-12-31T23:59:59.500000Z", -1, 500_000); + case("1969-12-31T23:58:59.000001Z", -60 - 1, 1); + case("1969-12-31T22:58:59.000001Z", -60 * 60 - 60 - 1, 1); + case( + "1969-12-30T22:58:59.000001Z", + -24 * 60 * 60 - 60 * 60 - 60 - 1, + 1, + ); + + case("2038-01-19T03:14:07.000000Z", std::i32::MAX as i64, 0); + case("2038-01-19T03:14:08.000000Z", std::i32::MAX as i64 + 1, 0); + case("1901-12-13T20:45:52.000000Z", i32::MIN as i64, 0); + case("1901-12-13T20:45:51.000000Z", i32::MIN as i64 - 1, 0); + + // Skipping these tests on windows as std::time::SysteTime range is low + // on Windows compared with that of Unix which can cause the following + // high date value tests to panic + #[cfg(not(target_os = "windows"))] + { + case("+292277026596-12-04T15:30:07.000000Z", std::i64::MAX, 0); + case("+292277026596-12-04T15:30:06.000000Z", std::i64::MAX - 1, 0); + case("-292277022657-01-27T08:29:53.000000Z", i64::MIN + 1, 0); + } + + case("1900-01-01T00:00:00.000000Z", -2208988800, 0); + case("1899-12-31T23:59:59.000000Z", -2208988801, 0); + case("0000-01-01T00:00:00.000000Z", -62167219200, 0); + case("-0001-12-31T23:59:59.000000Z", -62167219201, 0); + + case("1234-05-06T07:08:09.000000Z", -23215049511, 0); + case("-1234-05-06T07:08:09.000000Z", -101097651111, 0); + case("2345-06-07T08:09:01.000000Z", 11847456541, 0); + case("-2345-06-07T08:09:01.000000Z", -136154620259, 0); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/time/mod.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/time/mod.rs new file mode 100644 index 000000000..621df16e4 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/time/mod.rs @@ -0,0 +1,134 @@ +//! Formatters for event timestamps. +use crate::fmt::format::Writer; +use std::fmt; +use std::time::Instant; + +mod datetime; + +#[cfg(feature = "time")] +mod time_crate; +#[cfg(feature = "time")] +#[cfg_attr(docsrs, doc(cfg(feature = "time")))] +pub use time_crate::UtcTime; + +#[cfg(feature = "local-time")] +#[cfg_attr(docsrs, doc(cfg(feature = "local-time")))] +pub use time_crate::LocalTime; + +/// A type that can measure and format the current time. +/// +/// This trait is used by `Format` to include a timestamp with each `Event` when it is logged. +/// +/// Notable default implementations of this trait are `SystemTime` and `()`. The former prints the +/// current time as reported by `std::time::SystemTime`, and the latter does not print the current +/// time at all. `FormatTime` is also automatically implemented for any function pointer with the +/// appropriate signature. +/// +/// The full list of provided implementations can be found in [`time`]. +/// +/// [`time`]: ./index.html +pub trait FormatTime { + /// Measure and write out the current time. + /// + /// When `format_time` is called, implementors should get the current time using their desired + /// mechanism, and write it out to the given `fmt::Write`. Implementors must insert a trailing + /// space themselves if they wish to separate the time from subsequent log message text. + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result; +} + +/// Returns a new `SystemTime` timestamp provider. +/// +/// This can then be configured further to determine how timestamps should be +/// configured. +/// +/// This is equivalent to calling +/// ```rust +/// # fn timer() -> tracing_subscriber::fmt::time::SystemTime { +/// tracing_subscriber::fmt::time::SystemTime::default() +/// # } +/// ``` +pub fn time() -> SystemTime { + SystemTime::default() +} + +/// Returns a new `Uptime` timestamp provider. +/// +/// With this timer, timestamps will be formatted with the amount of time +/// elapsed since the timestamp provider was constructed. +/// +/// This can then be configured further to determine how timestamps should be +/// configured. +/// +/// This is equivalent to calling +/// ```rust +/// # fn timer() -> tracing_subscriber::fmt::time::Uptime { +/// tracing_subscriber::fmt::time::Uptime::default() +/// # } +/// ``` +pub fn uptime() -> Uptime { + Uptime::default() +} + +impl<'a, F> FormatTime for &'a F +where + F: FormatTime, +{ + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + (*self).format_time(w) + } +} + +impl FormatTime for () { + fn format_time(&self, _: &mut Writer<'_>) -> fmt::Result { + Ok(()) + } +} + +impl FormatTime for fn(&mut Writer<'_>) -> fmt::Result { + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + (*self)(w) + } +} + +/// Retrieve and print the current wall-clock time. +#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] +pub struct SystemTime; + +/// Retrieve and print the relative elapsed wall-clock time since an epoch. +/// +/// The `Default` implementation for `Uptime` makes the epoch the current time. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub struct Uptime { + epoch: Instant, +} + +impl Default for Uptime { + fn default() -> Self { + Uptime { + epoch: Instant::now(), + } + } +} + +impl From for Uptime { + fn from(epoch: Instant) -> Self { + Uptime { epoch } + } +} + +impl FormatTime for SystemTime { + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + write!( + w, + "{}", + datetime::DateTime::from(std::time::SystemTime::now()) + ) + } +} + +impl FormatTime for Uptime { + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + let e = self.epoch.elapsed(); + write!(w, "{:4}.{:09}s", e.as_secs(), e.subsec_nanos()) + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/time/time_crate.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/time/time_crate.rs new file mode 100644 index 000000000..64d274365 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/time/time_crate.rs @@ -0,0 +1,276 @@ +use crate::fmt::{format::Writer, time::FormatTime, writer::WriteAdaptor}; +use std::fmt; +use time::{format_description::well_known, formatting::Formattable, OffsetDateTime}; + +/// Formats the current [local time] using a [formatter] from the [`time` crate]. +/// +/// To format the current [UTC time] instead, use the [`UtcTime`] type. +/// +/// [local time]: https://docs.rs/time/0.3/time/struct.OffsetDateTime.html#method.now_local +/// [UTC time]: https://docs.rs/time/0.3/time/struct.OffsetDateTime.html#method.now_utc +/// [formatter]: https://docs.rs/time/0.3/time/formatting/trait.Formattable.html +/// [`time` crate]: https://docs.rs/time/0.3/time/ +#[derive(Clone, Debug)] +#[cfg_attr(docsrs, doc(cfg(all(feature = "time", feature = "local-time"))))] +#[cfg(feature = "local-time")] +pub struct LocalTime { + format: F, +} + +/// Formats the current [UTC time] using a [formatter] from the [`time` crate]. +/// +/// To format the current [local time] instead, use the [`LocalTime`] type. +/// +/// [local time]: https://docs.rs/time/0.3/time/struct.OffsetDateTime.html#method.now_local +/// [UTC time]: https://docs.rs/time/0.3/time/struct.OffsetDateTime.html#method.now_utc +/// [formatter]: https://docs.rs/time/0.3/time/formatting/trait.Formattable.html +/// [`time` crate]: https://docs.rs/time/0.3/time/ +#[cfg_attr(docsrs, doc(cfg(feature = "time")))] +#[derive(Clone, Debug)] +pub struct UtcTime { + format: F, +} + +// === impl LocalTime === + +#[cfg(feature = "local-time")] +impl LocalTime { + /// Returns a formatter that formats the current [local time] in the + /// [RFC 3339] format (a subset of the [ISO 8601] timestamp format). + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time}; + /// + /// let collector = tracing_subscriber::fmt() + /// .with_timer(time::LocalTime::rfc_3339()); + /// # drop(collector); + /// ``` + /// + /// [local time]: https://docs.rs/time/0.3/time/struct.OffsetDateTime.html#method.now_local + /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 + /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 + pub fn rfc_3339() -> Self { + Self::new(well_known::Rfc3339) + } +} + +#[cfg(feature = "local-time")] +impl LocalTime { + /// Returns a formatter that formats the current [local time] using the + /// [`time` crate] with the provided provided format. The format may be any + /// type that implements the [`Formattable`] trait. + /// + /// Typically, the format will be a format description string, or one of the + /// `time` crate's [well-known formats]. + /// + /// If the format description is statically known, then the + /// [`format_description!`] macro should be used. This is identical to the + /// [`time::format_description::parse`] method, but runs at compile-time, + /// throwing an error if the format description is invalid. If the desired format + /// is not known statically (e.g., a user is providing a format string), then the + /// [`time::format_description::parse`] method should be used. Note that this + /// method is fallible. + /// + /// See the [`time` book] for details on the format description syntax. + /// + /// # Examples + /// + /// Using the [`format_description!`] macro: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::LocalTime}; + /// use time::macros::format_description; + /// + /// let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]")); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using [`time::format_description::parse`]: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::LocalTime}; + /// + /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") + /// .expect("format string should be valid!"); + /// let timer = LocalTime::new(time_format); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using the [`format_description!`] macro requires enabling the `time` + /// crate's "macros" feature flag. + /// + /// Using a [well-known format][well-known formats] (this is equivalent to + /// [`LocalTime::rfc_3339`]): + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::LocalTime}; + /// + /// let timer = LocalTime::new(time::format_description::well_known::Rfc3339); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// [local time]: https://docs.rs/time/latest/time/struct.OffsetDateTime.html#method.now_local + /// [`time` crate]: https://docs.rs/time/0.3/time/ + /// [`Formattable`]: https://docs.rs/time/0.3/time/formatting/trait.Formattable.html + /// [well-known formats]: https://docs.rs/time/0.3/time/format_description/well_known/index.html + /// [`format_description!`]: https://docs.rs/time/0.3/time/macros/macro.format_description.html + /// [`time::format_description::parse`]: https://docs.rs/time/0.3/time/format_description/fn.parse.html + /// [`time` book]: https://time-rs.github.io/book/api/format-description.html + pub fn new(format: F) -> Self { + Self { format } + } +} + +#[cfg(feature = "local-time")] +impl FormatTime for LocalTime +where + F: Formattable, +{ + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + let now = OffsetDateTime::now_local().map_err(|_| fmt::Error)?; + format_datetime(now, w, &self.format) + } +} + +#[cfg(feature = "local-time")] +impl Default for LocalTime +where + F: Formattable + Default, +{ + fn default() -> Self { + Self::new(F::default()) + } +} + +// === impl UtcTime === + +impl UtcTime { + /// Returns a formatter that formats the current [UTC time] in the + /// [RFC 3339] format, which is a subset of the [ISO 8601] timestamp format. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time}; + /// + /// let collector = tracing_subscriber::fmt() + /// .with_timer(time::UtcTime::rfc_3339()); + /// # drop(collector); + /// ``` + /// + /// [local time]: https://docs.rs/time/0.3/time/struct.OffsetDateTime.html#method.now_utc + /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 + /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 + pub fn rfc_3339() -> Self { + Self::new(well_known::Rfc3339) + } +} + +impl UtcTime { + /// Returns a formatter that formats the current [UTC time] using the + /// [`time` crate], with the provided provided format. The format may be any + /// type that implements the [`Formattable`] trait. + /// + /// Typically, the format will be a format description string, or one of the + /// `time` crate's [well-known formats]. + /// + /// If the format description is statically known, then the + /// [`format_description!`] macro should be used. This is identical to the + /// [`time::format_description::parse`] method, but runs at compile-time, + /// failing an error if the format description is invalid. If the desired format + /// is not known statically (e.g., a user is providing a format string), then the + /// [`time::format_description::parse`] method should be used. Note that this + /// method is fallible. + /// + /// See the [`time` book] for details on the format description syntax. + /// + /// # Examples + /// + /// Using the [`format_description!`] macro: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::UtcTime}; + /// use time::macros::format_description; + /// + /// let timer = UtcTime::new(format_description!("[hour]:[minute]:[second]")); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using the [`format_description!`] macro requires enabling the `time` + /// crate's "macros" feature flag. + /// + /// Using [`time::format_description::parse`]: + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::UtcTime}; + /// + /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") + /// .expect("format string should be valid!"); + /// let timer = UtcTime::new(time_format); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// Using a [well-known format][well-known formats] (this is equivalent to + /// [`UtcTime::rfc_3339`]): + /// + /// ``` + /// use tracing_subscriber::fmt::{self, time::UtcTime}; + /// + /// let timer = UtcTime::new(time::format_description::well_known::Rfc3339); + /// let collector = tracing_subscriber::fmt() + /// .with_timer(timer); + /// # drop(collector); + /// ``` + /// + /// [UTC time]: https://docs.rs/time/latest/time/struct.OffsetDateTime.html#method.now_utc + /// [`time` crate]: https://docs.rs/time/0.3/time/ + /// [`Formattable`]: https://docs.rs/time/0.3/time/formatting/trait.Formattable.html + /// [well-known formats]: https://docs.rs/time/0.3/time/format_description/well_known/index.html + /// [`format_description!`]: https://docs.rs/time/0.3/time/macros/macro.format_description.html + /// [`time::format_description::parse`]: https://docs.rs/time/0.3/time/format_description/fn.parse.html + /// [`time` book]: https://time-rs.github.io/book/api/format-description.html + pub fn new(format: F) -> Self { + Self { format } + } +} + +impl FormatTime for UtcTime +where + F: Formattable, +{ + fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { + format_datetime(OffsetDateTime::now_utc(), w, &self.format) + } +} + +impl Default for UtcTime +where + F: Formattable + Default, +{ + fn default() -> Self { + Self::new(F::default()) + } +} + +fn format_datetime( + now: OffsetDateTime, + into: &mut Writer<'_>, + fmt: &impl Formattable, +) -> fmt::Result { + let mut into = WriteAdaptor::new(into); + now.format_into(&mut into, fmt) + .map_err(|_| fmt::Error) + .map(|_| ()) +} diff --git a/vendor/tracing-subscriber-0.3.3/src/fmt/writer.rs b/vendor/tracing-subscriber-0.3.3/src/fmt/writer.rs new file mode 100644 index 000000000..0974891f7 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/fmt/writer.rs @@ -0,0 +1,1464 @@ +//! Abstractions for creating [`io::Write`] instances. +//! +//! [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +use std::{ + fmt, + io::{self, Write}, + sync::{Arc, Mutex, MutexGuard}, +}; +use tracing_core::Metadata; + +/// A type that can create [`io::Write`] instances. +/// +/// `MakeWriter` is used by [`fmt::Layer`] or [`fmt::Subscriber`] to print +/// formatted text representations of [`Event`]s. +/// +/// This trait is already implemented for function pointers and +/// immutably-borrowing closures that return an instance of [`io::Write`], such +/// as [`io::stdout`] and [`io::stderr`]. Additionally, it is implemented for +/// [`std::sync::Mutex`][mutex] when the tyoe inside the mutex implements +/// [`io::Write`]. +/// +/// # Examples +/// +/// The simplest usage is to pass in a named function that returns a writer. For +/// example, to log all events to stderr, we could write: +/// ``` +/// let subscriber = tracing_subscriber::fmt() +/// .with_writer(std::io::stderr) +/// .finish(); +/// # drop(subscriber); +/// ``` +/// +/// Any function that returns a writer can be used: +/// +/// ``` +/// fn make_my_great_writer() -> impl std::io::Write { +/// // ... +/// # std::io::stdout() +/// } +/// +/// let subscriber = tracing_subscriber::fmt() +/// .with_writer(make_my_great_writer) +/// .finish(); +/// # drop(subscriber); +/// ``` +/// +/// A closure can be used to introduce arbitrary logic into how the writer is +/// created. Consider the (admittedly rather silly) example of sending every 5th +/// event to stderr, and all other events to stdout: +/// +/// ``` +/// use std::io; +/// use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; +/// +/// let n = AtomicUsize::new(0); +/// let subscriber = tracing_subscriber::fmt() +/// .with_writer(move || -> Box { +/// if n.fetch_add(1, Relaxed) % 5 == 0 { +/// Box::new(io::stderr()) +/// } else { +/// Box::new(io::stdout()) +/// } +/// }) +/// .finish(); +/// # drop(subscriber); +/// ``` +/// +/// A single instance of a type implementing [`io::Write`] may be used as a +/// `MakeWriter` by wrapping it in a [`Mutex`][mutex]. For example, we could +/// write to a file like so: +/// +/// ``` +/// use std::{fs::File, sync::Mutex}; +/// +/// # fn docs() -> Result<(), Box> { +/// let log_file = File::create("my_cool_trace.log")?; +/// let subscriber = tracing_subscriber::fmt() +/// .with_writer(Mutex::new(log_file)) +/// .finish(); +/// # drop(subscriber); +/// # Ok(()) +/// # } +/// ``` +/// +/// [`io::Write`]: std::io::Write +/// [`fmt::Layer`]: crate::fmt::Layer +/// [`fmt::Subscriber`]: crate::fmt::Subscriber +/// [`Event`]: tracing_core::event::Event +/// [`io::stdout`]: std::io::stdout() +/// [`io::stderr`]: std::io::stderr() +/// [mutex]: std::sync::Mutex +/// [`MakeWriter::make_writer_for`]: MakeWriter::make_writer_for +/// [`Metadata`]: tracing_core::Metadata +/// [levels]: tracing_core::Level +/// [targets]: tracing_core::Metadata::target +pub trait MakeWriter<'a> { + /// The concrete [`io::Write`] implementation returned by [`make_writer`]. + /// + /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html + /// [`make_writer`]: #tymethod.make_writer + type Writer: io::Write; + + /// Returns an instance of [`Writer`]. + /// + /// # Implementer notes + /// + /// [`fmt::Layer`] or [`fmt::Subscriber`] will call this method each time an event is recorded. Ensure any state + /// that must be saved across writes is not lost when the [`Writer`] instance is dropped. If + /// creating a [`io::Write`] instance is expensive, be sure to cache it when implementing + /// [`MakeWriter`] to improve performance. + /// + /// [`Writer`]: #associatedtype.Writer + /// [`fmt::Layer`]: crate::fmt::Layer + /// [`fmt::Subscriber`]: crate::fmt::Subscriber + /// [`io::Write`]: std::io::Write + fn make_writer(&'a self) -> Self::Writer; + + /// Returns a [`Writer`] for writing data from the span or event described + /// by the provided [`Metadata`]. + /// + /// By default, this calls [`self.make_writer()`][make_writer], ignoring + /// the provided metadata, but implementations can override this to provide + /// metadata-specific behaviors. + /// + /// This method allows `MakeWriter` implementations to implement different + /// behaviors based on the span or event being written. The `MakeWriter` + /// type might return different writers based on the provided metadata, or + /// might write some values to the writer before or after providing it to + /// the caller. + /// + /// For example, we might want to write data from spans and events at the + /// [`ERROR`] and [`WARN`] levels to `stderr`, and data from spans or events + /// at lower levels to stdout: + /// + /// ``` + /// use std::io::{self, Stdout, Stderr, StdoutLock, StderrLock}; + /// use tracing_subscriber::fmt::writer::MakeWriter; + /// use tracing_core::{Metadata, Level}; + /// + /// pub struct MyMakeWriter { + /// stdout: Stdout, + /// stderr: Stderr, + /// } + /// + /// /// A lock on either stdout or stderr, depending on the verbosity level + /// /// of the event being written. + /// pub enum StdioLock<'a> { + /// Stdout(StdoutLock<'a>), + /// Stderr(StderrLock<'a>), + /// } + /// + /// impl<'a> io::Write for StdioLock<'a> { + /// fn write(&mut self, buf: &[u8]) -> io::Result { + /// match self { + /// StdioLock::Stdout(lock) => lock.write(buf), + /// StdioLock::Stderr(lock) => lock.write(buf), + /// } + /// } + /// + /// fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + /// // ... + /// # match self { + /// # StdioLock::Stdout(lock) => lock.write_all(buf), + /// # StdioLock::Stderr(lock) => lock.write_all(buf), + /// # } + /// } + /// + /// fn flush(&mut self) -> io::Result<()> { + /// // ... + /// # match self { + /// # StdioLock::Stdout(lock) => lock.flush(), + /// # StdioLock::Stderr(lock) => lock.flush(), + /// # } + /// } + /// } + /// + /// impl<'a> MakeWriter<'a> for MyMakeWriter { + /// type Writer = StdioLock<'a>; + /// + /// fn make_writer(&'a self) -> Self::Writer { + /// // We must have an implementation of `make_writer` that makes + /// // a "default" writer without any configuring metadata. Let's + /// // just return stdout in that case. + /// StdioLock::Stdout(self.stdout.lock()) + /// } + /// + /// fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + /// // Here's where we can implement our special behavior. We'll + /// // check if the metadata's verbosity level is WARN or ERROR, + /// // and return stderr in that case. + /// if meta.level() <= &Level::WARN { + /// return StdioLock::Stderr(self.stderr.lock()); + /// } + /// + /// // Otherwise, we'll return stdout. + /// StdioLock::Stdout(self.stdout.lock()) + /// } + /// } + /// ``` + /// + /// [`Writer`]: MakeWriter::Writer + /// [`Metadata`]: tracing_core::Metadata + /// [make_writer]: MakeWriter::make_writer + /// [`WARN`]: tracing_core::Level::WARN + /// [`ERROR`]: tracing_core::Level::ERROR + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + let _ = meta; + self.make_writer() + } +} + +/// Extension trait adding combinators for working with types implementing +/// [`MakeWriter`]. +/// +/// This is not intended to be implemented directly for user-defined +/// [`MakeWriter`]s; instead, it should be imported when the desired methods are +/// used. +pub trait MakeWriterExt<'a>: MakeWriter<'a> { + /// Wraps `self` and returns a [`MakeWriter`] that will only write output + /// for events at or below the provided verbosity [`Level`]. For instance, + /// `Level::TRACE` is considered to be _more verbose` than `Level::INFO`. + /// + /// Events whose level is more verbose than `level` will be ignored, and no + /// output will be written. + /// + /// # Examples + /// + /// ``` + /// use tracing::Level; + /// use tracing_subscriber::fmt::writer::MakeWriterExt; + /// + /// // Construct a writer that outputs events to `stderr` only if the span or + /// // event's level is >= WARN (WARN and ERROR). + /// let mk_writer = std::io::stderr.with_max_level(Level::WARN); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// ``` + /// + /// Writing the `ERROR` and `WARN` levels to `stderr`, and everything else + /// to `stdout`: + /// + /// ``` + /// # use tracing::Level; + /// # use tracing_subscriber::fmt::writer::MakeWriterExt; + /// + /// let mk_writer = std::io::stderr + /// .with_max_level(Level::WARN) + /// .or_else(std::io::stdout); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// ``` + /// + /// Writing the `ERROR` level to `stderr`, the `INFO` and `WARN` levels to + /// `stdout`, and the `INFO` and DEBUG` levels to a file: + /// + /// ``` + /// # use tracing::Level; + /// # use tracing_subscriber::fmt::writer::MakeWriterExt; + /// use std::{sync::Arc, fs::File}; + /// # // don't actually create the file when running the tests. + /// # fn docs() -> std::io::Result<()> { + /// let debug_log = Arc::new(File::create("debug.log")?); + /// + /// let mk_writer = std::io::stderr + /// .with_max_level(Level::ERROR) + /// .or_else(std::io::stdout + /// .with_max_level(Level::INFO) + /// .and(debug_log.with_max_level(Level::DEBUG)) + /// ); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// # Ok(()) } + /// ``` + /// + /// [`Level`]: tracing_core::Level + /// [`io::Write`]: std::io::Write + fn with_max_level(self, level: tracing_core::Level) -> WithMaxLevel + where + Self: Sized, + { + WithMaxLevel::new(self, level) + } + + /// Wraps `self` and returns a [`MakeWriter`] that will only write output + /// for events at or above the provided verbosity [`Level`]. + /// + /// Events whose level is less verbose than `level` will be ignored, and no + /// output will be written. + /// + /// # Examples + /// + /// ``` + /// use tracing::Level; + /// use tracing_subscriber::fmt::writer::MakeWriterExt; + /// + /// // Construct a writer that outputs events to `stdout` only if the span or + /// // event's level is <= DEBUG (DEBUG and TRACE). + /// let mk_writer = std::io::stdout.with_min_level(Level::DEBUG); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// ``` + /// This can be combined with [`MakeWriterExt::with_max_level`] to write + /// only within a range of levels: + /// + /// ``` + /// # use tracing::Level; + /// # use tracing_subscriber::fmt::writer::MakeWriterExt; + /// // Only write the `DEBUG` and `INFO` levels to stdout. + /// let mk_writer = std::io::stdout + /// .with_max_level(Level::DEBUG) + /// .with_min_level(Level::INFO) + /// // Write the `WARN` and `ERROR` levels to stderr. + /// .and(std::io::stderr.with_min_level(Level::WARN)); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// ``` + /// [`Level`]: tracing_core::Level + /// [`io::Write`]: std::io::Write + fn with_min_level(self, level: tracing_core::Level) -> WithMinLevel + where + Self: Sized, + { + WithMinLevel::new(self, level) + } + + /// Wraps `self` with a predicate that takes a span or event's [`Metadata`] + /// and returns a `bool`. The returned [`MakeWriter`]'s + /// [`MakeWriter::make_writer_for`][mwf] method will check the predicate to + /// determine if a writer should be produced for a given span or event. + /// + /// If the predicate returns `false`, the wrapped [`MakeWriter`]'s + /// [`make_writer_for`][mwf] will return [`OptionalWriter::none`][own]. + /// Otherwise, it calls the wrapped [`MakeWriter`]'s + /// [`make_writer_for`][mwf] method, and returns the produced writer. + /// + /// This can be used to filter an output based on arbitrary [`Metadata`] + /// parameters. + /// + /// # Examples + /// + /// Writing events with a specific target to an HTTP access log, and other + /// events to stdout: + /// + /// ``` + /// use tracing_subscriber::fmt::writer::MakeWriterExt; + /// use std::{sync::Arc, fs::File}; + /// # // don't actually create the file when running the tests. + /// # fn docs() -> std::io::Result<()> { + /// let access_log = Arc::new(File::create("access.log")?); + /// + /// let mk_writer = access_log + /// // Only write events with the target "http::access_log" to the + /// // access log file. + /// .with_filter(|meta| meta.target() == "http::access_log") + /// // Write events with all other targets to stdout. + /// .or_else(std::io::stdout); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// # Ok(()) + /// # } + /// ``` + /// + /// Conditionally enabling or disabling a log file: + /// ``` + /// use tracing_subscriber::fmt::writer::MakeWriterExt; + /// use std::{ + /// sync::{Arc, atomic::{AtomicBool, Ordering}}, + /// fs::File, + /// }; + /// + /// static DEBUG_LOG_ENABLED: AtomicBool = AtomicBool::new(false); + /// + /// # // don't actually create the file when running the tests. + /// # fn docs() -> std::io::Result<()> { + /// // Create the debug log file + /// let debug_file = Arc::new(File::create("debug.log")?) + /// // Enable the debug log only if the flag is enabled. + /// .with_filter(|_| DEBUG_LOG_ENABLED.load(Ordering::Acquire)); + /// + /// // Always write to stdout + /// let mk_writer = std::io::stdout + /// // Write to the debug file if it's enabled + /// .and(debug_file); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// + /// // ... + /// + /// // Later, we can toggle on or off the debug log file. + /// DEBUG_LOG_ENABLED.store(true, Ordering::Release); + /// # Ok(()) + /// # } + /// ``` + /// + /// [`Metadata`]: tracing_core::Metadata + /// [mwf]: MakeWriter::make_writer_for + /// [own]: EitherWriter::none + fn with_filter(self, filter: F) -> WithFilter + where + Self: Sized, + F: Fn(&Metadata<'_>) -> bool, + { + WithFilter::new(self, filter) + } + + /// Combines `self` with another type implementing [`MakeWriter`], returning + /// a new [`MakeWriter`] that produces [writers] that write to *both* + /// outputs. + /// + /// If writing to either writer returns an error, the returned writer will + /// return that error. However, both writers will still be written to before + /// the error is returned, so it is possible for one writer to fail while + /// the other is written to successfully. + /// + /// # Examples + /// + /// ``` + /// use tracing_subscriber::fmt::writer::MakeWriterExt; + /// + /// // Construct a writer that outputs events to `stdout` *and* `stderr`. + /// let mk_writer = std::io::stdout.and(std::io::stderr); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// ``` + /// + /// `and` can be used in conjunction with filtering combinators. For + /// example, if we want to write to a number of outputs depending on the + /// level of an event, we could write: + /// + /// ``` + /// use tracing::Level; + /// # use tracing_subscriber::fmt::writer::MakeWriterExt; + /// use std::{sync::Arc, fs::File}; + /// # // don't actually create the file when running the tests. + /// # fn docs() -> std::io::Result<()> { + /// let debug_log = Arc::new(File::create("debug.log")?); + /// + /// // Write everything to the debug log. + /// let mk_writer = debug_log + /// // Write the `ERROR` and `WARN` levels to stderr. + /// .and(std::io::stderr.with_max_level(Level::WARN)) + /// // Write `INFO` to `stdout`. + /// .and(std::io::stdout + /// .with_max_level(Level::INFO) + /// .with_min_level(Level::INFO) + /// ); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// # Ok(()) } + /// ``` + /// + /// [writers]: std::io::Write + fn and(self, other: B) -> Tee + where + Self: Sized, + B: MakeWriter<'a> + Sized, + { + Tee::new(self, other) + } + + /// Combines `self` with another type implementing [`MakeWriter`], returning + /// a new [`MakeWriter`] that calls `other`'s [`make_writer`] if `self`'s + /// `make_writer` returns [`OptionalWriter::none`][own]. + /// + /// # Examples + /// + /// ``` + /// use tracing::Level; + /// use tracing_subscriber::fmt::writer::MakeWriterExt; + /// + /// // Produces a writer that writes to `stderr` if the level is >= WARN, + /// // or returns `OptionalWriter::none()` otherwise. + /// let stderr = std::io::stderr.with_max_level(Level::WARN); + /// + /// // If the `stderr` `MakeWriter` is disabled by the max level filter, + /// // write to stdout instead: + /// let mk_writer = stderr.or_else(std::io::stdout); + /// + /// tracing_subscriber::fmt().with_writer(mk_writer).init(); + /// ``` + /// + /// [`make_writer`]: MakeWriter::make_writer + /// [own]: EitherWriter::none + fn or_else(self, other: B) -> OrElse + where + Self: MakeWriter<'a, Writer = OptionalWriter> + Sized, + B: MakeWriter<'a> + Sized, + W: Write, + { + OrElse::new(self, other) + } +} + +/// A writer intended to support [`libtest`'s output capturing][capturing] for use in unit tests. +/// +/// `TestWriter` is used by [`fmt::Subscriber`] or [`fmt::Layer`] to enable capturing support. +/// +/// `cargo test` can only capture output from the standard library's [`print!`] macro. See +/// [`libtest`'s output capturing][capturing] for more details about output capturing. +/// +/// Writing to [`io::stdout`] and [`io::stderr`] produces the same results as using +/// [`libtest`'s `--nocapture` option][nocapture] which may make the results look unreadable. +/// +/// [`fmt::Subscriber`]: ../struct.Subscriber.html +/// [`fmt::Layer`]: ../struct.Layer.html +/// [capturing]: https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output +/// [nocapture]: https://doc.rust-lang.org/cargo/commands/cargo-test.html +/// [`io::stdout`]: https://doc.rust-lang.org/std/io/fn.stdout.html +/// [`io::stderr`]: https://doc.rust-lang.org/std/io/fn.stderr.html +/// [`print!`]: https://doc.rust-lang.org/std/macro.print.html +#[derive(Default, Debug)] +pub struct TestWriter { + _p: (), +} + +/// A writer that erases the specific [`io::Write`] and [`MakeWriter`] types being used. +/// +/// This is useful in cases where the concrete type of the writer cannot be known +/// until runtime. +/// +/// # Examples +/// +/// A function that returns a [`Subscriber`] that will write to either stdout or stderr: +/// +/// ```rust +/// # use tracing::Subscriber; +/// # use tracing_subscriber::fmt::writer::BoxMakeWriter; +/// +/// fn dynamic_writer(use_stderr: bool) -> impl Subscriber { +/// let writer = if use_stderr { +/// BoxMakeWriter::new(std::io::stderr) +/// } else { +/// BoxMakeWriter::new(std::io::stdout) +/// }; +/// +/// tracing_subscriber::fmt().with_writer(writer).finish() +/// } +/// ``` +/// +/// [`Subscriber`]: tracing::Subscriber +/// [`io::Write`]: std::io::Write +pub struct BoxMakeWriter { + inner: Box MakeWriter<'a, Writer = Box> + Send + Sync>, + name: &'static str, +} + +/// A [writer] that is one of two types implementing [`io::Write`][writer]. +/// +/// This may be used by [`MakeWriter`] implementations that may conditionally +/// return one of two writers. +/// +/// [writer]: std::io::Write +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum EitherWriter { + /// A writer of type `A`. + A(A), + /// A writer of type `B`. + B(B), +} + +/// A [writer] which may or may not be enabled. +/// +/// This may be used by [`MakeWriter`] implementations that wish to +/// conditionally enable or disable the returned writer based on a span or +/// event's [`Metadata`]. +/// +/// [writer]: std::io::Write +pub type OptionalWriter = EitherWriter; + +/// A [`MakeWriter`] combinator that only returns an enabled [writer] for spans +/// and events with metadata at or below a specified verbosity [`Level`]. +/// +/// This is returned by the [`MakeWriterExt::with_max_level`] method. See the +/// method documentation for details. +/// +/// [writer]: std::io::Write +/// [`Level`]: tracing_core::Level +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct WithMaxLevel { + make: M, + level: tracing_core::Level, +} + +/// A [`MakeWriter`] combinator that only returns an enabled [writer] for spans +/// and events with metadata at or above a specified verbosity [`Level`]. +/// +/// This is returned by the [`MakeWriterExt::with_min_level`] method. See the +/// method documentation for details. +/// +/// [writer]: std::io::Write +/// [`Level`]: tracing_core::Level +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct WithMinLevel { + make: M, + level: tracing_core::Level, +} + +/// A [`MakeWriter`] combinator that wraps a [`MakeWriter`] with a predicate for +/// span and event [`Metadata`], so that the [`MakeWriter::make_writer_for`] +/// method returns [`OptionalWriter::some`][ows] when the predicate returns `true`, +/// and [`OptionalWriter::none`][own] when the predicate returns `false`. +/// +/// This is returned by the [`MakeWriterExt::with_filter`] method. See the +/// method documentation for details. +/// +/// [`Metadata`]: tracing_core::Metadata +/// [ows]: EitherWriter::some +/// [own]: EitherWriter::none +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct WithFilter { + make: M, + filter: F, +} + +/// Combines a [`MakeWriter`] that returns an [`OptionalWriter`] with another +/// [`MakeWriter`], so that the second [`MakeWriter`] is used when the first +/// [`MakeWriter`] returns [`OptionalWriter::none`][own]. +/// +/// This is returned by the [`MakeWriterExt::or_else] method. See the +/// method documentation for details. +/// +/// [own]: EitherWriter::none +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct OrElse { + inner: A, + or_else: B, +} + +/// Combines two types implementing [`MakeWriter`] (or [`std::io::Write`]) to +/// produce a writer that writes to both [`MakeWriter`]'s returned writers. +/// +/// This is returned by the [`MakeWriterExt::and`] method. See the method +/// documentation for details. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Tee { + a: A, + b: B, +} + +/// A type implementing [`io::Write`] for a [`MutexGuard`] where the type +/// inside the [`Mutex`] implements [`io::Write`]. +/// +/// This is used by the [`MakeWriter`] implementation for [`Mutex`], because +/// [`MutexGuard`] itself will not implement [`io::Write`] — instead, it +/// _dereferences_ to a type implementing [`io::Write`]. Because [`MakeWriter`] +/// requires the `Writer` type to implement [`io::Write`], it's necessary to add +/// a newtype that forwards the trait implementation. +/// +/// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +/// [`MutexGuard`]: https://doc.rust-lang.org/std/sync/struct.MutexGuard.html +/// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html +/// [`MakeWriter`]: trait.MakeWriter.html +#[derive(Debug)] +pub struct MutexGuardWriter<'a, W>(MutexGuard<'a, W>); + +/// Implements [`std::io::Write`] for an [`Arc`] where `&W: Write`. +/// +/// This is an implementation detail of the [`MakeWriter`] impl for [`Arc`]. +#[derive(Clone, Debug)] +pub struct ArcWriter(Arc); + +/// A bridge between `fmt::Write` and `io::Write`. +/// +/// This is used by the timestamp formatting implementation for the `time` +/// crate and by the JSON formatter. In both cases, this is needed because +/// `tracing-subscriber`'s `FormatEvent`/`FormatTime` traits expect a +/// `fmt::Write` implementation, while `serde_json::Serializer` and `time`'s +/// `format_into` methods expect an `io::Write`. +#[cfg(any(feature = "json", feature = "time"))] +pub(in crate::fmt) struct WriteAdaptor<'a> { + fmt_write: &'a mut dyn fmt::Write, +} + +impl<'a, F, W> MakeWriter<'a> for F +where + F: Fn() -> W, + W: io::Write, +{ + type Writer = W; + + fn make_writer(&'a self) -> Self::Writer { + (self)() + } +} + +impl<'a, W> MakeWriter<'a> for Arc +where + &'a W: io::Write + 'a, +{ + type Writer = &'a W; + fn make_writer(&'a self) -> Self::Writer { + &*self + } +} + +impl<'a> MakeWriter<'a> for std::fs::File { + type Writer = &'a std::fs::File; + fn make_writer(&'a self) -> Self::Writer { + self + } +} + +// === impl TestWriter === + +impl TestWriter { + /// Returns a new `TestWriter` with the default configuration. + pub fn new() -> Self { + Self::default() + } +} + +impl io::Write for TestWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let out_str = String::from_utf8_lossy(buf); + print!("{}", out_str); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl<'a> MakeWriter<'a> for TestWriter { + type Writer = Self; + + fn make_writer(&'a self) -> Self::Writer { + Self::default() + } +} + +// === impl BoxMakeWriter === + +impl BoxMakeWriter { + /// Constructs a `BoxMakeWriter` wrapping a type implementing [`MakeWriter`]. + /// + /// [`MakeWriter`]: trait.MakeWriter.html + pub fn new(make_writer: M) -> Self + where + M: for<'a> MakeWriter<'a> + Send + Sync + 'static, + { + Self { + inner: Box::new(Boxed(make_writer)), + name: std::any::type_name::(), + } + } +} + +impl fmt::Debug for BoxMakeWriter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("BoxMakeWriter") + .field(&format_args!("<{}>", self.name)) + .finish() + } +} + +impl<'a> MakeWriter<'a> for BoxMakeWriter { + type Writer = Box; + + #[inline] + fn make_writer(&'a self) -> Self::Writer { + self.inner.make_writer() + } + + #[inline] + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + self.inner.make_writer_for(meta) + } +} + +struct Boxed(M); + +impl<'a, M> MakeWriter<'a> for Boxed +where + M: MakeWriter<'a>, +{ + type Writer = Box; + + fn make_writer(&'a self) -> Self::Writer { + let w = self.0.make_writer(); + Box::new(w) + } + + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + let w = self.0.make_writer_for(meta); + Box::new(w) + } +} + +// === impl Mutex/MutexGuardWriter === + +impl<'a, W> MakeWriter<'a> for Mutex +where + W: io::Write + 'a, +{ + type Writer = MutexGuardWriter<'a, W>; + + fn make_writer(&'a self) -> Self::Writer { + MutexGuardWriter(self.lock().expect("lock poisoned")) + } +} + +impl<'a, W> io::Write for MutexGuardWriter<'a, W> +where + W: io::Write, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + + #[inline] + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.0.write_all(buf) + } + + #[inline] + fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { + self.0.write_fmt(fmt) + } +} + +// === impl EitherWriter === + +impl io::Write for EitherWriter +where + A: io::Write, + B: io::Write, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + match self { + EitherWriter::A(a) => a.write(buf), + EitherWriter::B(b) => b.write(buf), + } + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + match self { + EitherWriter::A(a) => a.flush(), + EitherWriter::B(b) => b.flush(), + } + } + + #[inline] + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + match self { + EitherWriter::A(a) => a.write_vectored(bufs), + EitherWriter::B(b) => b.write_vectored(bufs), + } + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + match self { + EitherWriter::A(a) => a.write_all(buf), + EitherWriter::B(b) => b.write_all(buf), + } + } + + #[inline] + fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { + match self { + EitherWriter::A(a) => a.write_fmt(fmt), + EitherWriter::B(b) => b.write_fmt(fmt), + } + } +} + +impl OptionalWriter { + /// Returns a [disabled writer]. + /// + /// Any bytes written to the returned writer are discarded. + /// + /// This is equivalent to returning [`Option::None`]. + /// + /// [disabled writer]: std::io::sink + #[inline] + pub fn none() -> Self { + EitherWriter::B(std::io::sink()) + } + + /// Returns an enabled writer of type `T`. + /// + /// This is equivalent to returning [`Option::Some`]. + #[inline] + pub fn some(t: T) -> Self { + EitherWriter::A(t) + } +} + +impl From> for OptionalWriter { + #[inline] + fn from(opt: Option) -> Self { + match opt { + Some(writer) => Self::some(writer), + None => Self::none(), + } + } +} + +// === impl WithMaxLevel === + +impl WithMaxLevel { + /// Wraps the provided [`MakeWriter`] with a maximum [`Level`], so that it + /// returns [`OptionalWriter::none`] for spans and events whose level is + /// more verbose than the maximum level. + /// + /// See [`MakeWriterExt::with_max_level`] for details. + /// + /// [`Level`]: tracing_core::Level + pub fn new(make: M, level: tracing_core::Level) -> Self { + Self { make, level } + } +} + +impl<'a, M: MakeWriter<'a>> MakeWriter<'a> for WithMaxLevel { + type Writer = OptionalWriter; + + #[inline] + fn make_writer(&'a self) -> Self::Writer { + // If we don't know the level, assume it's disabled. + OptionalWriter::none() + } + + #[inline] + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + if meta.level() <= &self.level { + return OptionalWriter::some(self.make.make_writer_for(meta)); + } + OptionalWriter::none() + } +} + +// === impl WithMinLevel === + +impl WithMinLevel { + /// Wraps the provided [`MakeWriter`] with a minimum [`Level`], so that it + /// returns [`OptionalWriter::none`] for spans and events whose level is + /// less verbose than the maximum level. + /// + /// See [`MakeWriterExt::with_min_level`] for details. + /// + /// [`Level`]: tracing_core::Level + pub fn new(make: M, level: tracing_core::Level) -> Self { + Self { make, level } + } +} + +impl<'a, M: MakeWriter<'a>> MakeWriter<'a> for WithMinLevel { + type Writer = OptionalWriter; + + #[inline] + fn make_writer(&'a self) -> Self::Writer { + // If we don't know the level, assume it's disabled. + OptionalWriter::none() + } + + #[inline] + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + if meta.level() >= &self.level { + return OptionalWriter::some(self.make.make_writer_for(meta)); + } + OptionalWriter::none() + } +} + +// ==== impl WithFilter === + +impl WithFilter { + /// Wraps `make` with the provided `filter`, returning a [`MakeWriter`] that + /// will call `make.make_writer_for()` when `filter` returns `true` for a + /// span or event's [`Metadata`], and returns a [`sink`] otherwise. + /// + /// See [`MakeWriterExt::with_filter`] for details. + /// + /// [`Metadata`]: tracing_core::Metadata + /// [`sink`]: std::io::sink + pub fn new(make: M, filter: F) -> Self + where + F: Fn(&Metadata<'_>) -> bool, + { + Self { make, filter } + } +} + +impl<'a, M, F> MakeWriter<'a> for WithFilter +where + M: MakeWriter<'a>, + F: Fn(&Metadata<'_>) -> bool, +{ + type Writer = OptionalWriter; + + #[inline] + fn make_writer(&'a self) -> Self::Writer { + OptionalWriter::some(self.make.make_writer()) + } + + #[inline] + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + if (self.filter)(meta) { + OptionalWriter::some(self.make.make_writer_for(meta)) + } else { + OptionalWriter::none() + } + } +} + +// === impl Tee === + +impl Tee { + /// Combines two types implementing [`MakeWriter`], returning + /// a new [`MakeWriter`] that produces [writers] that write to *both* + /// outputs. + /// + /// See the documentation for [`MakeWriterExt::and`] for details. + pub fn new(a: A, b: B) -> Self { + Self { a, b } + } +} + +impl<'a, A, B> MakeWriter<'a> for Tee +where + A: MakeWriter<'a>, + B: MakeWriter<'a>, +{ + type Writer = Tee; + + #[inline] + fn make_writer(&'a self) -> Self::Writer { + Tee::new(self.a.make_writer(), self.b.make_writer()) + } + + #[inline] + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + Tee::new(self.a.make_writer_for(meta), self.b.make_writer_for(meta)) + } +} + +macro_rules! impl_tee { + ($self_:ident.$f:ident($($arg:ident),*)) => { + { + let res_a = $self_.a.$f($($arg),*); + let res_b = $self_.b.$f($($arg),*); + (res_a?, res_b?) + } + } +} + +impl io::Write for Tee +where + A: io::Write, + B: io::Write, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + let (a, b) = impl_tee!(self.write(buf)); + Ok(std::cmp::max(a, b)) + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + impl_tee!(self.flush()); + Ok(()) + } + + #[inline] + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + let (a, b) = impl_tee!(self.write_vectored(bufs)); + Ok(std::cmp::max(a, b)) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + impl_tee!(self.write_all(buf)); + Ok(()) + } + + #[inline] + fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { + impl_tee!(self.write_fmt(fmt)); + Ok(()) + } +} + +// === impl OrElse === + +impl OrElse { + /// Combines + pub fn new<'a, W>(inner: A, or_else: B) -> Self + where + A: MakeWriter<'a, Writer = OptionalWriter>, + B: MakeWriter<'a>, + W: Write, + { + Self { inner, or_else } + } +} + +impl<'a, A, B, W> MakeWriter<'a> for OrElse +where + A: MakeWriter<'a, Writer = OptionalWriter>, + B: MakeWriter<'a>, + W: io::Write, +{ + type Writer = EitherWriter; + + #[inline] + fn make_writer(&'a self) -> Self::Writer { + match self.inner.make_writer() { + EitherWriter::A(writer) => EitherWriter::A(writer), + EitherWriter::B(_) => EitherWriter::B(self.or_else.make_writer()), + } + } + + #[inline] + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + match self.inner.make_writer_for(meta) { + EitherWriter::A(writer) => EitherWriter::A(writer), + EitherWriter::B(_) => EitherWriter::B(self.or_else.make_writer_for(meta)), + } + } +} + +// === impl ArcWriter === + +impl io::Write for ArcWriter +where + for<'a> &'a W: io::Write, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + (&*self.0).write(buf) + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + (&*self.0).flush() + } + + #[inline] + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + (&*self.0).write_vectored(bufs) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (&*self.0).write_all(buf) + } + + #[inline] + fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { + (&*self.0).write_fmt(fmt) + } +} + +// === impl WriteAdaptor === + +#[cfg(any(feature = "json", feature = "time"))] +impl<'a> WriteAdaptor<'a> { + pub(in crate::fmt) fn new(fmt_write: &'a mut dyn fmt::Write) -> Self { + Self { fmt_write } + } +} +#[cfg(any(feature = "json", feature = "time"))] +impl<'a> io::Write for WriteAdaptor<'a> { + fn write(&mut self, buf: &[u8]) -> io::Result { + let s = + std::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + self.fmt_write + .write_str(s) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + + Ok(s.as_bytes().len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[cfg(any(feature = "json", feature = "time"))] +impl<'a> fmt::Debug for WriteAdaptor<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("WriteAdaptor { .. }") + } +} +// === blanket impls === + +impl<'a, M> MakeWriterExt<'a> for M where M: MakeWriter<'a> {} +#[cfg(test)] +mod test { + use super::*; + use crate::fmt::format::Format; + use crate::fmt::test::{MockMakeWriter, MockWriter}; + use crate::fmt::Subscriber; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::sync::{Arc, Mutex}; + use tracing::{debug, error, info, trace, warn, Level}; + use tracing_core::dispatcher::{self, Dispatch}; + + fn test_writer(make_writer: T, msg: &str, buf: &Mutex>) + where + T: for<'writer> MakeWriter<'writer> + Send + Sync + 'static, + { + let subscriber = { + #[cfg(feature = "ansi")] + let f = Format::default().without_time().with_ansi(false); + #[cfg(not(feature = "ansi"))] + let f = Format::default().without_time(); + Subscriber::builder() + .event_format(f) + .with_writer(make_writer) + .finish() + }; + let dispatch = Dispatch::from(subscriber); + + dispatcher::with_default(&dispatch, || { + error!("{}", msg); + }); + + let expected = format!("ERROR {}: {}\n", module_path!(), msg); + let actual = String::from_utf8(buf.try_lock().unwrap().to_vec()).unwrap(); + assert!(actual.contains(expected.as_str())); + } + + fn has_lines(buf: &Mutex>, msgs: &[(tracing::Level, &str)]) { + let actual = String::from_utf8(buf.try_lock().unwrap().to_vec()).unwrap(); + let mut expected_lines = msgs.iter(); + for line in actual.lines() { + let line = dbg!(line).trim(); + let (level, msg) = expected_lines + .next() + .unwrap_or_else(|| panic!("expected no more lines, but got: {:?}", line)); + let expected = format!("{} {}: {}", level, module_path!(), msg); + assert_eq!(line, expected.as_str()); + } + } + + #[test] + fn custom_writer_closure() { + let buf = Arc::new(Mutex::new(Vec::new())); + let buf2 = buf.clone(); + let make_writer = move || MockWriter::new(buf2.clone()); + let msg = "my custom writer closure error"; + test_writer(make_writer, msg, &buf); + } + + #[test] + fn custom_writer_struct() { + let buf = Arc::new(Mutex::new(Vec::new())); + let make_writer = MockMakeWriter::new(buf.clone()); + let msg = "my custom writer struct error"; + test_writer(make_writer, msg, &buf); + } + + #[test] + fn custom_writer_mutex() { + let buf = Arc::new(Mutex::new(Vec::new())); + let writer = MockWriter::new(buf.clone()); + let make_writer = Mutex::new(writer); + let msg = "my mutex writer error"; + test_writer(make_writer, msg, &buf); + } + + #[test] + fn combinators_level_filters() { + let info_buf = Arc::new(Mutex::new(Vec::new())); + let info = MockMakeWriter::new(info_buf.clone()); + + let debug_buf = Arc::new(Mutex::new(Vec::new())); + let debug = MockMakeWriter::new(debug_buf.clone()); + + let warn_buf = Arc::new(Mutex::new(Vec::new())); + let warn = MockMakeWriter::new(warn_buf.clone()); + + let err_buf = Arc::new(Mutex::new(Vec::new())); + let err = MockMakeWriter::new(err_buf.clone()); + + let make_writer = info + .with_max_level(Level::INFO) + .and(debug.with_max_level(Level::DEBUG)) + .and(warn.with_max_level(Level::WARN)) + .and(err.with_max_level(Level::ERROR)); + + let c = { + #[cfg(feature = "ansi")] + let f = Format::default().without_time().with_ansi(false); + #[cfg(not(feature = "ansi"))] + let f = Format::default().without_time(); + Subscriber::builder() + .event_format(f) + .with_writer(make_writer) + .with_max_level(Level::TRACE) + .finish() + }; + + let _s = tracing::subscriber::set_default(c); + + trace!("trace"); + debug!("debug"); + info!("info"); + warn!("warn"); + error!("error"); + + let all_lines = [ + (Level::TRACE, "trace"), + (Level::DEBUG, "debug"), + (Level::INFO, "info"), + (Level::WARN, "warn"), + (Level::ERROR, "error"), + ]; + + println!("max level debug"); + has_lines(&debug_buf, &all_lines[1..]); + + println!("max level info"); + has_lines(&info_buf, &all_lines[2..]); + + println!("max level warn"); + has_lines(&warn_buf, &all_lines[3..]); + + println!("max level error"); + has_lines(&err_buf, &all_lines[4..]); + } + + #[test] + fn combinators_or_else() { + let some_buf = Arc::new(Mutex::new(Vec::new())); + let some = MockMakeWriter::new(some_buf.clone()); + + let or_else_buf = Arc::new(Mutex::new(Vec::new())); + let or_else = MockMakeWriter::new(or_else_buf.clone()); + + let return_some = AtomicBool::new(true); + let make_writer = move || { + if return_some.swap(false, Ordering::Relaxed) { + OptionalWriter::some(some.make_writer()) + } else { + OptionalWriter::none() + } + }; + let make_writer = make_writer.or_else(or_else); + let c = { + #[cfg(feature = "ansi")] + let f = Format::default().without_time().with_ansi(false); + #[cfg(not(feature = "ansi"))] + let f = Format::default().without_time(); + Subscriber::builder() + .event_format(f) + .with_writer(make_writer) + .with_max_level(Level::TRACE) + .finish() + }; + + let _s = tracing::subscriber::set_default(c); + info!("hello"); + info!("world"); + info!("goodbye"); + + has_lines(&some_buf, &[(Level::INFO, "hello")]); + has_lines( + &or_else_buf, + &[(Level::INFO, "world"), (Level::INFO, "goodbye")], + ); + } + + #[test] + fn combinators_or_else_chain() { + let info_buf = Arc::new(Mutex::new(Vec::new())); + let info = MockMakeWriter::new(info_buf.clone()); + + let debug_buf = Arc::new(Mutex::new(Vec::new())); + let debug = MockMakeWriter::new(debug_buf.clone()); + + let warn_buf = Arc::new(Mutex::new(Vec::new())); + let warn = MockMakeWriter::new(warn_buf.clone()); + + let err_buf = Arc::new(Mutex::new(Vec::new())); + let err = MockMakeWriter::new(err_buf.clone()); + + let make_writer = err.with_max_level(Level::ERROR).or_else( + warn.with_max_level(Level::WARN).or_else( + info.with_max_level(Level::INFO) + .or_else(debug.with_max_level(Level::DEBUG)), + ), + ); + + let c = { + #[cfg(feature = "ansi")] + let f = Format::default().without_time().with_ansi(false); + #[cfg(not(feature = "ansi"))] + let f = Format::default().without_time(); + Subscriber::builder() + .event_format(f) + .with_writer(make_writer) + .with_max_level(Level::TRACE) + .finish() + }; + + let _s = tracing::subscriber::set_default(c); + + trace!("trace"); + debug!("debug"); + info!("info"); + warn!("warn"); + error!("error"); + + println!("max level debug"); + has_lines(&debug_buf, &[(Level::DEBUG, "debug")]); + + println!("max level info"); + has_lines(&info_buf, &[(Level::INFO, "info")]); + + println!("max level warn"); + has_lines(&warn_buf, &[(Level::WARN, "warn")]); + + println!("max level error"); + has_lines(&err_buf, &[(Level::ERROR, "error")]); + } + + #[test] + fn combinators_and() { + let a_buf = Arc::new(Mutex::new(Vec::new())); + let a = MockMakeWriter::new(a_buf.clone()); + + let b_buf = Arc::new(Mutex::new(Vec::new())); + let b = MockMakeWriter::new(b_buf.clone()); + + let lines = &[(Level::INFO, "hello"), (Level::INFO, "world")]; + + let make_writer = a.and(b); + let c = { + #[cfg(feature = "ansi")] + let f = Format::default().without_time().with_ansi(false); + #[cfg(not(feature = "ansi"))] + let f = Format::default().without_time(); + Subscriber::builder() + .event_format(f) + .with_writer(make_writer) + .with_max_level(Level::TRACE) + .finish() + }; + + let _s = tracing::subscriber::set_default(c); + info!("hello"); + info!("world"); + + has_lines(&a_buf, &lines[..]); + has_lines(&b_buf, &lines[..]); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/layer/context.rs b/vendor/tracing-subscriber-0.3.3/src/layer/context.rs new file mode 100644 index 000000000..e11959526 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/layer/context.rs @@ -0,0 +1,434 @@ +use tracing_core::{metadata::Metadata, span, subscriber::Subscriber, Event}; + +use crate::registry::{self, LookupSpan, SpanRef}; + +#[cfg(all(feature = "registry", feature = "std"))] +use crate::{filter::FilterId, registry::Registry}; +/// Represents information about the current context provided to [`Layer`]s by the +/// wrapped [`Subscriber`]. +/// +/// To access [stored data] keyed by a span ID, implementors of the `Layer` +/// trait should ensure that the `Subscriber` type parameter is *also* bound by the +/// [`LookupSpan`]: +/// +/// ```rust +/// use tracing::Subscriber; +/// use tracing_subscriber::{Layer, registry::LookupSpan}; +/// +/// pub struct MyLayer; +/// +/// impl Layer for MyLayer +/// where +/// S: Subscriber + for<'a> LookupSpan<'a>, +/// { +/// // ... +/// } +/// ``` +/// +/// [`Layer`]: ../layer/trait.Layer.html +/// [`Subscriber`]: https://docs.rs/tracing-core/latest/tracing_core/trait.Subscriber.html +/// [stored data]: ../registry/struct.SpanRef.html +/// [`LookupSpan`]: "../registry/trait.LookupSpan.html +#[derive(Debug)] +pub struct Context<'a, S> { + subscriber: Option<&'a S>, + /// The bitmask of all [`Filtered`] layers that currently apply in this + /// context. If there is only a single [`Filtered`] wrapping the layer that + /// produced this context, then this is that filter's ID. Otherwise, if we + /// are in a nested tree with multiple filters, this is produced by + /// [`and`]-ing together the [`FilterId`]s of each of the filters that wrap + /// the current layer. + /// + /// [`Filtered`]: crate::filter::Filtered + /// [`FilterId`]: crate::filter::FilterId + /// [`and`]: crate::filter::FilterId::and + #[cfg(all(feature = "registry", feature = "std"))] + filter: FilterId, +} + +// === impl Context === + +impl<'a, S> Context<'a, S> +where + S: Subscriber, +{ + pub(super) fn new(subscriber: &'a S) -> Self { + Self { + subscriber: Some(subscriber), + + #[cfg(feature = "registry")] + filter: FilterId::none(), + } + } + + /// Returns the wrapped subscriber's view of the current span. + #[inline] + pub fn current_span(&self) -> span::Current { + self.subscriber + .map(Subscriber::current_span) + // TODO: this would be more correct as "unknown", so perhaps + // `tracing-core` should make `Current::unknown()` public? + .unwrap_or_else(span::Current::none) + } + + /// Returns whether the wrapped subscriber would enable the current span. + #[inline] + pub fn enabled(&self, metadata: &Metadata<'_>) -> bool { + self.subscriber + .map(|subscriber| subscriber.enabled(metadata)) + // If this context is `None`, we are registering a callsite, so + // return `true` so that the layer does not incorrectly assume that + // the inner subscriber has disabled this metadata. + // TODO(eliza): would it be more correct for this to return an `Option`? + .unwrap_or(true) + } + + /// Records the provided `event` with the wrapped subscriber. + /// + /// # Notes + /// + /// - The subscriber is free to expect that the event's callsite has been + /// [registered][register], and may panic or fail to observe the event if this is + /// not the case. The `tracing` crate's macros ensure that all events are + /// registered, but if the event is constructed through other means, the + /// user is responsible for ensuring that [`register_callsite`][register] + /// has been called prior to calling this method. + /// - This does _not_ call [`enabled`] on the inner subscriber. If the + /// caller wishes to apply the wrapped subscriber's filter before choosing + /// whether to record the event, it may first call [`Context::enabled`] to + /// check whether the event would be enabled. This allows `Layer`s to + /// elide constructing the event if it would not be recorded. + /// + /// [register]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html#method.register_callsite + /// [`enabled`]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html#method.enabled + /// [`Context::enabled`]: #method.enabled + #[inline] + pub fn event(&self, event: &Event<'_>) { + if let Some(subscriber) = self.subscriber { + subscriber.event(event); + } + } + + /// Returns a [`SpanRef`] for the parent span of the given [`Event`], if + /// it has a parent. + /// + /// If the event has an explicitly overridden parent, this method returns + /// a reference to that span. If the event's parent is the current span, + /// this returns a reference to the current span, if there is one. If this + /// returns `None`, then either the event's parent was explicitly set to + /// `None`, or the event's parent was defined contextually, but no span + /// is currently entered. + /// + /// Compared to [`Context::current_span`] and [`Context::lookup_current`], + /// this respects overrides provided by the [`Event`]. + /// + /// Compared to [`Event::parent`], this automatically falls back to the contextual + /// span, if required. + /// + /// ```rust + /// use tracing::{Event, Subscriber}; + /// use tracing_subscriber::{ + /// layer::{Context, Layer}, + /// prelude::*, + /// registry::LookupSpan, + /// }; + /// + /// struct PrintingLayer; + /// impl Layer for PrintingLayer + /// where + /// S: Subscriber + for<'lookup> LookupSpan<'lookup>, + /// { + /// fn on_event(&self, event: &Event, ctx: Context) { + /// let span = ctx.event_span(event); + /// println!("Event in span: {:?}", span.map(|s| s.name())); + /// } + /// } + /// + /// tracing::subscriber::with_default(tracing_subscriber::registry().with(PrintingLayer), || { + /// tracing::info!("no span"); + /// // Prints: Event in span: None + /// + /// let span = tracing::info_span!("span"); + /// tracing::info!(parent: &span, "explicitly specified"); + /// // Prints: Event in span: Some("span") + /// + /// let _guard = span.enter(); + /// tracing::info!("contextual span"); + /// // Prints: Event in span: Some("span") + /// }); + /// ``` + /// + ///
+    ///     Note: This requires the wrapped subscriber to
+    ///     implement the 
+    ///     LookupSpan trait. See the documentation on
+    ///     Context's
+    ///     declaration for details.
+    /// 
+ #[inline] + pub fn event_span(&self, event: &Event<'_>) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + if event.is_root() { + None + } else if event.is_contextual() { + self.lookup_current() + } else { + // TODO(eliza): this should handle parent IDs + event.parent().and_then(|id| self.span(id)) + } + } + + /// Returns metadata for the span with the given `id`, if it exists. + /// + /// If this returns `None`, then no span exists for that ID (either it has + /// closed or the ID is invalid). + #[inline] + pub fn metadata(&self, id: &span::Id) -> Option<&'static Metadata<'static>> + where + S: for<'lookup> LookupSpan<'lookup>, + { + let span = self.span(id)?; + Some(span.metadata()) + } + + /// Returns [stored data] for the span with the given `id`, if it exists. + /// + /// If this returns `None`, then no span exists for that ID (either it has + /// closed or the ID is invalid). + /// + ///
+    ///     Note: This requires the wrapped subscriber to
+    ///     implement the 
+    ///     LookupSpan trait. See the documentation on
+    ///     Context's
+    ///     declaration for details.
+    /// 
+ /// + /// [stored data]: ../registry/struct.SpanRef.html + #[inline] + pub fn span(&self, id: &span::Id) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + let span = self.subscriber.as_ref()?.span(id)?; + + #[cfg(all(feature = "registry", feature = "std"))] + return span.try_with_filter(self.filter); + + #[cfg(not(feature = "registry"))] + Some(span) + } + + /// Returns `true` if an active span exists for the given `Id`. + /// + ///
+    ///     Note: This requires the wrapped subscriber to
+    ///     implement the 
+    ///     LookupSpan trait. See the documentation on
+    ///     Context's
+    ///     declaration for details.
+    /// 
+ #[inline] + pub fn exists(&self, id: &span::Id) -> bool + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.subscriber.as_ref().and_then(|s| s.span(id)).is_some() + } + + /// Returns [stored data] for the span that the wrapped subscriber considers + /// to be the current. + /// + /// If this returns `None`, then we are not currently within a span. + /// + ///
+    ///     Note: This requires the wrapped subscriber to
+    ///     implement the 
+    ///     LookupSpan trait. See the documentation on
+    ///     Context's
+    ///     declaration for details.
+    /// 
+ /// + /// [stored data]: ../registry/struct.SpanRef.html + #[inline] + pub fn lookup_current(&self) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + let subscriber = *self.subscriber.as_ref()?; + let current = subscriber.current_span(); + let id = current.id()?; + let span = subscriber.span(id); + debug_assert!( + span.is_some(), + "the subscriber should have data for the current span ({:?})!", + id, + ); + + // If we found a span, and our per-layer filter enables it, return that + // span! + #[cfg(all(feature = "registry", feature = "std"))] + { + if let Some(span) = span?.try_with_filter(self.filter) { + Some(span) + } else { + // Otherwise, the span at the *top* of the stack is disabled by + // per-layer filtering, but there may be additional spans in the stack. + // + // Currently, `LookupSpan` doesn't have a nice way of exposing access to + // the whole span stack. However, if we can downcast the innermost + // subscriber to a a `Registry`, we can iterate over its current span + // stack. + // + // TODO(eliza): when https://github.com/tokio-rs/tracing/issues/1459 is + // implemented, change this to use that instead... + self.lookup_current_filtered(subscriber) + } + } + + #[cfg(not(feature = "registry"))] + span + } + + /// Slow path for when the current span is disabled by PLF and we have a + /// registry. + // This is called by `lookup_current` in the case that per-layer filtering + // is in use. `lookup_current` is allowed to be inlined, but this method is + // factored out to prevent the loop and (potentially-recursive) subscriber + // downcasting from being inlined if `lookup_current` is inlined. + #[inline(never)] + #[cfg(all(feature = "registry", feature = "std"))] + fn lookup_current_filtered<'lookup>( + &self, + subscriber: &'lookup S, + ) -> Option> + where + S: LookupSpan<'lookup>, + { + let registry = (subscriber as &dyn Subscriber).downcast_ref::()?; + registry + .span_stack() + .iter() + .find_map(|id| subscriber.span(id)?.try_with_filter(self.filter)) + } + + /// Returns an iterator over the [stored data] for all the spans in the + /// current context, starting with the specified span and ending with the + /// root of the trace tree and ending with the current span. + /// + ///
+    /// Note: Compared to scope this
+    /// returns the spans in reverse order (from leaf to root). Use
+    /// Scope::from_root
+    /// in case root-to-leaf ordering is desired.
+    /// 
+ /// + ///
+    ///     Note: This requires the wrapped subscriber to
+    ///     implement the 
+    ///     LookupSpan trait. See the documentation on
+    ///     Context's
+    ///     declaration for details.
+    /// 
+ /// + /// [stored data]: ../registry/struct.SpanRef.html + pub fn span_scope(&self, id: &span::Id) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + Some(self.span(id)?.scope()) + } + + /// Returns an iterator over the [stored data] for all the spans in the + /// current context, starting with the parent span of the specified event, + /// and ending with the root of the trace tree and ending with the current span. + /// + ///
+    /// Note: Compared to scope this
+    /// returns the spans in reverse order (from leaf to root). Use
+    /// Scope::from_root
+    /// in case root-to-leaf ordering is desired.
+    /// 
+ /// + ///
+    ///     Note: This requires the wrapped subscriber to
+    ///     implement the 
+    ///     LookupSpan trait. See the documentation on
+    ///     Context's
+    ///     declaration for details.
+    /// 
+ /// + /// [stored data]: ../registry/struct.SpanRef.html + pub fn event_scope(&self, event: &Event<'_>) -> Option> + where + S: for<'lookup> LookupSpan<'lookup>, + { + Some(self.event_span(event)?.scope()) + } + + #[cfg(all(feature = "registry", feature = "std"))] + pub(crate) fn with_filter(self, filter: FilterId) -> Self { + // If we already have our own `FilterId`, combine it with the provided + // one. That way, the new `FilterId` will consider a span to be disabled + // if it was disabled by the given `FilterId` *or* any `FilterId`s for + // layers "above" us in the stack. + // + // See the doc comment for `FilterId::and` for details. + let filter = self.filter.and(filter); + Self { filter, ..self } + } + + #[cfg(all(feature = "registry", feature = "std"))] + pub(crate) fn is_enabled_for(&self, span: &span::Id, filter: FilterId) -> bool + where + S: for<'lookup> LookupSpan<'lookup>, + { + self.is_enabled_inner(span, filter).unwrap_or(false) + } + + #[cfg(all(feature = "registry", feature = "std"))] + pub(crate) fn if_enabled_for(self, span: &span::Id, filter: FilterId) -> Option + where + S: for<'lookup> LookupSpan<'lookup>, + { + if self.is_enabled_inner(span, filter)? { + Some(self.with_filter(filter)) + } else { + None + } + } + + #[cfg(all(feature = "registry", feature = "std"))] + fn is_enabled_inner(&self, span: &span::Id, filter: FilterId) -> Option + where + S: for<'lookup> LookupSpan<'lookup>, + { + Some(self.span(span)?.is_enabled_for(filter)) + } +} + +impl<'a, S> Context<'a, S> { + pub(crate) fn none() -> Self { + Self { + subscriber: None, + + #[cfg(feature = "registry")] + filter: FilterId::none(), + } + } +} + +impl<'a, S> Clone for Context<'a, S> { + #[inline] + fn clone(&self) -> Self { + let subscriber = self.subscriber.as_ref().copied(); + Context { + subscriber, + + #[cfg(all(feature = "registry", feature = "std"))] + filter: self.filter, + } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/layer/layered.rs b/vendor/tracing-subscriber-0.3.3/src/layer/layered.rs new file mode 100644 index 000000000..c690764ad --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/layer/layered.rs @@ -0,0 +1,471 @@ +use tracing_core::{ + metadata::Metadata, + span, + subscriber::{Interest, Subscriber}, + Event, LevelFilter, +}; + +use crate::{ + filter, + layer::{Context, Layer}, + registry::LookupSpan, +}; +#[cfg(all(feature = "registry", feature = "std"))] +use crate::{filter::FilterId, registry::Registry}; +use core::{any::TypeId, cmp, fmt, marker::PhantomData}; + +/// A [`Subscriber`] composed of a `Subscriber` wrapped by one or more +/// [`Layer`]s. +/// +/// [`Layer`]: crate::Layer +/// [`Subscriber`]: https://docs.rs/tracing-core/latest/tracing_core/trait.Subscriber.html +#[derive(Clone)] +pub struct Layered { + /// The layer. + layer: L, + + /// The inner value that `self.layer` was layered onto. + /// + /// If this is also a `Layer`, then this `Layered` will implement `Layer`. + /// If this is a `Subscriber`, then this `Layered` will implement + /// `Subscriber` instead. + inner: I, + + // These booleans are used to determine how to combine `Interest`s and max + // level hints when per-layer filters are in use. + /// Is `self.inner` a `Registry`? + /// + /// If so, when combining `Interest`s, we want to "bubble up" its + /// `Interest`. + inner_is_registry: bool, + + /// Does `self.layer` have per-layer filters? + /// + /// This will be true if: + /// - `self.inner` is a `Filtered`. + /// - `self.inner` is a tree of `Layered`s where _all_ arms of those + /// `Layered`s have per-layer filters. + /// + /// Otherwise, if it's a `Layered` with one per-layer filter in one branch, + /// but a non-per-layer-filtered layer in the other branch, this will be + /// _false_, because the `Layered` is already handling the combining of + /// per-layer filter `Interest`s and max level hints with its non-filtered + /// `Layer`. + has_layer_filter: bool, + + /// Does `self.inner` have per-layer filters? + /// + /// This is determined according to the same rules as + /// `has_layer_filter` above. + inner_has_layer_filter: bool, + _s: PhantomData, +} + +// === impl Layered === + +impl Subscriber for Layered +where + L: Layer, + S: Subscriber, +{ + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + self.pick_interest(self.layer.register_callsite(metadata), || { + self.inner.register_callsite(metadata) + }) + } + + fn enabled(&self, metadata: &Metadata<'_>) -> bool { + if self.layer.enabled(metadata, self.ctx()) { + // if the outer layer enables the callsite metadata, ask the subscriber. + self.inner.enabled(metadata) + } else { + // otherwise, the callsite is disabled by the layer + + // If per-layer filters are in use, and we are short-circuiting + // (rather than calling into the inner type), clear the current + // per-layer filter `enabled` state. + #[cfg(feature = "registry")] + filter::FilterState::clear_enabled(); + + false + } + } + + fn max_level_hint(&self) -> Option { + self.pick_level_hint(self.layer.max_level_hint(), self.inner.max_level_hint()) + } + + fn new_span(&self, span: &span::Attributes<'_>) -> span::Id { + let id = self.inner.new_span(span); + self.layer.on_new_span(span, &id, self.ctx()); + id + } + + fn record(&self, span: &span::Id, values: &span::Record<'_>) { + self.inner.record(span, values); + self.layer.on_record(span, values, self.ctx()); + } + + fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { + self.inner.record_follows_from(span, follows); + self.layer.on_follows_from(span, follows, self.ctx()); + } + + fn event(&self, event: &Event<'_>) { + self.inner.event(event); + self.layer.on_event(event, self.ctx()); + } + + fn enter(&self, span: &span::Id) { + self.inner.enter(span); + self.layer.on_enter(span, self.ctx()); + } + + fn exit(&self, span: &span::Id) { + self.inner.exit(span); + self.layer.on_exit(span, self.ctx()); + } + + fn clone_span(&self, old: &span::Id) -> span::Id { + let new = self.inner.clone_span(old); + if &new != old { + self.layer.on_id_change(old, &new, self.ctx()) + }; + new + } + + #[inline] + fn drop_span(&self, id: span::Id) { + self.try_close(id); + } + + fn try_close(&self, id: span::Id) -> bool { + #[cfg(all(feature = "registry", feature = "std"))] + let subscriber = &self.inner as &dyn Subscriber; + #[cfg(all(feature = "registry", feature = "std"))] + let mut guard = subscriber + .downcast_ref::() + .map(|registry| registry.start_close(id.clone())); + if self.inner.try_close(id.clone()) { + // If we have a registry's close guard, indicate that the span is + // closing. + #[cfg(all(feature = "registry", feature = "std"))] + { + if let Some(g) = guard.as_mut() { + g.is_closing() + }; + } + + self.layer.on_close(id, self.ctx()); + true + } else { + false + } + } + + #[inline] + fn current_span(&self) -> span::Current { + self.inner.current_span() + } + + #[doc(hidden)] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + // Unlike the implementation of `Layer` for `Layered`, we don't have to + // handle the "magic PLF downcast marker" here. If a `Layered` + // implements `Subscriber`, we already know that the `inner` branch is + // going to contain something that doesn't have per-layer filters (the + // actual root `Subscriber`). Thus, a `Layered` that implements + // `Subscriber` will always be propagating the root subscriber's + // `Interest`/level hint, even if it includes a `Layer` that has + // per-layer filters, because it will only ever contain layers where + // _one_ child has per-layer filters. + // + // The complex per-layer filter detection logic is only relevant to + // *trees* of layers, which involve the `Layer` implementation for + // `Layered`, not *lists* of layers, where every `Layered` implements + // `Subscriber`. Of course, a linked list can be thought of as a + // degenerate tree...but luckily, we are able to make a type-level + // distinction between individual `Layered`s that are definitely + // list-shaped (their inner child implements `Subscriber`), and + // `Layered`s that might be tree-shaped (the inner child is also a + // `Layer`). + + // If downcasting to `Self`, return a pointer to `self`. + if id == TypeId::of::() { + return Some(self as *const _ as *const ()); + } + + self.layer + .downcast_raw(id) + .or_else(|| self.inner.downcast_raw(id)) + } +} + +impl Layer for Layered +where + A: Layer, + B: Layer, + S: Subscriber, +{ + fn on_layer(&mut self, subscriber: &mut S) { + self.layer.on_layer(subscriber); + self.inner.on_layer(subscriber); + } + + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + self.pick_interest(self.layer.register_callsite(metadata), || { + self.inner.register_callsite(metadata) + }) + } + + fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { + if self.layer.enabled(metadata, ctx.clone()) { + // if the outer subscriber enables the callsite metadata, ask the inner layer. + self.inner.enabled(metadata, ctx) + } else { + // otherwise, the callsite is disabled by this layer + false + } + } + + fn max_level_hint(&self) -> Option { + self.pick_level_hint(self.layer.max_level_hint(), self.inner.max_level_hint()) + } + + #[inline] + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { + self.inner.on_new_span(attrs, id, ctx.clone()); + self.layer.on_new_span(attrs, id, ctx); + } + + #[inline] + fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { + self.inner.on_record(span, values, ctx.clone()); + self.layer.on_record(span, values, ctx); + } + + #[inline] + fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { + self.inner.on_follows_from(span, follows, ctx.clone()); + self.layer.on_follows_from(span, follows, ctx); + } + + #[inline] + fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { + self.inner.on_event(event, ctx.clone()); + self.layer.on_event(event, ctx); + } + + #[inline] + fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { + self.inner.on_enter(id, ctx.clone()); + self.layer.on_enter(id, ctx); + } + + #[inline] + fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { + self.inner.on_exit(id, ctx.clone()); + self.layer.on_exit(id, ctx); + } + + #[inline] + fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { + self.inner.on_close(id.clone(), ctx.clone()); + self.layer.on_close(id, ctx); + } + + #[inline] + fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { + self.inner.on_id_change(old, new, ctx.clone()); + self.layer.on_id_change(old, new, ctx); + } + + #[doc(hidden)] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + match id { + // If downcasting to `Self`, return a pointer to `self`. + id if id == TypeId::of::() => Some(self as *const _ as *const ()), + + // Oh, we're looking for per-layer filters! + // + // This should only happen if we are inside of another `Layered`, + // and it's trying to determine how it should combine `Interest`s + // and max level hints. + // + // In that case, this `Layered` should be considered to be + // "per-layer filtered" if *both* the outer layer and the inner + // layer/subscriber have per-layer filters. Otherwise, this `Layered + // should *not* be considered per-layer filtered (even if one or the + // other has per layer filters). If only one `Layer` is per-layer + // filtered, *this* `Layered` will handle aggregating the `Interest` + // and level hints on behalf of its children, returning the + // aggregate (which is the value from the &non-per-layer-filtered* + // child). + // + // Yes, this rule *is* slightly counter-intuitive, but it's + // necessary due to a weird edge case that can occur when two + // `Layered`s where one side is per-layer filtered and the other + // isn't are `Layered` together to form a tree. If we didn't have + // this rule, we would actually end up *ignoring* `Interest`s from + // the non-per-layer-filtered layers, since both branches would + // claim to have PLF. + // + // If you don't understand this...that's fine, just don't mess with + // it. :) + id if filter::is_plf_downcast_marker(id) => { + self.layer.downcast_raw(id).and(self.inner.downcast_raw(id)) + } + + // Otherwise, try to downcast both branches normally... + _ => self + .layer + .downcast_raw(id) + .or_else(|| self.inner.downcast_raw(id)), + } + } +} + +impl<'a, L, S> LookupSpan<'a> for Layered +where + S: Subscriber + LookupSpan<'a>, +{ + type Data = S::Data; + + fn span_data(&'a self, id: &span::Id) -> Option { + self.inner.span_data(id) + } + + #[cfg(all(feature = "registry", feature = "std"))] + fn register_filter(&mut self) -> FilterId { + self.inner.register_filter() + } +} + +impl Layered +where + S: Subscriber, +{ + fn ctx(&self) -> Context<'_, S> { + Context::new(&self.inner) + } +} + +impl Layered +where + A: Layer, + S: Subscriber, +{ + pub(super) fn new(layer: A, inner: B, inner_has_layer_filter: bool) -> Self { + #[cfg(all(feature = "registry", feature = "std"))] + let inner_is_registry = TypeId::of::() == TypeId::of::(); + + #[cfg(not(all(feature = "registry", feature = "std")))] + let inner_is_registry = false; + + let inner_has_layer_filter = inner_has_layer_filter || inner_is_registry; + let has_layer_filter = filter::layer_has_plf(&layer); + Self { + layer, + inner, + has_layer_filter, + inner_has_layer_filter, + inner_is_registry, + _s: PhantomData, + } + } + + fn pick_interest(&self, outer: Interest, inner: impl FnOnce() -> Interest) -> Interest { + if self.has_layer_filter { + return inner(); + } + + // If the outer layer has disabled the callsite, return now so that + // the inner layer/subscriber doesn't get its hopes up. + if outer.is_never() { + // If per-layer filters are in use, and we are short-circuiting + // (rather than calling into the inner type), clear the current + // per-layer filter interest state. + #[cfg(feature = "registry")] + drop(filter::FilterState::take_interest()); + + return outer; + } + + // The `inner` closure will call `inner.register_callsite()`. We do this + // before the `if` statement to ensure that the inner subscriber is + // informed that the callsite exists regardless of the outer layer's + // filtering decision. + let inner = inner(); + if outer.is_sometimes() { + // if this interest is "sometimes", return "sometimes" to ensure that + // filters are reevaluated. + return outer; + } + + // If there is a per-layer filter in the `inner` stack, and it returns + // `never`, change the interest to `sometimes`, because the `outer` + // layer didn't return `never`. This means that _some_ layer still wants + // to see that callsite, even though the inner stack's per-layer filter + // didn't want it. Therefore, returning `sometimes` will ensure + // `enabled` is called so that the per-layer filter can skip that + // span/event, while the `outer` layer still gets to see it. + if inner.is_never() && self.inner_has_layer_filter { + return Interest::sometimes(); + } + + // otherwise, allow the inner subscriber or collector to weigh in. + inner + } + + fn pick_level_hint( + &self, + outer_hint: Option, + inner_hint: Option, + ) -> Option { + if self.inner_is_registry { + return outer_hint; + } + + if self.has_layer_filter && self.inner_has_layer_filter { + return Some(cmp::max(outer_hint?, inner_hint?)); + } + + if self.has_layer_filter && inner_hint.is_none() { + return None; + } + + if self.inner_has_layer_filter && outer_hint.is_none() { + return None; + } + + cmp::max(outer_hint, inner_hint) + } +} + +impl fmt::Debug for Layered +where + A: fmt::Debug, + B: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(all(feature = "registry", feature = "std"))] + let alt = f.alternate(); + let mut s = f.debug_struct("Layered"); + // These additional fields are more verbose and usually only necessary + // for internal debugging purposes, so only print them if alternate mode + // is enabled. + + #[cfg(all(feature = "registry", feature = "std"))] + { + if alt { + s.field("inner_is_registry", &self.inner_is_registry) + .field("has_layer_filter", &self.has_layer_filter) + .field("inner_has_layer_filter", &self.inner_has_layer_filter); + } + } + + s.field("layer", &self.layer) + .field("inner", &self.inner) + .finish() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/layer/mod.rs b/vendor/tracing-subscriber-0.3.3/src/layer/mod.rs new file mode 100644 index 000000000..f3f994490 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/layer/mod.rs @@ -0,0 +1,1285 @@ +//! The [`Layer`] trait, a composable abstraction for building [`Subscriber`]s. +//! +//! The [`Subscriber`] trait in `tracing-core` represents the _complete_ set of +//! functionality required to consume `tracing` instrumentation. This means that +//! a single `Subscriber` instance is a self-contained implementation of a +//! complete strategy for collecting traces; but it _also_ means that the +//! `Subscriber` trait cannot easily be composed with other `Subscriber`s. +//! +//! In particular, [`Subscriber`]s are responsible for generating [span IDs] and +//! assigning them to spans. Since these IDs must uniquely identify a span +//! within the context of the current trace, this means that there may only be +//! a single `Subscriber` for a given thread at any point in time — +//! otherwise, there would be no authoritative source of span IDs. +//! +//! On the other hand, the majority of the [`Subscriber`] trait's functionality +//! is composable: any number of subscribers may _observe_ events, span entry +//! and exit, and so on, provided that there is a single authoritative source of +//! span IDs. The [`Layer`] trait represents this composable subset of the +//! [`Subscriber`] behavior; it can _observe_ events and spans, but does not +//! assign IDs. +//! +//! ## Composing Layers +//! +//! Since a [`Layer`] does not implement a complete strategy for collecting +//! traces, it must be composed with a `Subscriber` in order to be used. The +//! [`Layer`] trait is generic over a type parameter (called `S` in the trait +//! definition), representing the types of `Subscriber` they can be composed +//! with. Thus, a [`Layer`] may be implemented that will only compose with a +//! particular `Subscriber` implementation, or additional trait bounds may be +//! added to constrain what types implementing `Subscriber` a `Layer` can wrap. +//! +//! `Layer`s may be added to a `Subscriber` by using the [`SubscriberExt::with`] +//! method, which is provided by `tracing-subscriber`'s [prelude]. This method +//! returns a [`Layered`] struct that implements `Subscriber` by composing the +//! `Layer` with the `Subscriber`. +//! +//! For example: +//! ```rust +//! use tracing_subscriber::Layer; +//! use tracing_subscriber::prelude::*; +//! use tracing::Subscriber; +//! +//! pub struct MyLayer { +//! // ... +//! } +//! +//! impl Layer for MyLayer { +//! // ... +//! } +//! +//! pub struct MySubscriber { +//! // ... +//! } +//! +//! # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; +//! impl Subscriber for MySubscriber { +//! // ... +//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } +//! # fn record(&self, _: &Id, _: &Record) {} +//! # fn event(&self, _: &Event) {} +//! # fn record_follows_from(&self, _: &Id, _: &Id) {} +//! # fn enabled(&self, _: &Metadata) -> bool { false } +//! # fn enter(&self, _: &Id) {} +//! # fn exit(&self, _: &Id) {} +//! } +//! # impl MyLayer { +//! # fn new() -> Self { Self {} } +//! # } +//! # impl MySubscriber { +//! # fn new() -> Self { Self { }} +//! # } +//! +//! let subscriber = MySubscriber::new() +//! .with(MyLayer::new()); +//! +//! tracing::subscriber::set_global_default(subscriber); +//! ``` +//! +//! Multiple `Layer`s may be composed in the same manner: +//! ```rust +//! # use tracing_subscriber::{Layer, layer::SubscriberExt}; +//! # use tracing::Subscriber; +//! pub struct MyOtherLayer { +//! // ... +//! } +//! +//! impl Layer for MyOtherLayer { +//! // ... +//! } +//! +//! pub struct MyThirdLayer { +//! // ... +//! } +//! +//! impl Layer for MyThirdLayer { +//! // ... +//! } +//! # pub struct MyLayer {} +//! # impl Layer for MyLayer {} +//! # pub struct MySubscriber { } +//! # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; +//! # impl Subscriber for MySubscriber { +//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } +//! # fn record(&self, _: &Id, _: &Record) {} +//! # fn event(&self, _: &Event) {} +//! # fn record_follows_from(&self, _: &Id, _: &Id) {} +//! # fn enabled(&self, _: &Metadata) -> bool { false } +//! # fn enter(&self, _: &Id) {} +//! # fn exit(&self, _: &Id) {} +//! } +//! # impl MyLayer { +//! # fn new() -> Self { Self {} } +//! # } +//! # impl MyOtherLayer { +//! # fn new() -> Self { Self {} } +//! # } +//! # impl MyThirdLayer { +//! # fn new() -> Self { Self {} } +//! # } +//! # impl MySubscriber { +//! # fn new() -> Self { Self { }} +//! # } +//! +//! let subscriber = MySubscriber::new() +//! .with(MyLayer::new()) +//! .with(MyOtherLayer::new()) +//! .with(MyThirdLayer::new()); +//! +//! tracing::subscriber::set_global_default(subscriber); +//! ``` +//! +//! The [`Layer::with_subscriber`] constructs the [`Layered`] type from a +//! [`Layer`] and [`Subscriber`], and is called by [`SubscriberExt::with`]. In +//! general, it is more idiomatic to use [`SubscriberExt::with`], and treat +//! [`Layer::with_subscriber`] as an implementation detail, as `with_subscriber` +//! calls must be nested, leading to less clear code for the reader. +//! +//! [prelude]: crate::prelude +//! +//! ## Recording Traces +//! +//! The [`Layer`] trait defines a set of methods for consuming notifications from +//! tracing instrumentation, which are generally equivalent to the similarly +//! named methods on [`Subscriber`]. Unlike [`Subscriber`], the methods on +//! `Layer` are additionally passed a [`Context`] type, which exposes additional +//! information provided by the wrapped subscriber (such as [the current span]) +//! to the layer. +//! +//! ## Filtering with `Layer`s +//! +//! As well as strategies for handling trace events, the `Layer` trait may also +//! be used to represent composable _filters_. This allows the determination of +//! what spans and events should be recorded to be decoupled from _how_ they are +//! recorded: a filtering layer can be applied to other layers or +//! subscribers. `Layer`s can be used to implement _global filtering_, where a +//! `Layer` provides a filtering strategy for the entire subscriber. +//! Additionally, individual recording `Layer`s or sets of `Layer`s may be +//! combined with _per-layer filters_ that control what spans and events are +//! recorded by those layers. +//! +//! ### Global Filtering +//! +//! A `Layer` that implements a filtering strategy should override the +//! [`register_callsite`] and/or [`enabled`] methods. It may also choose to implement +//! methods such as [`on_enter`], if it wishes to filter trace events based on +//! the current span context. +//! +//! Note that the [`Layer::register_callsite`] and [`Layer::enabled`] methods +//! determine whether a span or event is enabled *globally*. Thus, they should +//! **not** be used to indicate whether an individual layer wishes to record a +//! particular span or event. Instead, if a layer is only interested in a subset +//! of trace data, but does *not* wish to disable other spans and events for the +//! rest of the layer stack should ignore those spans and events in its +//! notification methods. +//! +//! The filtering methods on a stack of `Layer`s are evaluated in a top-down +//! order, starting with the outermost `Layer` and ending with the wrapped +//! [`Subscriber`]. If any layer returns `false` from its [`enabled`] method, or +//! [`Interest::never()`] from its [`register_callsite`] method, filter +//! evaluation will short-circuit and the span or event will be disabled. +//! +//! ### Per-Layer Filtering +//! +//! **Note**: per-layer filtering APIs currently require the [`"registry"` crate +//! feature flag][feat] to be enabled. +//! +//! Sometimes, it may be desirable for one `Layer` to record a particular subset +//! of spans and events, while a different subset of spans and events are +//! recorded by other `Layer`s. For example: +//! +//! - A layer that records metrics may wish to observe only events including +//! particular tracked values, while a logging layer ignores those events. +//! - If recording a distributed trace is expensive, it might be desirable to +//! only send spans with `INFO` and lower verbosity to the distributed tracing +//! system, while logging more verbose spans to a file. +//! - Spans and events with a particular target might be recorded differently +//! from others, such as by generating an HTTP access log from a span that +//! tracks the lifetime of an HTTP request. +//! +//! The [`Filter`] trait is used to control what spans and events are +//! observed by an individual `Layer`, while still allowing other `Layer`s to +//! potentially record them. The [`Layer::with_filter`] method combines a +//! `Layer` with a [`Filter`], returning a [`Filtered`] layer. +//! +//! This crate's [`filter`] module provides a number of types which implement +//! the [`Filter`] trait, such as [`LevelFilter`], [`Targets`], and +//! [`FilterFn`]. These [`Filter`]s provide ready-made implementations of +//! common forms of filtering. For custom filtering policies, the [`FilterFn`] +//! and [`DynFilterFn`] types allow implementing a [`Filter`] with a closure or +//! function pointer. In addition, when more control is required, the [`Filter`] +//! trait may also be implemented for user-defined types. +//! +//!
+//!     Warning: Currently, the 
+//!     Registry type defined in this crate is the only root
+//!     Subscriber capable of supporting Layers with
+//!     per-layer filters. In the future, new APIs will be added to allow other
+//!     root Subscribers to support per-layer filters.
+//! 
+//! +//! For example, to generate an HTTP access log based on spans with +//! the `http_access` target, while logging other spans and events to +//! standard out, a [`Filter`] can be added to the access log layer: +//! +//! ``` +//! use tracing_subscriber::{filter, prelude::*}; +//! +//! // Generates an HTTP access log. +//! let access_log = // ... +//! # filter::LevelFilter::INFO; +//! +//! // Add a filter to the access log layer so that it only observes +//! // spans and events with the `http_access` target. +//! let access_log = access_log.with_filter(filter::filter_fn(|metadata| { +//! // Returns `true` if and only if the span or event's target is +//! // "http_access". +//! metadata.target() == "http_access" +//! })); +//! +//! // A general-purpose logging layer. +//! let fmt_layer = tracing_subscriber::fmt::layer(); +//! +//! // Build a subscriber that combines the access log and stdout log +//! // layers. +//! tracing_subscriber::registry() +//! .with(fmt_layer) +//! .with(access_log) +//! .init(); +//! ``` +//! +//! Multiple layers can have their own, separate per-layer filters. A span or +//! event will be recorded if it is enabled by _any_ per-layer filter, but it +//! will be skipped by the layers whose filters did not enable it. Building on +//! the previous example: +//! +//! ``` +//! use tracing_subscriber::{filter::{filter_fn, LevelFilter}, prelude::*}; +//! +//! let access_log = // ... +//! # LevelFilter::INFO; +//! let fmt_layer = tracing_subscriber::fmt::layer(); +//! +//! tracing_subscriber::registry() +//! // Add the filter for the "http_access" target to the access +//! // log layer, like before. +//! .with(access_log.with_filter(filter_fn(|metadata| { +//! metadata.target() == "http_access" +//! }))) +//! // Add a filter for spans and events with the INFO level +//! // and below to the logging layer. +//! .with(fmt_layer.with_filter(LevelFilter::INFO)) +//! .init(); +//! +//! // Neither layer will observe this event +//! tracing::debug!(does_anyone_care = false, "a tree fell in the forest"); +//! +//! // This event will be observed by the logging layer, but not +//! // by the access log layer. +//! tracing::warn!(dose_roentgen = %3.8, "not great, but not terrible"); +//! +//! // This event will be observed only by the access log layer. +//! tracing::trace!(target: "http_access", "HTTP request started"); +//! +//! // Both layers will observe this event. +//! tracing::error!(target: "http_access", "HTTP request failed with a very bad error!"); +//! ``` +//! +//! A per-layer filter can be applied to multiple [`Layer`]s at a time, by +//! combining them into a [`Layered`] layer using [`Layer::and_then`], and then +//! calling [`Layer::with_filter`] on the resulting [`Layered`] layer. +//! +//! Consider the following: +//! - `layer_a` and `layer_b`, which should only receive spans and events at +//! the [`INFO`] [level] and above. +//! - A third layer, `layer_c`, which should receive spans and events at +//! the [`DEBUG`] [level] as well. +//! The layers and filters would be composed thusly: +//! +//! ``` +//! use tracing_subscriber::{filter::LevelFilter, prelude::*}; +//! +//! let layer_a = // ... +//! # LevelFilter::INFO; +//! let layer_b = // ... +//! # LevelFilter::INFO; +//! let layer_c = // ... +//! # LevelFilter::INFO; +//! +//! let info_layers = layer_a +//! // Combine `layer_a` and `layer_b` into a `Layered` layer: +//! .and_then(layer_b) +//! // ...and then add an `INFO` `LevelFilter` to that layer: +//! .with_filter(LevelFilter::INFO); +//! +//! tracing_subscriber::registry() +//! // Add `layer_c` with a `DEBUG` filter. +//! .with(layer_c.with_filter(LevelFilter::DEBUG)) +//! .with(info_layers) +//! .init(); +//!``` +//! +//! If a [`Filtered`] [`Layer`] is combined with another [`Layer`] +//! [`Layer::and_then`], and a filter is added to the [`Layered`] layer, that +//! layer will be filtered by *both* the inner filter and the outer filter. +//! Only spans and events that are enabled by *both* filters will be +//! observed by that layer. This can be used to implement complex filtering +//! trees. +//! +//! As an example, consider the following constraints: +//! - Suppose that a particular [target] is used to indicate events that +//! should be counted as part of a metrics system, which should be only +//! observed by a layer that collects metrics. +//! - A log of high-priority events ([`INFO`] and above) should be logged +//! to stdout, while more verbose events should be logged to a debugging log file. +//! - Metrics-focused events should *not* be included in either log output. +//! +//! In that case, it is possible to apply a filter to both logging layers to +//! exclude the metrics events, while additionally adding a [`LevelFilter`] +//! to the stdout log: +//! +//! ``` +//! # // wrap this in a function so we don't actually create `debug.log` when +//! # // running the doctests.. +//! # fn docs() -> Result<(), Box> { +//! use tracing_subscriber::{filter, prelude::*}; +//! use std::{fs::File, sync::Arc}; +//! +//! // A layer that logs events to stdout using the human-readable "pretty" +//! // format. +//! let stdout_log = tracing_subscriber::fmt::layer() +//! .pretty(); +//! +//! // A layer that logs events to a file. +//! let file = File::create("debug.log")?; +//! let debug_log = tracing_subscriber::fmt::layer() +//! .with_writer(Arc::new(file)); +//! +//! // A layer that collects metrics using specific events. +//! let metrics_layer = /* ... */ filter::LevelFilter::INFO; +//! +//! tracing_subscriber::registry() +//! .with( +//! stdout_log +//! // Add an `INFO` filter to the stdout logging layer +//! .with_filter(filter::LevelFilter::INFO) +//! // Combine the filtered `stdout_log` layer with the +//! // `debug_log` layer, producing a new `Layered` layer. +//! .and_then(debug_log) +//! // Add a filter to *both* layers that rejects spans and +//! // events whose targets start with `metrics`. +//! .with_filter(filter::filter_fn(|metadata| { +//! !metadata.target().starts_with("metrics") +//! })) +//! ) +//! .with( +//! // Add a filter to the metrics label that *only* enables +//! // events whose targets start with `metrics`. +//! metrics_layer.with_filter(filter::filter_fn(|metadata| { +//! metadata.target().starts_with("metrics") +//! })) +//! ) +//! .init(); +//! +//! // This event will *only* be recorded by the metrics layer. +//! tracing::info!(target: "metrics::cool_stuff_count", value = 42); +//! +//! // This event will only be seen by the debug log file layer: +//! tracing::debug!("this is a message, and part of a system of messages"); +//! +//! // This event will be seen by both the stdout log layer *and* +//! // the debug log file layer, but not by the metrics layer. +//! tracing::warn!("the message is a warning about danger!"); +//! # Ok(()) } +//! ``` +//! +//! ## Runtime Configuration With Layers +//! +//! In some cases, a particular [`Layer`] may be enabled or disabled based on +//! runtime configuration. This can introduce challenges, because the type of a +//! layered [`Subscriber`] depends on which layers are added to it: if an `if` +//! or `match` expression adds some [`Layer`]s in one branch and other layers +//! in another, the [`Subscriber`] values returned by those branches will have +//! different types. For example, the following _will not_ work: +//! +//! ```compile_fail +//! # fn docs() -> Result<(), Box> { +//! # struct Config { +//! # is_prod: bool, +//! # path: &'static str, +//! # } +//! # let cfg = Config { is_prod: false, path: "debug.log" }; +//! use std::{fs::File, sync::Arc}; +//! use tracing_subscriber::{Registry, prelude::*}; +//! +//! let stdout_log = tracing_subscriber::fmt::layer().pretty(); +//! let subscriber = Registry::default().with(stdout_log); +//! +//! // The compile error will occur here because the if and else +//! // branches have different (and therefore incompatible) types. +//! let subscriber = if cfg.is_prod { +//! let file = File::create(cfg.path)?; +//! let layer = tracing_subscriber::fmt::layer() +//! .json() +//! .with_writer(Arc::new(file)); +//! subscriber.with(layer) +//! } else { +//! subscriber +//! }; +//! +//! tracing::subscriber::set_global_default(subscriber) +//! .expect("Unable to set global subscriber"); +//! # Ok(()) } +//! ``` +//! +//! However, a [`Layer`] wrapped in an [`Option`] [also implements the `Layer` +//! trait][option-impl]. This allows individual layers to be enabled or disabled at +//! runtime while always producing a [`Subscriber`] of the same type. For +//! example: +//! +//! ``` +//! # fn docs() -> Result<(), Box> { +//! # struct Config { +//! # is_prod: bool, +//! # path: &'static str, +//! # } +//! # let cfg = Config { is_prod: false, path: "debug.log" }; +//! use std::{fs::File, sync::Arc}; +//! use tracing_subscriber::{Registry, prelude::*}; +//! +//! let stdout_log = tracing_subscriber::fmt::layer().pretty(); +//! let subscriber = Registry::default().with(stdout_log); +//! +//! // if `cfg.is_prod` is true, also log JSON-formatted logs to a file. +//! let json_log = if cfg.is_prod { +//! let file = File::create(cfg.path)?; +//! let json_log = tracing_subscriber::fmt::layer() +//! .json() +//! .with_writer(Arc::new(file)); +//! Some(json_log) +//! } else { +//! None +//! }; +//! +//! // If `cfg.is_prod` is false, then `json` will be `None`, and this layer +//! // will do nothing. However, the subscriber will still have the same type +//! // regardless of whether the `Option`'s value is `None` or `Some`. +//! let subscriber = subscriber.with(json_log); +//! +//! tracing::subscriber::set_global_default(subscriber) +//! .expect("Unable to set global subscriber"); +//! # Ok(()) } +//! ``` +//! +//! [`Subscriber`]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html +//! [span IDs]: https://docs.rs/tracing-core/latest/tracing_core/span/struct.Id.html +//! [the current span]: Context::current_span +//! [`register_callsite`]: Layer::register_callsite +//! [`enabled`]: Layer::enabled +//! [`on_enter`]: Layer::on_enter +//! [`Layer::register_callsite`]: Layer::register_callsite +//! [`Layer::enabled`]: Layer::enabled +//! [`Interest::never()`]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/struct.Interest.html#method.never +//! [option-impl]: crate::layer::Layer#impl-Layer-for-Option +//! [`Filtered`]: crate::filter::Filtered +//! [`filter`]: crate::filter +//! [`Targets`]: crate::filter::Targets +//! [`FilterFn`]: crate::filter::FilterFn +//! [`DynFilterFn`]: crate::filter::DynFilterFn +//! [level]: tracing_core::Level +//! [`INFO`]: tracing_core::Level::INFO +//! [`DEBUG`]: tracing_core::Level::DEBUG +//! [target]: tracing_core::Metadata::target +//! [`LevelFilter`]: crate::filter::LevelFilter +//! [feat]: crate#feature-flags +use crate::filter; + +use tracing_core::{ + metadata::Metadata, + span, + subscriber::{Interest, Subscriber}, + Event, LevelFilter, +}; + +use core::any::TypeId; + +feature! { + #![feature = "alloc"] + use alloc::boxed::Box; + use core::ops::{Deref, DerefMut}; +} + +mod context; +mod layered; +pub use self::{context::*, layered::*}; + +// The `tests` module is `pub(crate)` because it contains test utilities used by +// other modules. +#[cfg(test)] +pub(crate) mod tests; + +/// A composable handler for `tracing` events. +/// +/// A `Layer` implements a behavior for recording or collecting traces that can +/// be composed together with other `Layer`s to build a [`Subscriber`]. See the +/// [module-level documentation](crate::layer) for details. +/// +/// [`Subscriber`]: tracing_core::Subscriber +#[cfg_attr(docsrs, doc(notable_trait))] +pub trait Layer +where + S: Subscriber, + Self: 'static, +{ + /// Performs late initialization when attaching a `Layer` to a + /// [`Subscriber`]. + /// + /// This is a callback that is called when the `Layer` is added to a + /// [`Subscriber`] (e.g. in [`Layer::with_subscriber`] and + /// [`SubscriberExt::with`]). Since this can only occur before the + /// [`Subscriber`] has been set as the default, both the `Layer` and + /// [`Subscriber`] are passed to this method _mutably_. This gives the + /// `Layer` the opportunity to set any of its own fields with values + /// recieved by method calls on the [`Subscriber`]. + /// + /// For example, [`Filtered`] layers implement `on_layer` to call the + /// [`Subscriber`]'s [`register_filter`] method, and store the returned + /// [`FilterId`] as a field. + /// + /// **Note** In most cases, `Layer` implementations will not need to + /// implement this method. However, in cases where a type implementing + /// `Layer` wraps one or more other types that implement `Layer`, like the + /// [`Layered`] and [`Filtered`] types in this crate, that type MUST ensure + /// that the inner `Layer`s' `on_layer` methods are called. Otherwise, + /// functionality that relies on `on_layer`, such as [per-layer filtering], + /// may not work correctly. + /// + /// [`Filtered`]: crate::filter::Filtered + /// [`register_filter`]: crate::registry::LookupSpan::register_filter + /// [per-layer filtering]: #per-layer-filtering + /// [`FilterId`]: crate::filter::FilterId + fn on_layer(&mut self, subscriber: &mut S) { + let _ = subscriber; + } + + /// Registers a new callsite with this layer, returning whether or not + /// the layer is interested in being notified about the callsite, similarly + /// to [`Subscriber::register_callsite`]. + /// + /// By default, this returns [`Interest::always()`] if [`self.enabled`] returns + /// true, or [`Interest::never()`] if it returns false. + /// + ///
+    /// Note: This method (and 
+    /// Layer::enabled) determine whether a span or event is
+    /// globally enabled, not whether the individual layer will be
+    /// notified about that span or event. This is intended to be used
+    /// by layers that implement filtering for the entire stack. Layers which do
+    /// not wish to be notified about certain spans or events but do not wish to
+    /// globally disable them should ignore those spans or events in their
+    /// on_event,
+    /// on_enter,
+    /// on_exit, and other notification
+    /// methods.
+    /// 
+ /// + /// See [the trait-level documentation] for more information on filtering + /// with `Layer`s. + /// + /// Layers may also implement this method to perform any behaviour that + /// should be run once per callsite. If the layer wishes to use + /// `register_callsite` for per-callsite behaviour, but does not want to + /// globally enable or disable those callsites, it should always return + /// [`Interest::always()`]. + /// + /// [`Interest`]: https://docs.rs/tracing-core/latest/tracing_core/struct.Interest.html + /// [`Subscriber::register_callsite`]: https://docs.rs/tracing-core/latest/tracing_core/trait.Subscriber.html#method.register_callsite + /// [`Interest::never()`]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/struct.Interest.html#method.never + /// [`Interest::always()`]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/struct.Interest.html#method.always + /// [`self.enabled`]: #method.enabled + /// [`Layer::enabled`]: #method.enabled + /// [`on_event`]: #method.on_event + /// [`on_enter`]: #method.on_enter + /// [`on_exit`]: #method.on_exit + /// [the trait-level documentation]: #filtering-with-layers + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + if self.enabled(metadata, Context::none()) { + Interest::always() + } else { + Interest::never() + } + } + + /// Returns `true` if this layer is interested in a span or event with the + /// given `metadata` in the current [`Context`], similarly to + /// [`Subscriber::enabled`]. + /// + /// By default, this always returns `true`, allowing the wrapped subscriber + /// to choose to disable the span. + /// + ///
+    /// Note: This method (and 
+    /// Layer::register_callsite) determine whether a span or event is
+    /// globally enabled, not whether the individual layer will be
+    /// notified about that span or event. This is intended to be used
+    /// by layers that implement filtering for the entire stack. Layers which do
+    /// not wish to be notified about certain spans or events but do not wish to
+    /// globally disable them should ignore those spans or events in their
+    /// on_event,
+    /// on_enter,
+    /// on_exit, and other notification
+    /// methods.
+    /// 
+ /// + /// + /// See [the trait-level documentation] for more information on filtering + /// with `Layer`s. + /// + /// [`Interest`]: https://docs.rs/tracing-core/latest/tracing_core/struct.Interest.html + /// [`Context`]: ../struct.Context.html + /// [`Subscriber::enabled`]: https://docs.rs/tracing-core/latest/tracing_core/trait.Subscriber.html#method.enabled + /// [`Layer::register_callsite`]: #method.register_callsite + /// [`on_event`]: #method.on_event + /// [`on_enter`]: #method.on_enter + /// [`on_exit`]: #method.on_exit + /// [the trait-level documentation]: #filtering-with-layers + fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { + let _ = (metadata, ctx); + true + } + + /// Notifies this layer that a new span was constructed with the given + /// `Attributes` and `Id`. + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { + let _ = (attrs, id, ctx); + } + + // TODO(eliza): do we want this to be a public API? If we end up moving + // filtering layers to a separate trait, we may no longer want `Layer`s to + // be able to participate in max level hinting... + #[doc(hidden)] + fn max_level_hint(&self) -> Option { + None + } + + /// Notifies this layer that a span with the given `Id` recorded the given + /// `values`. + // Note: it's unclear to me why we'd need the current span in `record` (the + // only thing the `Context` type currently provides), but passing it in anyway + // seems like a good future-proofing measure as it may grow other methods later... + fn on_record(&self, _span: &span::Id, _values: &span::Record<'_>, _ctx: Context<'_, S>) {} + + /// Notifies this layer that a span with the ID `span` recorded that it + /// follows from the span with the ID `follows`. + // Note: it's unclear to me why we'd need the current span in `record` (the + // only thing the `Context` type currently provides), but passing it in anyway + // seems like a good future-proofing measure as it may grow other methods later... + fn on_follows_from(&self, _span: &span::Id, _follows: &span::Id, _ctx: Context<'_, S>) {} + + /// Notifies this layer that an event has occurred. + fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, S>) {} + + /// Notifies this layer that a span with the given ID was entered. + fn on_enter(&self, _id: &span::Id, _ctx: Context<'_, S>) {} + + /// Notifies this layer that the span with the given ID was exited. + fn on_exit(&self, _id: &span::Id, _ctx: Context<'_, S>) {} + + /// Notifies this layer that the span with the given ID has been closed. + fn on_close(&self, _id: span::Id, _ctx: Context<'_, S>) {} + + /// Notifies this layer that a span ID has been cloned, and that the + /// subscriber returned a different ID. + fn on_id_change(&self, _old: &span::Id, _new: &span::Id, _ctx: Context<'_, S>) {} + + /// Composes this layer around the given `Layer`, returning a `Layered` + /// struct implementing `Layer`. + /// + /// The returned `Layer` will call the methods on this `Layer` and then + /// those of the new `Layer`, before calling the methods on the subscriber + /// it wraps. For example: + /// + /// ```rust + /// # use tracing_subscriber::layer::Layer; + /// # use tracing_core::Subscriber; + /// pub struct FooLayer { + /// // ... + /// } + /// + /// pub struct BarLayer { + /// // ... + /// } + /// + /// pub struct MySubscriber { + /// // ... + /// } + /// + /// impl Layer for FooLayer { + /// // ... + /// } + /// + /// impl Layer for BarLayer { + /// // ... + /// } + /// + /// # impl FooLayer { + /// # fn new() -> Self { Self {} } + /// # } + /// # impl BarLayer { + /// # fn new() -> Self { Self { }} + /// # } + /// # impl MySubscriber { + /// # fn new() -> Self { Self { }} + /// # } + /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; + /// # impl tracing_core::Subscriber for MySubscriber { + /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } + /// # fn record(&self, _: &Id, _: &Record) {} + /// # fn event(&self, _: &Event) {} + /// # fn record_follows_from(&self, _: &Id, _: &Id) {} + /// # fn enabled(&self, _: &Metadata) -> bool { false } + /// # fn enter(&self, _: &Id) {} + /// # fn exit(&self, _: &Id) {} + /// # } + /// let subscriber = FooLayer::new() + /// .and_then(BarLayer::new()) + /// .with_subscriber(MySubscriber::new()); + /// ``` + /// + /// Multiple layers may be composed in this manner: + /// + /// ```rust + /// # use tracing_subscriber::layer::Layer; + /// # use tracing_core::Subscriber; + /// # pub struct FooLayer {} + /// # pub struct BarLayer {} + /// # pub struct MySubscriber {} + /// # impl Layer for FooLayer {} + /// # impl Layer for BarLayer {} + /// # impl FooLayer { + /// # fn new() -> Self { Self {} } + /// # } + /// # impl BarLayer { + /// # fn new() -> Self { Self { }} + /// # } + /// # impl MySubscriber { + /// # fn new() -> Self { Self { }} + /// # } + /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; + /// # impl tracing_core::Subscriber for MySubscriber { + /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } + /// # fn record(&self, _: &Id, _: &Record) {} + /// # fn event(&self, _: &Event) {} + /// # fn record_follows_from(&self, _: &Id, _: &Id) {} + /// # fn enabled(&self, _: &Metadata) -> bool { false } + /// # fn enter(&self, _: &Id) {} + /// # fn exit(&self, _: &Id) {} + /// # } + /// pub struct BazLayer { + /// // ... + /// } + /// + /// impl Layer for BazLayer { + /// // ... + /// } + /// # impl BazLayer { fn new() -> Self { BazLayer {} } } + /// + /// let subscriber = FooLayer::new() + /// .and_then(BarLayer::new()) + /// .and_then(BazLayer::new()) + /// .with_subscriber(MySubscriber::new()); + /// ``` + fn and_then(self, layer: L) -> Layered + where + L: Layer, + Self: Sized, + { + let inner_has_layer_filter = filter::layer_has_plf(&self); + Layered::new(layer, self, inner_has_layer_filter) + } + + /// Composes this `Layer` with the given [`Subscriber`], returning a + /// `Layered` struct that implements [`Subscriber`]. + /// + /// The returned `Layered` subscriber will call the methods on this `Layer` + /// and then those of the wrapped subscriber. + /// + /// For example: + /// ```rust + /// # use tracing_subscriber::layer::Layer; + /// # use tracing_core::Subscriber; + /// pub struct FooLayer { + /// // ... + /// } + /// + /// pub struct MySubscriber { + /// // ... + /// } + /// + /// impl Layer for FooLayer { + /// // ... + /// } + /// + /// # impl FooLayer { + /// # fn new() -> Self { Self {} } + /// # } + /// # impl MySubscriber { + /// # fn new() -> Self { Self { }} + /// # } + /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata}; + /// # impl tracing_core::Subscriber for MySubscriber { + /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) } + /// # fn record(&self, _: &Id, _: &Record) {} + /// # fn event(&self, _: &tracing_core::Event) {} + /// # fn record_follows_from(&self, _: &Id, _: &Id) {} + /// # fn enabled(&self, _: &Metadata) -> bool { false } + /// # fn enter(&self, _: &Id) {} + /// # fn exit(&self, _: &Id) {} + /// # } + /// let subscriber = FooLayer::new() + /// .with_subscriber(MySubscriber::new()); + ///``` + /// + /// [`Subscriber`]: https://docs.rs/tracing-core/latest/tracing_core/trait.Subscriber.html + fn with_subscriber(mut self, mut inner: S) -> Layered + where + Self: Sized, + { + let inner_has_layer_filter = filter::subscriber_has_plf(&inner); + self.on_layer(&mut inner); + Layered::new(self, inner, inner_has_layer_filter) + } + + /// Combines `self` with a [`Filter`], returning a [`Filtered`] layer. + /// + /// The [`Filter`] will control which spans and events are enabled for + /// this layer. See [the trait-level documentation][plf] for details on + /// per-layer filtering. + /// + /// [`Filtered`]: crate::filter::Filtered + /// [plf]: #per-layer-filtering + #[cfg(all(feature = "registry", feature = "std"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] + fn with_filter(self, filter: F) -> filter::Filtered + where + Self: Sized, + F: Filter, + { + filter::Filtered::new(self, filter) + } + + #[doc(hidden)] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + if id == TypeId::of::() { + Some(self as *const _ as *const ()) + } else { + None + } + } +} + +feature! { + #![all(feature = "registry", feature = "std")] + /// A per-[`Layer`] filter that determines whether a span or event is enabled + /// for an individual layer. + /// + /// See [the module-level documentation][plf] for details on using [`Filter`]s. + /// + /// [plf]: crate::layer#per-layer-filtering + #[cfg_attr(docsrs, doc(notable_trait))] + pub trait Filter { + /// Returns `true` if this layer is interested in a span or event with the + /// given [`Metadata`] in the current [`Context`], similarly to + /// [`Subscriber::enabled`]. + /// + /// If this returns `false`, the span or event will be disabled _for the + /// wrapped [`Layer`]_. Unlike [`Layer::enabled`], the span or event will + /// still be recorded if any _other_ layers choose to enable it. However, + /// the layer [filtered] by this filter will skip recording that span or + /// event. + /// + /// If all layers indicate that they do not wish to see this span or event, + /// it will be disabled. + /// + /// [`metadata`]: tracing_core::Metadata + /// [`Subscriber::enabled`]: tracing_core::Subscriber::enabled + /// [filtered]: crate::filter::Filtered + fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool; + + /// Returns an [`Interest`] indicating whether this layer will [always], + /// [sometimes], or [never] be interested in the given [`Metadata`]. + /// + /// When a given callsite will [always] or [never] be enabled, the results + /// of evaluating the filter may be cached for improved performance. + /// Therefore, if a filter is capable of determining that it will always or + /// never enable a particular callsite, providing an implementation of this + /// function is recommended. + /// + ///
+        /// Note: If a Filter will perform
+        /// dynamic filtering that depends on the current context in which
+        /// a span or event was observered (e.g. only enabling an event when it
+        /// occurs within a particular span), it must return
+        /// Interest::sometimes() from this method. If it returns
+        /// Interest::always() or Interest::never(), the
+        /// enabled method may not be called when a particular instance
+        /// of that span or event is recorded.
+        /// 
+ /// + /// This method is broadly similar to [`Subscriber::register_callsite`]; + /// however, since the returned value represents only the interest of + /// *this* layer, the resulting behavior is somewhat different. + /// + /// If a [`Subscriber`] returns [`Interest::always()`][always] or + /// [`Interest::never()`][never] for a given [`Metadata`], its [`enabled`] + /// method is then *guaranteed* to never be called for that callsite. On the + /// other hand, when a `Filter` returns [`Interest::always()`][always] or + /// [`Interest::never()`][never] for a callsite, _other_ [`Layer`]s may have + /// differing interests in that callsite. If this is the case, the callsite + /// will recieve [`Interest::sometimes()`][sometimes], and the [`enabled`] + /// method will still be called for that callsite when it records a span or + /// event. + /// + /// Returning [`Interest::always()`][always] or [`Interest::never()`][never] from + /// `Filter::callsite_enabled` will permanently enable or disable a + /// callsite (without requiring subsequent calls to [`enabled`]) if and only + /// if the following is true: + /// + /// - all [`Layer`]s that comprise the subscriber include `Filter`s + /// (this includes a tree of [`Layered`] layers that share the same + /// `Filter`) + /// - all those `Filter`s return the same [`Interest`]. + /// + /// For example, if a [`Subscriber`] consists of two [`Filtered`] layers, + /// and both of those layers return [`Interest::never()`][never], that + /// callsite *will* never be enabled, and the [`enabled`] methods of those + /// [`Filter`]s will not be called. + /// + /// ## Default Implementation + /// + /// The default implementation of this method assumes that the + /// `Filter`'s [`enabled`] method _may_ perform dynamic filtering, and + /// returns [`Interest::sometimes()`][sometimes], to ensure that [`enabled`] + /// is called to determine whether a particular _instance_ of the callsite + /// is enabled in the current context. If this is *not* the case, and the + /// `Filter`'s [`enabled`] method will always return the same result + /// for a particular [`Metadata`], this method can be overridden as + /// follows: + /// + /// ``` + /// use tracing_subscriber::layer; + /// use tracing_core::{Metadata, subscriber::Interest}; + /// + /// struct MyFilter { + /// // ... + /// } + /// + /// impl MyFilter { + /// // The actual logic for determining whether a `Metadata` is enabled + /// // must be factored out from the `enabled` method, so that it can be + /// // called without a `Context` (which is not provided to the + /// // `callsite_enabled` method). + /// fn is_enabled(&self, metadata: &Metadata<'_>) -> bool { + /// // ... + /// # drop(metadata); true + /// } + /// } + /// + /// impl layer::Filter for MyFilter { + /// fn enabled(&self, metadata: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool { + /// // Even though we are implementing `callsite_enabled`, we must still provide a + /// // working implementation of `enabled`, as returning `Interest::always()` or + /// // `Interest::never()` will *allow* caching, but will not *guarantee* it. + /// // Other filters may still return `Interest::sometimes()`, so we may be + /// // asked again in `enabled`. + /// self.is_enabled(metadata) + /// } + /// + /// fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { + /// // The result of `self.enabled(metadata, ...)` will always be + /// // the same for any given `Metadata`, so we can convert it into + /// // an `Interest`: + /// if self.is_enabled(metadata) { + /// Interest::always() + /// } else { + /// Interest::never() + /// } + /// } + /// } + /// ``` + /// + /// [`Metadata`]: tracing_core::Metadata + /// [`Interest`]: tracing_core::Interest + /// [always]: tracing_core::Interest::always + /// [sometimes]: tracing_core::Interest::sometimes + /// [never]: tracing_core::Interest::never + /// [`Subscriber::register_callsite`]: tracing_core::Subscriber::register_callsite + /// [`Subscriber`]: tracing_core::Subscriber + /// [`enabled`]: Filter::enabled + /// [`Filtered`]: crate::filter::Filtered + fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { + let _ = meta; + Interest::sometimes() + } + + /// Returns an optional hint of the highest [verbosity level][level] that + /// this `Filter` will enable. + /// + /// If this method returns a [`LevelFilter`], it will be used as a hint to + /// determine the most verbose level that will be enabled. This will allow + /// spans and events which are more verbose than that level to be skipped + /// more efficiently. An implementation of this method is optional, but + /// strongly encouraged. + /// + /// If the maximum level the `Filter` will enable can change over the + /// course of its lifetime, it is free to return a different value from + /// multiple invocations of this method. However, note that changes in the + /// maximum level will **only** be reflected after the callsite [`Interest`] + /// cache is rebuilt, by calling the + /// [`tracing_core::callsite::rebuild_interest_cache`][rebuild] function. + /// Therefore, if the `Filter will change the value returned by this + /// method, it is responsible for ensuring that + /// [`rebuild_interest_cache`][rebuild] is called after the value of the max + /// level changes. + /// + /// ## Default Implementation + /// + /// By default, this method returns `None`, indicating that the maximum + /// level is unknown. + /// + /// [level]: tracing_core::metadata::Level + /// [`LevelFilter`]: crate::filter::LevelFilter + /// [`Interest`]: tracing_core::subscriber::Interest + /// [rebuild]: tracing_core::callsite::rebuild_interest_cache + fn max_level_hint(&self) -> Option { + None + } + } +} + +/// Extension trait adding a `with(Layer)` combinator to `Subscriber`s. +pub trait SubscriberExt: Subscriber + crate::sealed::Sealed { + /// Wraps `self` with the provided `layer`. + fn with(self, layer: L) -> Layered + where + L: Layer, + Self: Sized, + { + layer.with_subscriber(self) + } +} + +/// A layer that does nothing. +#[derive(Clone, Debug, Default)] +pub struct Identity { + _p: (), +} + +// === impl Layer === + +impl Layer for Option +where + L: Layer, + S: Subscriber, +{ + fn on_layer(&mut self, subscriber: &mut S) { + if let Some(ref mut layer) = self { + layer.on_layer(subscriber) + } + } + + #[inline] + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_new_span(attrs, id, ctx) + } + } + + #[inline] + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + match self { + Some(ref inner) => inner.register_callsite(metadata), + None => Interest::always(), + } + } + + #[inline] + fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { + match self { + Some(ref inner) => inner.enabled(metadata, ctx), + None => true, + } + } + + #[inline] + fn max_level_hint(&self) -> Option { + match self { + Some(ref inner) => inner.max_level_hint(), + None => None, + } + } + + #[inline] + fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_record(span, values, ctx); + } + } + + #[inline] + fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_follows_from(span, follows, ctx); + } + } + + #[inline] + fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_event(event, ctx); + } + } + + #[inline] + fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_enter(id, ctx); + } + } + + #[inline] + fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_exit(id, ctx); + } + } + + #[inline] + fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_close(id, ctx); + } + } + + #[inline] + fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { + if let Some(ref inner) = self { + inner.on_id_change(old, new, ctx) + } + } + + #[doc(hidden)] + #[inline] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + if id == TypeId::of::() { + Some(self as *const _ as *const ()) + } else { + self.as_ref().and_then(|inner| inner.downcast_raw(id)) + } + } +} + +feature! { + #![any(feature = "std", feature = "alloc")] + + macro_rules! layer_impl_body { + () => { + #[inline] + fn on_layer(&mut self, subscriber: &mut S) { + self.deref_mut().on_layer(subscriber); + } + + #[inline] + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { + self.deref().on_new_span(attrs, id, ctx) + } + + #[inline] + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + self.deref().register_callsite(metadata) + } + + #[inline] + fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { + self.deref().enabled(metadata, ctx) + } + + #[inline] + fn max_level_hint(&self) -> Option { + self.deref().max_level_hint() + } + + #[inline] + fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { + self.deref().on_record(span, values, ctx) + } + + #[inline] + fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { + self.deref().on_follows_from(span, follows, ctx) + } + + #[inline] + fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { + self.deref().on_event(event, ctx) + } + + #[inline] + fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { + self.deref().on_enter(id, ctx) + } + + #[inline] + fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { + self.deref().on_exit(id, ctx) + } + + #[inline] + fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { + self.deref().on_close(id, ctx) + } + + #[inline] + fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { + self.deref().on_id_change(old, new, ctx) + } + + #[doc(hidden)] + #[inline] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + self.deref().downcast_raw(id) + } + }; + } + + impl Layer for Box + where + L: Layer, + S: Subscriber, + { + layer_impl_body! {} + } + + impl Layer for Box + Send + Sync> + where + S: Subscriber, + { + layer_impl_body! {} + } +} + +// === impl SubscriberExt === + +impl crate::sealed::Sealed for S {} +impl SubscriberExt for S {} + +// === impl Identity === + +impl Layer for Identity {} + +impl Identity { + /// Returns a new `Identity` layer. + pub fn new() -> Self { + Self { _p: () } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/layer/tests.rs b/vendor/tracing-subscriber-0.3.3/src/layer/tests.rs new file mode 100644 index 000000000..d7ad61769 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/layer/tests.rs @@ -0,0 +1,308 @@ +use super::*; +use tracing_core::subscriber::NoSubscriber; + +#[derive(Debug)] +pub(crate) struct NopLayer; +impl Layer for NopLayer {} + +#[allow(dead_code)] +struct NopLayer2; +impl Layer for NopLayer2 {} + +/// A layer that holds a string. +/// +/// Used to test that pointers returned by downcasting are actually valid. +struct StringLayer(&'static str); +impl Layer for StringLayer {} +struct StringLayer2(&'static str); +impl Layer for StringLayer2 {} + +struct StringLayer3(&'static str); +impl Layer for StringLayer3 {} + +pub(crate) struct StringSubscriber(&'static str); + +impl Subscriber for StringSubscriber { + fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { + Interest::never() + } + + fn enabled(&self, _: &Metadata<'_>) -> bool { + false + } + + fn new_span(&self, _: &span::Attributes<'_>) -> span::Id { + span::Id::from_u64(1) + } + + fn record(&self, _: &span::Id, _: &span::Record<'_>) {} + fn record_follows_from(&self, _: &span::Id, _: &span::Id) {} + fn event(&self, _: &Event<'_>) {} + fn enter(&self, _: &span::Id) {} + fn exit(&self, _: &span::Id) {} +} + +fn assert_subscriber(_s: impl Subscriber) {} +fn assert_layer(_l: &impl Layer) {} + +#[test] +fn layer_is_subscriber() { + let s = NopLayer.with_subscriber(NoSubscriber::default()); + assert_subscriber(s) +} + +#[test] +fn two_layers_are_subscriber() { + let s = NopLayer + .and_then(NopLayer) + .with_subscriber(NoSubscriber::default()); + assert_subscriber(s) +} + +#[test] +fn three_layers_are_subscriber() { + let s = NopLayer + .and_then(NopLayer) + .and_then(NopLayer) + .with_subscriber(NoSubscriber::default()); + assert_subscriber(s) +} + +#[test] +fn three_layers_are_layer() { + let layers = NopLayer.and_then(NopLayer).and_then(NopLayer); + assert_layer(&layers); + let _ = layers.with_subscriber(NoSubscriber::default()); +} + +#[test] +#[cfg(feature = "alloc")] +fn box_layer_is_layer() { + use alloc::boxed::Box; + let l: Box + Send + Sync> = Box::new(NopLayer); + assert_layer(&l); + l.with_subscriber(NoSubscriber::default()); +} + +#[test] +fn downcasts_to_subscriber() { + let s = NopLayer + .and_then(NopLayer) + .and_then(NopLayer) + .with_subscriber(StringSubscriber("subscriber")); + let subscriber = + ::downcast_ref::(&s).expect("subscriber should downcast"); + assert_eq!(subscriber.0, "subscriber"); +} + +#[test] +fn downcasts_to_layer() { + let s = StringLayer("layer_1") + .and_then(StringLayer2("layer_2")) + .and_then(StringLayer3("layer_3")) + .with_subscriber(NoSubscriber::default()); + let layer = ::downcast_ref::(&s).expect("layer 1 should downcast"); + assert_eq!(layer.0, "layer_1"); + let layer = + ::downcast_ref::(&s).expect("layer 2 should downcast"); + assert_eq!(layer.0, "layer_2"); + let layer = + ::downcast_ref::(&s).expect("layer 3 should downcast"); + assert_eq!(layer.0, "layer_3"); +} + +#[cfg(all(feature = "registry", feature = "std"))] +mod registry_tests { + use super::*; + use crate::registry::LookupSpan; + + #[test] + fn context_event_span() { + use std::sync::{Arc, Mutex}; + let last_event_span = Arc::new(Mutex::new(None)); + + struct RecordingLayer { + last_event_span: Arc>>, + } + + impl Layer for RecordingLayer + where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + { + fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { + let span = ctx.event_span(event); + *self.last_event_span.lock().unwrap() = span.map(|s| s.name()); + } + } + + tracing::subscriber::with_default( + crate::registry().with(RecordingLayer { + last_event_span: last_event_span.clone(), + }), + || { + tracing::info!("no span"); + assert_eq!(*last_event_span.lock().unwrap(), None); + + let parent = tracing::info_span!("explicit"); + tracing::info!(parent: &parent, "explicit span"); + assert_eq!(*last_event_span.lock().unwrap(), Some("explicit")); + + let _guard = tracing::info_span!("contextual").entered(); + tracing::info!("contextual span"); + assert_eq!(*last_event_span.lock().unwrap(), Some("contextual")); + }, + ); + } + + /// Tests for how max-level hints are calculated when combining layers + /// with and without per-layer filtering. + mod max_level_hints { + + use super::*; + use crate::filter::*; + + #[test] + fn mixed_with_unfiltered() { + let subscriber = crate::registry() + .with(NopLayer) + .with(NopLayer.with_filter(LevelFilter::INFO)); + assert_eq!(subscriber.max_level_hint(), None); + } + + #[test] + fn mixed_with_unfiltered_layered() { + let subscriber = crate::registry().with(NopLayer).with( + NopLayer + .with_filter(LevelFilter::INFO) + .and_then(NopLayer.with_filter(LevelFilter::TRACE)), + ); + assert_eq!(dbg!(subscriber).max_level_hint(), None); + } + + #[test] + fn mixed_interleaved() { + let subscriber = crate::registry() + .with(NopLayer) + .with(NopLayer.with_filter(LevelFilter::INFO)) + .with(NopLayer) + .with(NopLayer.with_filter(LevelFilter::INFO)); + assert_eq!(dbg!(subscriber).max_level_hint(), None); + } + + #[test] + fn mixed_layered() { + let subscriber = crate::registry() + .with(NopLayer.with_filter(LevelFilter::INFO).and_then(NopLayer)) + .with(NopLayer.and_then(NopLayer.with_filter(LevelFilter::INFO))); + assert_eq!(dbg!(subscriber).max_level_hint(), None); + } + + #[test] + fn plf_only_unhinted() { + let subscriber = crate::registry() + .with(NopLayer.with_filter(LevelFilter::INFO)) + .with(NopLayer.with_filter(filter_fn(|_| true))); + assert_eq!(dbg!(subscriber).max_level_hint(), None); + } + + #[test] + fn plf_only_unhinted_nested_outer() { + // if a nested tree of per-layer filters has an _outer_ filter with + // no max level hint, it should return `None`. + let subscriber = crate::registry() + .with( + NopLayer + .with_filter(LevelFilter::INFO) + .and_then(NopLayer.with_filter(LevelFilter::WARN)), + ) + .with( + NopLayer + .with_filter(filter_fn(|_| true)) + .and_then(NopLayer.with_filter(LevelFilter::DEBUG)), + ); + assert_eq!(dbg!(subscriber).max_level_hint(), None); + } + + #[test] + fn plf_only_unhinted_nested_inner() { + // If a nested tree of per-layer filters has an _inner_ filter with + // no max-level hint, but the _outer_ filter has a max level hint, + // it should pick the outer hint. This is because the outer filter + // will disable the spans/events before they make it to the inner + // filter. + let subscriber = dbg!(crate::registry().with( + NopLayer + .with_filter(filter_fn(|_| true)) + .and_then(NopLayer.with_filter(filter_fn(|_| true))) + .with_filter(LevelFilter::INFO), + )); + assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::INFO)); + } + + #[test] + fn unhinted_nested_inner() { + let subscriber = dbg!(crate::registry() + .with(NopLayer.and_then(NopLayer).with_filter(LevelFilter::INFO)) + .with( + NopLayer + .with_filter(filter_fn(|_| true)) + .and_then(NopLayer.with_filter(filter_fn(|_| true))) + .with_filter(LevelFilter::WARN), + )); + assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::INFO)); + } + + #[test] + fn unhinted_nested_inner_mixed() { + let subscriber = dbg!(crate::registry() + .with( + NopLayer + .and_then(NopLayer.with_filter(filter_fn(|_| true))) + .with_filter(LevelFilter::INFO) + ) + .with( + NopLayer + .with_filter(filter_fn(|_| true)) + .and_then(NopLayer.with_filter(filter_fn(|_| true))) + .with_filter(LevelFilter::WARN), + )); + assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::INFO)); + } + + #[test] + fn plf_only_picks_max() { + let subscriber = crate::registry() + .with(NopLayer.with_filter(LevelFilter::WARN)) + .with(NopLayer.with_filter(LevelFilter::DEBUG)); + assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::DEBUG)); + } + + #[test] + fn many_plf_only_picks_max() { + let subscriber = crate::registry() + .with(NopLayer.with_filter(LevelFilter::WARN)) + .with(NopLayer.with_filter(LevelFilter::DEBUG)) + .with(NopLayer.with_filter(LevelFilter::INFO)) + .with(NopLayer.with_filter(LevelFilter::ERROR)); + assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::DEBUG)); + } + + #[test] + fn nested_plf_only_picks_max() { + let subscriber = crate::registry() + .with( + NopLayer.with_filter(LevelFilter::INFO).and_then( + NopLayer + .with_filter(LevelFilter::WARN) + .and_then(NopLayer.with_filter(LevelFilter::DEBUG)), + ), + ) + .with( + NopLayer + .with_filter(LevelFilter::INFO) + .and_then(NopLayer.with_filter(LevelFilter::ERROR)), + ); + assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::DEBUG)); + } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/lib.rs b/vendor/tracing-subscriber-0.3.3/src/lib.rs new file mode 100644 index 000000000..563a86dee --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/lib.rs @@ -0,0 +1,218 @@ +//! Utilities for implementing and composing [`tracing`] subscribers. +//! +//! [`tracing`] is a framework for instrumenting Rust programs to collect +//! scoped, structured, and async-aware diagnostics. The [`Subscriber`] trait +//! represents the functionality necessary to collect this trace data. This +//! crate contains tools for composing subscribers out of smaller units of +//! behaviour, and batteries-included implementations of common subscriber +//! functionality. +//! +//! `tracing-subscriber` is intended for use by both `Subscriber` authors and +//! application authors using `tracing` to instrument their applications. +//! +//! *Compiler support: [requires `rustc` 1.42+][msrv]* +//! +//! [msrv]: #supported-rust-versions +//! +//! ## `Layer`s and `Filter`s +//! +//! The most important component of the `tracing-subscriber` API is the +//! [`Layer`] trait, which provides a composable abstraction for building +//! [`Subscriber`]s. Like the [`Subscriber`] trait, a [`Layer`] defines a +//! particular behavior for collecting trace data. Unlike [`Subscriber`]s, +//! which implement a *complete* strategy for how trace data is collected, +//! [`Layer`]s provide *modular* implementations of specific behaviors. +//! Therefore, they can be [composed together] to form a [`Subscriber`] which is +//! capable of recording traces in a variety of ways. See the [`layer` module's +//! documentation][layer] for details on using [`Layer`]s. +//! +//! In addition, the [`Filter`] trait defines an interface for filtering what +//! spans and events are recorded by a particular layer. This allows different +//! [`Layer`]s to handle separate subsets of the trace data emitted by a +//! program. See the [documentation on per-layer filtering][plf] for more +//! information on using [`Filter`]s. +//! +//! [`Layer`]: crate::layer::Layer +//! [composed together]: crate::layer#composing-layers +//! [layer]: crate::layer +//! [`Filter`]: crate::layer::Filter +//! [plf]: crate::layer#per-layer-filtering +//! +//! ## Included Subscribers +//! +//! The following `Subscriber`s are provided for application authors: +//! +//! - [`fmt`] - Formats and logs tracing data (requires the `fmt` feature flag) +//! +//! ## Feature Flags +//! +//! - `std`: Enables APIs that depend on the on the Rust standard library +//! (enabled by default). +//! - `alloc`: Depend on [`liballoc`] (enabled by "std"). +//! - `env-filter`: Enables the [`EnvFilter`] type, which implements filtering +//! similar to the [`env_logger` crate]. **Requires "std"**. +//! - `fmt`: Enables the [`fmt`] module, which provides a subscriber +//! implementation for printing formatted representations of trace events. +//! Enabled by default. **Requires "std"**. +//! - `ansi`: Enables `fmt` support for ANSI terminal colors. Enabled by +//! default. +//! - `registry`: enables the [`registry`] module. Enabled by default. +//! **Requires "std"**. +//! - `json`: Enables `fmt` support for JSON output. In JSON output, the ANSI +//! feature does nothing. **Requires "fmt" and "std"**. +//! - [`local-time`]: Enables local time formatting when using the [`time` +//! crate]'s timestamp formatters with the `fmt` subscriber. +//! +//! ### Optional Dependencies +//! +//! - [`tracing-log`]: Enables better formatting for events emitted by `log` +//! macros in the `fmt` subscriber. Enabled by default. +//! - [`time`][`time` crate]: Enables support for using the [`time` crate] for timestamp +//! formatting in the `fmt` subscriber. +//! - [`smallvec`]: Causes the `EnvFilter` type to use the `smallvec` crate (rather +//! than `Vec`) as a performance optimization. Enabled by default. +//! - [`parking_lot`]: Use the `parking_lot` crate's `RwLock` implementation +//! rather than the Rust standard library's implementation. +//! +//! ### `no_std` Support +//! +//! In embedded systems and other bare-metal applications, `tracing` can be +//! used without requiring the Rust standard library, although some features are +//! disabled. Although most of the APIs provided by `tracing-subscriber`, such +//! as [`fmt`] and [`EnvFilter`], require the standard library, some +//! functionality, such as the [`Subscriber`] trait, can still be used in +//! `no_std` environments. +//! +//! The dependency on the standard library is controlled by two crate feature +//! flags, "std", which enables the dependency on [`libstd`], and "alloc", which +//! enables the dependency on [`liballoc`] (and is enabled by the "std" +//! feature). These features are enabled by default, but `no_std` users can +//! disable them using: +//! +//! ```toml +//! # Cargo.toml +//! tracing-subscriber = { version = "0.3", default-features = false } +//! ``` +//! +//! Additional APIs are available when [`liballoc`] is available. To enable +//! `liballoc` but not `std`, use: +//! +//! ```toml +//! # Cargo.toml +//! tracing-subscriber = { version = "0.3", default-features = false, features = ["alloc"] } +//! ``` +//! +//! ## Supported Rust Versions +//! +//! Tracing is built against the latest stable release. The minimum supported +//! version is 1.42. The current Tracing version is not guaranteed to build on +//! Rust versions earlier than the minimum supported version. +//! +//! Tracing follows the same compiler support policies as the rest of the Tokio +//! project. The current stable Rust compiler and the three most recent minor +//! versions before it will always be supported. For example, if the current +//! stable compiler version is 1.45, the minimum supported version will not be +//! increased past 1.42, three minor versions prior. Increasing the minimum +//! supported compiler version is not considered a semver breaking change as +//! long as doing so complies with this policy. +//! +//! [`tracing`]: https://docs.rs/tracing/latest/tracing/ +//! [`Subscriber`]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html +//! [`EnvFilter`]: filter/struct.EnvFilter.html +//! [`fmt`]: fmt/index.html +//! [`tracing-log`]: https://crates.io/crates/tracing-log +//! [`smallvec`]: https://crates.io/crates/smallvec +//! [`env_logger` crate]: https://crates.io/crates/env_logger +//! [`parking_lot`]: https://crates.io/crates/parking_lot +//! [`time` crate]: https://crates.io/crates/time +//! [`liballoc`]: https://doc.rust-lang.org/alloc/index.html +#![doc(html_root_url = "https://docs.rs/tracing-subscriber/0.3.1")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png", + issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/" +)] +#![cfg_attr( + docsrs, + // Allows displaying cfgs/feature flags in the documentation. + feature(doc_cfg), + // Allows adding traits to RustDoc's list of "notable traits" + feature(doc_notable_trait), + // Fail the docs build if any intra-docs links are broken + deny(rustdoc::broken_intra_doc_links), +)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + unreachable_pub, + bad_style, + const_err, + dead_code, + improper_ctypes, + non_shorthand_field_patterns, + no_mangle_generic_items, + overflowing_literals, + path_statements, + patterns_in_fns_without_body, + private_in_public, + unconditional_recursion, + unused, + unused_allocation, + unused_comparisons, + unused_parens, + while_true +)] +// Using struct update syntax when a struct has no additional fields avoids +// a potential source change if additional fields are added to the struct in the +// future, reducing diff noise. Allow this even though clippy considers it +// "needless". +#![allow(clippy::needless_update)] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[macro_use] +mod macros; + +pub mod field; +pub mod filter; +pub mod prelude; +pub mod registry; + +pub mod layer; +pub mod util; + +feature! { + #![feature = "std"] + pub mod reload; + pub(crate) mod sync; +} + +feature! { + #![all(feature = "fmt", feature = "std")] + pub mod fmt; + pub use fmt::fmt; + pub use fmt::Subscriber as FmtSubscriber; +} + +feature! { + #![all(feature = "env-filter", feature = "std")] + pub use filter::EnvFilter; +} + +pub use layer::Layer; + +feature! { + #![all(feature = "registry", feature = "std")] + pub use registry::Registry; + + /// + pub fn registry() -> Registry { + Registry::default() + } +} + +mod sealed { + pub trait Sealed {} +} diff --git a/vendor/tracing-subscriber-0.3.3/src/macros.rs b/vendor/tracing-subscriber-0.3.3/src/macros.rs new file mode 100644 index 000000000..81351132f --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/macros.rs @@ -0,0 +1,28 @@ +#[cfg(feature = "std")] +macro_rules! try_lock { + ($lock:expr) => { + try_lock!($lock, else return) + }; + ($lock:expr, else $els:expr) => { + if let Ok(l) = $lock { + l + } else if std::thread::panicking() { + $els + } else { + panic!("lock poisoned") + } + }; +} + +macro_rules! feature { + ( + #![$meta:meta] + $($item:item)* + ) => { + $( + #[cfg($meta)] + #[cfg_attr(docsrs, doc(cfg($meta)))] + $item + )* + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/prelude.rs b/vendor/tracing-subscriber-0.3.3/src/prelude.rs new file mode 100644 index 000000000..c2230907b --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/prelude.rs @@ -0,0 +1,19 @@ +//! The `tracing-subscriber` prelude. +//! +//! This brings into scope a number of extension traits that define methods on +//! types defined here and in other crates. + +pub use crate::field::{ + MakeExt as __tracing_subscriber_field_MakeExt, + RecordFields as __tracing_subscriber_field_RecordFields, +}; +pub use crate::layer::{ + Layer as __tracing_subscriber_Layer, SubscriberExt as __tracing_subscriber_SubscriberExt, +}; + +pub use crate::util::SubscriberInitExt as _; + +feature! { + #![all(feature = "fmt", feature = "std")] + pub use crate::fmt::writer::MakeWriterExt as _; +} diff --git a/vendor/tracing-subscriber-0.3.3/src/registry/extensions.rs b/vendor/tracing-subscriber-0.3.3/src/registry/extensions.rs new file mode 100644 index 000000000..899e1549f --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/registry/extensions.rs @@ -0,0 +1,274 @@ +// taken from https://github.com/hyperium/http/blob/master/src/extensions.rs. + +use crate::sync::{RwLockReadGuard, RwLockWriteGuard}; +use std::{ + any::{Any, TypeId}, + collections::HashMap, + fmt, + hash::{BuildHasherDefault, Hasher}, +}; + +#[allow(warnings)] +type AnyMap = HashMap, BuildHasherDefault>; + +/// With TypeIds as keys, there's no need to hash them. They are already hashes +/// themselves, coming from the compiler. The IdHasher holds the u64 of +/// the TypeId, and then returns it, instead of doing any bit fiddling. +#[derive(Default, Debug)] +struct IdHasher(u64); + +impl Hasher for IdHasher { + fn write(&mut self, _: &[u8]) { + unreachable!("TypeId calls write_u64"); + } + + #[inline] + fn write_u64(&mut self, id: u64) { + self.0 = id; + } + + #[inline] + fn finish(&self) -> u64 { + self.0 + } +} + +/// An immutable, read-only reference to a Span's extensions. +#[derive(Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub struct Extensions<'a> { + inner: RwLockReadGuard<'a, ExtensionsInner>, +} + +impl<'a> Extensions<'a> { + #[cfg(feature = "registry")] + pub(crate) fn new(inner: RwLockReadGuard<'a, ExtensionsInner>) -> Self { + Self { inner } + } + + /// Immutably borrows a type previously inserted into this `Extensions`. + pub fn get(&self) -> Option<&T> { + self.inner.get::() + } +} + +/// An mutable reference to a Span's extensions. +#[derive(Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub struct ExtensionsMut<'a> { + inner: RwLockWriteGuard<'a, ExtensionsInner>, +} + +impl<'a> ExtensionsMut<'a> { + #[cfg(feature = "registry")] + pub(crate) fn new(inner: RwLockWriteGuard<'a, ExtensionsInner>) -> Self { + Self { inner } + } + + /// Insert a type into this `Extensions`. + /// + /// Note that extensions are _not_ + /// `Layer`-specific—they are _span_-specific. This means that + /// other layers can access and mutate extensions that + /// a different Layer recorded. For example, an application might + /// have a layer that records execution timings, alongside a layer + /// that reports spans and events to a distributed + /// tracing system that requires timestamps for spans. + /// Ideally, if one layer records a timestamp _x_, the other layer + /// should be able to reuse timestamp _x_. + /// + /// Therefore, extensions should generally be newtypes, rather than common + /// types like [`String`](https://doc.rust-lang.org/std/string/struct.String.html), to avoid accidental + /// cross-`Layer` clobbering. + /// + /// ## Panics + /// + /// If `T` is already present in `Extensions`, then this method will panic. + pub fn insert(&mut self, val: T) { + assert!(self.replace(val).is_none()) + } + + /// Replaces an existing `T` into this extensions. + /// + /// If `T` is not present, `Option::None` will be returned. + pub fn replace(&mut self, val: T) -> Option { + self.inner.insert(val) + } + + /// Get a mutable reference to a type previously inserted on this `ExtensionsMut`. + pub fn get_mut(&mut self) -> Option<&mut T> { + self.inner.get_mut::() + } + + /// Remove a type from this `Extensions`. + /// + /// If a extension of this type existed, it will be returned. + pub fn remove(&mut self) -> Option { + self.inner.remove::() + } +} + +/// A type map of span extensions. +/// +/// [ExtensionsInner] is used by `SpanData` to store and +/// span-specific data. A given `Layer` can read and write +/// data that it is interested in recording and emitting. +#[derive(Default)] +pub(crate) struct ExtensionsInner { + map: AnyMap, +} + +impl ExtensionsInner { + /// Create an empty `Extensions`. + #[cfg(any(test, feature = "registry"))] + #[inline] + #[cfg(any(test, feature = "registry"))] + pub(crate) fn new() -> ExtensionsInner { + ExtensionsInner { + map: AnyMap::default(), + } + } + + /// Insert a type into this `Extensions`. + /// + /// If a extension of this type already existed, it will + /// be returned. + pub(crate) fn insert(&mut self, val: T) -> Option { + self.map + .insert(TypeId::of::(), Box::new(val)) + .and_then(|boxed| { + #[allow(warnings)] + { + (boxed as Box) + .downcast() + .ok() + .map(|boxed| *boxed) + } + }) + } + + /// Get a reference to a type previously inserted on this `Extensions`. + pub(crate) fn get(&self) -> Option<&T> { + self.map + .get(&TypeId::of::()) + .and_then(|boxed| (&**boxed as &(dyn Any + 'static)).downcast_ref()) + } + + /// Get a mutable reference to a type previously inserted on this `Extensions`. + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + self.map + .get_mut(&TypeId::of::()) + .and_then(|boxed| (&mut **boxed as &mut (dyn Any + 'static)).downcast_mut()) + } + + /// Remove a type from this `Extensions`. + /// + /// If a extension of this type existed, it will be returned. + pub(crate) fn remove(&mut self) -> Option { + self.map.remove(&TypeId::of::()).and_then(|boxed| { + #[allow(warnings)] + { + (boxed as Box) + .downcast() + .ok() + .map(|boxed| *boxed) + } + }) + } + + /// Clear the `ExtensionsInner` in-place, dropping any elements in the map but + /// retaining allocated capacity. + /// + /// This permits the hash map allocation to be pooled by the registry so + /// that future spans will not need to allocate new hashmaps. + #[cfg(any(test, feature = "registry"))] + pub(crate) fn clear(&mut self) { + self.map.clear(); + } +} + +impl fmt::Debug for ExtensionsInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Extensions") + .field("len", &self.map.len()) + .field("capacity", &self.map.capacity()) + .finish() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, PartialEq)] + struct MyType(i32); + + #[test] + fn test_extensions() { + let mut extensions = ExtensionsInner::new(); + + extensions.insert(5i32); + extensions.insert(MyType(10)); + + assert_eq!(extensions.get(), Some(&5i32)); + assert_eq!(extensions.get_mut(), Some(&mut 5i32)); + + assert_eq!(extensions.remove::(), Some(5i32)); + assert!(extensions.get::().is_none()); + + assert_eq!(extensions.get::(), None); + assert_eq!(extensions.get(), Some(&MyType(10))); + } + + #[test] + fn clear_retains_capacity() { + let mut extensions = ExtensionsInner::new(); + extensions.insert(5i32); + extensions.insert(MyType(10)); + extensions.insert(true); + + assert_eq!(extensions.map.len(), 3); + let prev_capacity = extensions.map.capacity(); + extensions.clear(); + + assert_eq!( + extensions.map.len(), + 0, + "after clear(), extensions map should have length 0" + ); + assert_eq!( + extensions.map.capacity(), + prev_capacity, + "after clear(), extensions map should retain prior capacity" + ); + } + + #[test] + fn clear_drops_elements() { + use std::sync::Arc; + struct DropMePlease(Arc<()>); + struct DropMeTooPlease(Arc<()>); + + let mut extensions = ExtensionsInner::new(); + let val1 = DropMePlease(Arc::new(())); + let val2 = DropMeTooPlease(Arc::new(())); + + let val1_dropped = Arc::downgrade(&val1.0); + let val2_dropped = Arc::downgrade(&val2.0); + extensions.insert(val1); + extensions.insert(val2); + + assert!(val1_dropped.upgrade().is_some()); + assert!(val2_dropped.upgrade().is_some()); + + extensions.clear(); + assert!( + val1_dropped.upgrade().is_none(), + "after clear(), val1 should be dropped" + ); + assert!( + val2_dropped.upgrade().is_none(), + "after clear(), val2 should be dropped" + ); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/registry/mod.rs b/vendor/tracing-subscriber-0.3.3/src/registry/mod.rs new file mode 100644 index 000000000..f3b77b6a9 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/registry/mod.rs @@ -0,0 +1,604 @@ +//! Storage for span data shared by multiple [`Layer`]s. +//! +//! ## Using the Span Registry +//! +//! This module provides the [`Registry`] type, a [`Subscriber`] implementation +//! which tracks per-span data and exposes it to [`Layer`]s. When a `Registry` +//! is used as the base `Subscriber` of a `Layer` stack, the +//! [`layer::Context`][ctx] type will provide methods allowing `Layer`s to +//! [look up span data][lookup] stored in the registry. While [`Registry`] is a +//! reasonable default for storing spans and events, other stores that implement +//! [`LookupSpan`] and [`Subscriber`] themselves (with [`SpanData`] implemented +//! by the per-span data they store) can be used as a drop-in replacement. +//! +//! For example, we might create a `Registry` and add multiple `Layer`s like so: +//! ```rust +//! use tracing_subscriber::{registry::Registry, Layer, prelude::*}; +//! # use tracing_core::Subscriber; +//! # pub struct FooLayer {} +//! # pub struct BarLayer {} +//! # impl Layer for FooLayer {} +//! # impl Layer for BarLayer {} +//! # impl FooLayer { +//! # fn new() -> Self { Self {} } +//! # } +//! # impl BarLayer { +//! # fn new() -> Self { Self {} } +//! # } +//! +//! let subscriber = Registry::default() +//! .with(FooLayer::new()) +//! .with(BarLayer::new()); +//! ``` +//! +//! If a type implementing `Layer` depends on the functionality of a `Registry` +//! implementation, it should bound its `Subscriber` type parameter with the +//! [`LookupSpan`] trait, like so: +//! +//! ```rust +//! use tracing_subscriber::{registry, Layer}; +//! use tracing_core::Subscriber; +//! +//! pub struct MyLayer { +//! // ... +//! } +//! +//! impl Layer for MyLayer +//! where +//! S: Subscriber + for<'a> registry::LookupSpan<'a>, +//! { +//! // ... +//! } +//! ``` +//! When this bound is added, the `Layer` implementation will be guaranteed +//! access to the [`Context`][ctx] methods, such as [`Context::span`][lookup], that +//! require the root subscriber to be a registry. +//! +//! [`Layer`]: crate::layer::Layer +//! [`Subscriber`]: +//! https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html +//! [ctx]: crate::layer::Context +//! [lookup]: crate::layer::Context::span() +use tracing_core::{field::FieldSet, span::Id, Metadata}; + +feature! { + #![feature = "std"] + /// A module containing a type map of span extensions. + mod extensions; + pub use extensions::{Extensions, ExtensionsMut}; + +} + +feature! { + #![all(feature = "registry", feature = "std")] + + mod sharded; + mod stack; + + pub use sharded::Data; + pub use sharded::Registry; + + use crate::filter::FilterId; +} + +/// Provides access to stored span data. +/// +/// Subscribers which store span data and associate it with span IDs should +/// implement this trait; if they do, any [`Layer`]s wrapping them can look up +/// metadata via the [`Context`] type's [`span()`] method. +/// +/// [`Layer`]: ../layer/trait.Layer.html +/// [`Context`]: ../layer/struct.Context.html +/// [`span()`]: ../layer/struct.Context.html#method.span +pub trait LookupSpan<'a> { + /// The type of span data stored in this registry. + type Data: SpanData<'a>; + + /// Returns the [`SpanData`] for a given `Id`, if it exists. + /// + ///
+    /// Note: users of the LookupSpan trait should
+    /// typically call the span method rather
+    /// than this method. The span method is implemented by
+    /// calling span_data, but returns a reference which is
+    /// capable of performing more sophisiticated queries.
+    /// 
+ /// + /// [`SpanData`]: trait.SpanData.html + fn span_data(&'a self, id: &Id) -> Option; + + /// Returns a [`SpanRef`] for the span with the given `Id`, if it exists. + /// + /// A `SpanRef` is similar to [`SpanData`], but it allows performing + /// additional lookups against the registryr that stores the wrapped data. + /// + /// In general, _users_ of the `LookupSpan` trait should use this method + /// rather than the [`span_data`] method; while _implementors_ of this trait + /// should only implement `span_data`. + /// + /// [`SpanRef`]: struct.SpanRef.html + /// [`SpanData`]: trait.SpanData.html + /// [`span_data`]: #method.span_data + fn span(&'a self, id: &Id) -> Option> + where + Self: Sized, + { + let data = self.span_data(id)?; + Some(SpanRef { + registry: self, + data, + #[cfg(feature = "registry")] + filter: FilterId::none(), + }) + } + + /// Registers a [`Filter`] for [per-layer filtering] with this + /// [`Subscriber`]. + /// + /// The [`Filter`] can then use the returned [`FilterId`] to + /// [check if it previously enabled a span][check]. + /// + /// # Panics + /// + /// If this `Subscriber` does not support [per-layer filtering]. + /// + /// [`Filter`]: crate::layer::Filter + /// [per-layer filtering]: crate::layer::Layer#per-layer-filtering + /// [`Subscriber`]: tracing_core::Subscriber + /// [`FilterId`]: crate::filter::FilterId + /// [check]: SpanData::is_enabled_for + #[cfg(feature = "registry")] + #[cfg_attr(docsrs, doc(cfg(feature = "registry")))] + fn register_filter(&mut self) -> FilterId { + panic!( + "{} does not currently support filters", + std::any::type_name::() + ) + } +} + +/// A stored representation of data associated with a span. +pub trait SpanData<'a> { + /// Returns this span's ID. + fn id(&self) -> Id; + + /// Returns a reference to the span's `Metadata`. + fn metadata(&self) -> &'static Metadata<'static>; + + /// Returns a reference to the ID + fn parent(&self) -> Option<&Id>; + + /// Returns a reference to this span's `Extensions`. + /// + /// The extensions may be used by `Layer`s to store additional data + /// describing the span. + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + fn extensions(&self) -> Extensions<'_>; + + /// Returns a mutable reference to this span's `Extensions`. + /// + /// The extensions may be used by `Layer`s to store additional data + /// describing the span. + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + fn extensions_mut(&self) -> ExtensionsMut<'_>; + + /// Returns `true` if this span is enabled for the [per-layer filter][plf] + /// corresponding to the provided [`FilterId`]. + /// + /// ## Default Implementation + /// + /// By default, this method assumes that the [`LookupSpan`] implementation + /// does not support [per-layer filtering][plf], and always returns `true`. + /// + /// [plf]: crate::layer::Layer#per-layer-filtering + /// [`FilterId`]: crate::filter::FilterId + #[cfg(feature = "registry")] + #[cfg_attr(docsrs, doc(cfg(feature = "registry")))] + fn is_enabled_for(&self, filter: FilterId) -> bool { + let _ = filter; + true + } +} + +/// A reference to [span data] and the associated [registry]. +/// +/// This type implements all the same methods as [`SpanData`][span data], and +/// provides additional methods for querying the registry based on values from +/// the span. +/// +/// [span data]: trait.SpanData.html +/// [registry]: trait.LookupSpan.html +#[derive(Debug)] +pub struct SpanRef<'a, R: LookupSpan<'a>> { + registry: &'a R, + data: R::Data, + + #[cfg(feature = "registry")] + filter: FilterId, +} + +/// An iterator over the parents of a span, ordered from leaf to root. +/// +/// This is returned by the [`SpanRef::scope`] method. +#[derive(Debug)] +pub struct Scope<'a, R> { + registry: &'a R, + next: Option, + + #[cfg(all(feature = "registry", feature = "std"))] + filter: FilterId, +} + +feature! { + #![any(feature = "alloc", feature = "std")] + + #[cfg(not(feature = "smallvec"))] + use alloc::vec::{self, Vec}; + + use core::{fmt,iter}; + + /// An iterator over the parents of a span, ordered from root to leaf. + /// + /// This is returned by the [`Scope::from_root`] method. + pub struct ScopeFromRoot<'a, R> + where + R: LookupSpan<'a>, + { + #[cfg(feature = "smallvec")] + spans: iter::Rev>>, + #[cfg(not(feature = "smallvec"))] + spans: iter::Rev>>, + } + + #[cfg(feature = "smallvec")] + type SpanRefVecArray<'span, L> = [SpanRef<'span, L>; 16]; + + impl<'a, R> Scope<'a, R> + where + R: LookupSpan<'a>, + { + /// Flips the order of the iterator, so that it is ordered from root to leaf. + /// + /// The iterator will first return the root span, then that span's immediate child, + /// and so on until it finally returns the span that [`SpanRef::scope`] was called on. + /// + /// If any items were consumed from the [`Scope`] before calling this method then they + /// will *not* be returned from the [`ScopeFromRoot`]. + /// + /// **Note**: this will allocate if there are many spans remaining, or if the + /// "smallvec" feature flag is not enabled. + #[allow(clippy::wrong_self_convention)] + pub fn from_root(self) -> ScopeFromRoot<'a, R> { + #[cfg(feature = "smallvec")] + type Buf = smallvec::SmallVec; + #[cfg(not(feature = "smallvec"))] + type Buf = Vec; + ScopeFromRoot { + spans: self.collect::>().into_iter().rev(), + } + } + } + + impl<'a, R> Iterator for ScopeFromRoot<'a, R> + where + R: LookupSpan<'a>, + { + type Item = SpanRef<'a, R>; + + #[inline] + fn next(&mut self) -> Option { + self.spans.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.spans.size_hint() + } + } + + impl<'a, R> fmt::Debug for ScopeFromRoot<'a, R> + where + R: LookupSpan<'a>, + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("ScopeFromRoot { .. }") + } + } +} + +impl<'a, R> Iterator for Scope<'a, R> +where + R: LookupSpan<'a>, +{ + type Item = SpanRef<'a, R>; + + fn next(&mut self) -> Option { + loop { + let curr = self.registry.span(self.next.as_ref()?)?; + + #[cfg(all(feature = "registry", feature = "std"))] + let curr = curr.with_filter(self.filter); + self.next = curr.data.parent().cloned(); + + // If the `Scope` is filtered, check if the current span is enabled + // by the selected filter ID. + + #[cfg(all(feature = "registry", feature = "std"))] + { + if !curr.is_enabled_for(self.filter) { + // The current span in the chain is disabled for this + // filter. Try its parent. + continue; + } + } + + return Some(curr); + } + } +} + +impl<'a, R> SpanRef<'a, R> +where + R: LookupSpan<'a>, +{ + /// Returns this span's ID. + pub fn id(&self) -> Id { + self.data.id() + } + + /// Returns a static reference to the span's metadata. + pub fn metadata(&self) -> &'static Metadata<'static> { + self.data.metadata() + } + + /// Returns the span's name, + pub fn name(&self) -> &'static str { + self.data.metadata().name() + } + + /// Returns a list of [fields] defined by the span. + /// + /// [fields]: https://docs.rs/tracing-core/latest/tracing_core/field/index.html + pub fn fields(&self) -> &FieldSet { + self.data.metadata().fields() + } + + /// Returns a `SpanRef` describing this span's parent, or `None` if this + /// span is the root of its trace tree. + pub fn parent(&self) -> Option { + let id = self.data.parent()?; + let data = self.registry.span_data(id)?; + + #[cfg(all(feature = "registry", feature = "std"))] + { + // move these into mut bindings if the registry feature is enabled, + // since they may be mutated in the loop. + let mut data = data; + loop { + // Is this parent enabled by our filter? + if data.is_enabled_for(self.filter) { + return Some(Self { + registry: self.registry, + filter: self.filter, + data, + }); + } + + // It's not enabled. If the disabled span has a parent, try that! + let id = data.parent()?; + data = self.registry.span_data(id)?; + } + } + + #[cfg(not(all(feature = "registry", feature = "std")))] + Some(Self { + registry: self.registry, + data, + }) + } + + /// Returns an iterator over all parents of this span, starting with this span, + /// ordered from leaf to root. + /// + /// The iterator will first return the span, then the span's immediate parent, + /// followed by that span's parent, and so on, until it reaches a root span. + /// + /// ```rust + /// use tracing::{span, Subscriber}; + /// use tracing_subscriber::{ + /// layer::{Context, Layer}, + /// prelude::*, + /// registry::LookupSpan, + /// }; + /// + /// struct PrintingLayer; + /// impl Layer for PrintingLayer + /// where + /// S: Subscriber + for<'lookup> LookupSpan<'lookup>, + /// { + /// fn on_enter(&self, id: &span::Id, ctx: Context) { + /// let span = ctx.span(id).unwrap(); + /// let scope = span.scope().map(|span| span.name()).collect::>(); + /// println!("Entering span: {:?}", scope); + /// } + /// } + /// + /// tracing::subscriber::with_default(tracing_subscriber::registry().with(PrintingLayer), || { + /// let _root = tracing::info_span!("root").entered(); + /// // Prints: Entering span: ["root"] + /// let _child = tracing::info_span!("child").entered(); + /// // Prints: Entering span: ["child", "root"] + /// let _leaf = tracing::info_span!("leaf").entered(); + /// // Prints: Entering span: ["leaf", "child", "root"] + /// }); + /// ``` + /// + /// If the opposite order (from the root to this span) is desired, calling [`Scope::from_root`] on + /// the returned iterator reverses the order. + /// + /// ```rust + /// # use tracing::{span, Subscriber}; + /// # use tracing_subscriber::{ + /// # layer::{Context, Layer}, + /// # prelude::*, + /// # registry::LookupSpan, + /// # }; + /// # struct PrintingLayer; + /// impl Layer for PrintingLayer + /// where + /// S: Subscriber + for<'lookup> LookupSpan<'lookup>, + /// { + /// fn on_enter(&self, id: &span::Id, ctx: Context) { + /// let span = ctx.span(id).unwrap(); + /// let scope = span.scope().from_root().map(|span| span.name()).collect::>(); + /// println!("Entering span: {:?}", scope); + /// } + /// } + /// + /// tracing::subscriber::with_default(tracing_subscriber::registry().with(PrintingLayer), || { + /// let _root = tracing::info_span!("root").entered(); + /// // Prints: Entering span: ["root"] + /// let _child = tracing::info_span!("child").entered(); + /// // Prints: Entering span: ["root", "child"] + /// let _leaf = tracing::info_span!("leaf").entered(); + /// // Prints: Entering span: ["root", "child", "leaf"] + /// }); + /// ``` + pub fn scope(&self) -> Scope<'a, R> { + Scope { + registry: self.registry, + next: Some(self.id()), + + #[cfg(feature = "registry")] + filter: self.filter, + } + } + + /// Returns a reference to this span's `Extensions`. + /// + /// The extensions may be used by `Layer`s to store additional data + /// describing the span. + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + pub fn extensions(&self) -> Extensions<'_> { + self.data.extensions() + } + + /// Returns a mutable reference to this span's `Extensions`. + /// + /// The extensions may be used by `Layer`s to store additional data + /// describing the span. + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + pub fn extensions_mut(&self) -> ExtensionsMut<'_> { + self.data.extensions_mut() + } + + #[cfg(all(feature = "registry", feature = "std"))] + pub(crate) fn try_with_filter(self, filter: FilterId) -> Option { + if self.is_enabled_for(filter) { + return Some(self.with_filter(filter)); + } + + None + } + + #[inline] + #[cfg(all(feature = "registry", feature = "std"))] + pub(crate) fn is_enabled_for(&self, filter: FilterId) -> bool { + self.data.is_enabled_for(filter) + } + + #[inline] + #[cfg(all(feature = "registry", feature = "std"))] + fn with_filter(self, filter: FilterId) -> Self { + Self { filter, ..self } + } +} + +#[cfg(all(test, feature = "registry", feature = "std"))] +mod tests { + use crate::{ + layer::{Context, Layer}, + prelude::*, + registry::LookupSpan, + }; + use std::sync::{Arc, Mutex}; + use tracing::{span, Subscriber}; + + #[test] + fn spanref_scope_iteration_order() { + let last_entered_scope = Arc::new(Mutex::new(Vec::new())); + + #[derive(Default)] + struct PrintingLayer { + last_entered_scope: Arc>>, + } + + impl Layer for PrintingLayer + where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + { + fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { + let span = ctx.span(id).unwrap(); + let scope = span.scope().map(|span| span.name()).collect::>(); + *self.last_entered_scope.lock().unwrap() = scope; + } + } + + let _guard = tracing::subscriber::set_default(crate::registry().with(PrintingLayer { + last_entered_scope: last_entered_scope.clone(), + })); + + let _root = tracing::info_span!("root").entered(); + assert_eq!(&*last_entered_scope.lock().unwrap(), &["root"]); + let _child = tracing::info_span!("child").entered(); + assert_eq!(&*last_entered_scope.lock().unwrap(), &["child", "root"]); + let _leaf = tracing::info_span!("leaf").entered(); + assert_eq!( + &*last_entered_scope.lock().unwrap(), + &["leaf", "child", "root"] + ); + } + + #[test] + fn spanref_scope_fromroot_iteration_order() { + let last_entered_scope = Arc::new(Mutex::new(Vec::new())); + + #[derive(Default)] + struct PrintingLayer { + last_entered_scope: Arc>>, + } + + impl Layer for PrintingLayer + where + S: Subscriber + for<'lookup> LookupSpan<'lookup>, + { + fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { + let span = ctx.span(id).unwrap(); + let scope = span + .scope() + .from_root() + .map(|span| span.name()) + .collect::>(); + *self.last_entered_scope.lock().unwrap() = scope; + } + } + + let _guard = tracing::subscriber::set_default(crate::registry().with(PrintingLayer { + last_entered_scope: last_entered_scope.clone(), + })); + + let _root = tracing::info_span!("root").entered(); + assert_eq!(&*last_entered_scope.lock().unwrap(), &["root"]); + let _child = tracing::info_span!("child").entered(); + assert_eq!(&*last_entered_scope.lock().unwrap(), &["root", "child",]); + let _leaf = tracing::info_span!("leaf").entered(); + assert_eq!( + &*last_entered_scope.lock().unwrap(), + &["root", "child", "leaf"] + ); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/registry/sharded.rs b/vendor/tracing-subscriber-0.3.3/src/registry/sharded.rs new file mode 100644 index 000000000..a6311cb71 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/registry/sharded.rs @@ -0,0 +1,904 @@ +use sharded_slab::{pool::Ref, Clear, Pool}; +use thread_local::ThreadLocal; + +use super::stack::SpanStack; +use crate::{ + filter::{FilterId, FilterMap, FilterState}, + registry::{ + extensions::{Extensions, ExtensionsInner, ExtensionsMut}, + LookupSpan, SpanData, + }, + sync::RwLock, +}; +use std::{ + cell::{self, Cell, RefCell}, + sync::atomic::{fence, AtomicUsize, Ordering}, +}; +use tracing_core::{ + dispatcher::{self, Dispatch}, + span::{self, Current, Id}, + Event, Interest, Metadata, Subscriber, +}; + +/// A shared, reusable store for spans. +/// +/// A `Registry` is a [`Subscriber`] around which multiple [`Layer`]s +/// implementing various behaviors may be [added]. Unlike other types +/// implementing `Subscriber`, `Registry` does not actually record traces itself: +/// instead, it collects and stores span data that is exposed to any [`Layer`]s +/// wrapping it through implementations of the [`LookupSpan`] trait. +/// The `Registry` is responsible for storing span metadata, recording +/// relationships between spans, and tracking which spans are active and which +/// are closed. In addition, it provides a mechanism for [`Layer`]s to store +/// user-defined per-span data, called [extensions], in the registry. This +/// allows [`Layer`]-specific data to benefit from the `Registry`'s +/// high-performance concurrent storage. +/// +/// This registry is implemented using a [lock-free sharded slab][slab], and is +/// highly optimized for concurrent access. +/// +/// # Span ID Generation +/// +/// Span IDs are not globally unique, but the registry ensures that +/// no two currently active spans have the same ID within a process. +/// +/// One of the primary responsibilities of the registry is to generate [span +/// IDs]. Therefore, it's important for other code that interacts with the +/// registry, such as [`Layer`]s, to understand the guarantees of the +/// span IDs that are generated. +/// +/// The registry's span IDs are guaranteed to be unique **at a given point +/// in time**. This means that an active span will never be assigned the +/// same ID as another **currently active** span. However, the registry +/// **will** eventually reuse the IDs of [closed] spans, although an ID +/// will never be reassigned immediately after a span has closed. +/// +/// Spans are not [considered closed] by the `Registry` until *every* +/// [`Span`] reference with that ID has been dropped. +/// +/// Thus: span IDs generated by the registry should be considered unique +/// only at a given point in time, and only relative to other spans +/// generated by the same process. Two spans with the same ID will not exist +/// in the same process concurrently. However, if historical span data is +/// being stored, the same ID may occur for multiple spans times in that +/// data. If spans must be uniquely identified in historical data, the user +/// code storing this data must assign its own unique identifiers to those +/// spans. A counter is generally sufficient for this. +/// +/// Similarly, span IDs generated by the registry are not unique outside of +/// a given process. Distributed tracing systems may require identifiers +/// that are unique across multiple processes on multiple machines (for +/// example, [OpenTelemetry's `SpanId`s and `TraceId`s][ot]). `tracing` span +/// IDs generated by the registry should **not** be used for this purpose. +/// Instead, code which integrates with a distributed tracing system should +/// generate and propagate its own IDs according to the rules specified by +/// the distributed tracing system. These IDs can be associated with +/// `tracing` spans using [fields] and/or [stored span data]. +/// +/// [span IDs]: https://docs.rs/tracing-core/latest/tracing_core/span/struct.Id.html +/// [slab]: https://docs.rs/crate/sharded-slab/ +/// [`Layer`]: crate::Layer +/// [added]: crate::layer::Layer#composing-layers +/// [extensions]: super::Extensions +/// [closed]: https://docs.rs/tracing/latest/tracing/span/index.html#closing-spans +/// [considered closed]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html#method.try_close +/// [`Span`]: https://docs.rs/tracing/latest/tracing/span/struct.Span.html +/// [ot]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spancontext +/// [fields]: https://docs.rs/tracing-core/latest/tracing-core/field/index.html +/// [stored span data]: crate::registry::SpanData::extensions_mut +#[cfg(feature = "registry")] +#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] +#[derive(Debug)] +pub struct Registry { + spans: Pool, + current_spans: ThreadLocal>, + next_filter_id: u8, +} + +/// Span data stored in a [`Registry`]. +/// +/// The registry stores well-known data defined by tracing: span relationships, +/// metadata and reference counts. Additional user-defined data provided by +/// [`Layer`s], such as formatted fields, metrics, or distributed traces should +/// be stored in the [extensions] typemap. +/// +/// [`Registry`]: struct.Registry.html +/// [`Layer`s]: ../layer/trait.Layer.html +/// [extensions]: struct.Extensions.html +#[cfg(feature = "registry")] +#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] +#[derive(Debug)] +pub struct Data<'a> { + /// Immutable reference to the pooled `DataInner` entry. + inner: Ref<'a, DataInner>, +} + +/// Stored data associated with a span. +/// +/// This type is pooled using `sharded_slab::Pool`; when a span is dropped, the +/// `DataInner` entry at that span's slab index is cleared in place and reused +/// by a future span. Thus, the `Default` and `sharded_slab::Clear` +/// implementations for this type are load-bearing. +#[derive(Debug)] +struct DataInner { + filter_map: FilterMap, + metadata: &'static Metadata<'static>, + parent: Option, + ref_count: AtomicUsize, + // The span's `Extensions` typemap. Allocations for the `HashMap` backing + // this are pooled and reused in place. + pub(crate) extensions: RwLock, +} + +// === impl Registry === + +impl Default for Registry { + fn default() -> Self { + Self { + spans: Pool::new(), + current_spans: ThreadLocal::new(), + next_filter_id: 0, + } + } +} + +#[inline] +fn idx_to_id(idx: usize) -> Id { + Id::from_u64(idx as u64 + 1) +} + +#[inline] +fn id_to_idx(id: &Id) -> usize { + id.into_u64() as usize - 1 +} + +/// A guard that tracks how many [`Registry`]-backed `Layer`s have +/// processed an `on_close` event. +/// +/// This is needed to enable a [`Registry`]-backed Layer to access span +/// data after the `Layer` has recieved the `on_close` callback. +/// +/// Once all `Layer`s have processed this event, the [`Registry`] knows +/// that is able to safely remove the span tracked by `id`. `CloseGuard` +/// accomplishes this through a two-step process: +/// 1. Whenever a [`Registry`]-backed `Layer::on_close` method is +/// called, `Registry::start_close` is closed. +/// `Registry::start_close` increments a thread-local `CLOSE_COUNT` +/// by 1 and returns a `CloseGuard`. +/// 2. The `CloseGuard` is dropped at the end of `Layer::on_close`. On +/// drop, `CloseGuard` checks thread-local `CLOSE_COUNT`. If +/// `CLOSE_COUNT` is 0, the `CloseGuard` removes the span with the +/// `id` from the registry, as all `Layers` that might have seen the +/// `on_close` notification have processed it. If `CLOSE_COUNT` is +/// greater than 0, `CloseGuard` decrements the counter by one and +/// _does not_ remove the span from the [`Registry`]. +/// +/// [`Registry`]: ./struct.Registry.html +pub(crate) struct CloseGuard<'a> { + id: Id, + registry: &'a Registry, + is_closing: bool, +} + +impl Registry { + fn get(&self, id: &Id) -> Option> { + self.spans.get(id_to_idx(id)) + } + + /// Returns a guard which tracks how many `Layer`s have + /// processed an `on_close` notification via the `CLOSE_COUNT` thread-local. + /// For additional details, see [`CloseGuard`]. + /// + /// [`CloseGuard`]: ./struct.CloseGuard.html + pub(crate) fn start_close(&self, id: Id) -> CloseGuard<'_> { + CLOSE_COUNT.with(|count| { + let c = count.get(); + count.set(c + 1); + }); + CloseGuard { + id, + registry: self, + is_closing: false, + } + } + + pub(crate) fn has_per_layer_filters(&self) -> bool { + self.next_filter_id > 0 + } + + pub(crate) fn span_stack(&self) -> cell::Ref<'_, SpanStack> { + self.current_spans.get_or_default().borrow() + } +} + +thread_local! { + /// `CLOSE_COUNT` is the thread-local counter used by `CloseGuard` to + /// track how many layers have processed the close. + /// For additional details, see [`CloseGuard`]. + /// + /// [`CloseGuard`]: ./struct.CloseGuard.html + static CLOSE_COUNT: Cell = Cell::new(0); +} + +impl Subscriber for Registry { + fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { + if self.has_per_layer_filters() { + return FilterState::take_interest().unwrap_or_else(Interest::always); + } + + Interest::always() + } + + fn enabled(&self, _: &Metadata<'_>) -> bool { + if self.has_per_layer_filters() { + return FilterState::event_enabled(); + } + true + } + + #[inline] + fn new_span(&self, attrs: &span::Attributes<'_>) -> span::Id { + let parent = if attrs.is_root() { + None + } else if attrs.is_contextual() { + self.current_span().id().map(|id| self.clone_span(id)) + } else { + attrs.parent().map(|id| self.clone_span(id)) + }; + + let id = self + .spans + // Check out a `DataInner` entry from the pool for the new span. If + // there are free entries already allocated in the pool, this will + // preferentially reuse one; otherwise, a new `DataInner` is + // allocated and added to the pool. + .create_with(|data| { + data.metadata = attrs.metadata(); + data.parent = parent; + data.filter_map = crate::filter::FILTERING.with(|filtering| filtering.filter_map()); + #[cfg(debug_assertions)] + { + if data.filter_map != FilterMap::default() { + debug_assert!(self.has_per_layer_filters()); + } + } + + let refs = data.ref_count.get_mut(); + debug_assert_eq!(*refs, 0); + *refs = 1; + }) + .expect("Unable to allocate another span"); + idx_to_id(id) + } + + /// This is intentionally not implemented, as recording fields + /// on a span is the responsibility of layers atop of this registry. + #[inline] + fn record(&self, _: &span::Id, _: &span::Record<'_>) {} + + fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {} + + /// This is intentionally not implemented, as recording events + /// is the responsibility of layers atop of this registry. + fn event(&self, _: &Event<'_>) {} + + fn enter(&self, id: &span::Id) { + if self + .current_spans + .get_or_default() + .borrow_mut() + .push(id.clone()) + { + self.clone_span(id); + } + } + + fn exit(&self, id: &span::Id) { + if let Some(spans) = self.current_spans.get() { + if spans.borrow_mut().pop(id) { + dispatcher::get_default(|dispatch| dispatch.try_close(id.clone())); + } + } + } + + fn clone_span(&self, id: &span::Id) -> span::Id { + let span = self + .get(id) + .unwrap_or_else(|| panic!( + "tried to clone {:?}, but no span exists with that ID\n\ + This may be caused by consuming a parent span (`parent: span`) rather than borrowing it (`parent: &span`).", + id, + )); + // Like `std::sync::Arc`, adds to the ref count (on clone) don't require + // a strong ordering; if we call` clone_span`, the reference count must + // always at least 1. The only synchronization necessary is between + // calls to `try_close`: we have to ensure that all threads have + // dropped their refs to the span before the span is closed. + let refs = span.ref_count.fetch_add(1, Ordering::Relaxed); + assert_ne!( + refs, 0, + "tried to clone a span ({:?}) that already closed", + id + ); + id.clone() + } + + fn current_span(&self) -> Current { + self.current_spans + .get() + .and_then(|spans| { + let spans = spans.borrow(); + let id = spans.current()?; + let span = self.get(id)?; + Some(Current::new(id.clone(), span.metadata)) + }) + .unwrap_or_else(Current::none) + } + + /// Decrements the reference count of the span with the given `id`, and + /// removes the span if it is zero. + /// + /// The allocated span slot will be reused when a new span is created. + fn try_close(&self, id: span::Id) -> bool { + let span = match self.get(&id) { + Some(span) => span, + None if std::thread::panicking() => return false, + None => panic!("tried to drop a ref to {:?}, but no such span exists!", id), + }; + + let refs = span.ref_count.fetch_sub(1, Ordering::Release); + if !std::thread::panicking() { + assert!(refs < std::usize::MAX, "reference count overflow!"); + } + if refs > 1 { + return false; + } + + // Synchronize if we are actually removing the span (stolen + // from std::Arc); this ensures that all other `try_close` calls on + // other threads happen-before we actually remove the span. + fence(Ordering::Acquire); + true + } +} + +impl<'a> LookupSpan<'a> for Registry { + type Data = Data<'a>; + + fn span_data(&'a self, id: &Id) -> Option { + let inner = self.get(id)?; + Some(Data { inner }) + } + + fn register_filter(&mut self) -> FilterId { + let id = FilterId::new(self.next_filter_id); + self.next_filter_id += 1; + id + } +} + +// === impl CloseGuard === + +impl<'a> CloseGuard<'a> { + pub(crate) fn is_closing(&mut self) { + self.is_closing = true; + } +} + +impl<'a> Drop for CloseGuard<'a> { + fn drop(&mut self) { + // If this returns with an error, we are already panicking. At + // this point, there's nothing we can really do to recover + // except by avoiding a double-panic. + let _ = CLOSE_COUNT.try_with(|count| { + let c = count.get(); + // Decrement the count to indicate that _this_ guard's + // `on_close` callback has completed. + // + // Note that we *must* do this before we actually remove the span + // from the registry, since dropping the `DataInner` may trigger a + // new close, if this span is the last reference to a parent span. + count.set(c - 1); + + // If the current close count is 1, this stack frame is the last + // `on_close` call. If the span is closing, it's okay to remove the + // span. + if c == 1 && self.is_closing { + self.registry.spans.clear(id_to_idx(&self.id)); + } + }); + } +} + +// === impl Data === + +impl<'a> SpanData<'a> for Data<'a> { + fn id(&self) -> Id { + idx_to_id(self.inner.key()) + } + + fn metadata(&self) -> &'static Metadata<'static> { + (*self).inner.metadata + } + + fn parent(&self) -> Option<&Id> { + self.inner.parent.as_ref() + } + + fn extensions(&self) -> Extensions<'_> { + Extensions::new(self.inner.extensions.read().expect("Mutex poisoned")) + } + + fn extensions_mut(&self) -> ExtensionsMut<'_> { + ExtensionsMut::new(self.inner.extensions.write().expect("Mutex poisoned")) + } + + #[inline] + fn is_enabled_for(&self, filter: FilterId) -> bool { + self.inner.filter_map.is_enabled(filter) + } +} + +// === impl DataInner === + +impl Default for DataInner { + fn default() -> Self { + // Since `DataInner` owns a `&'static Callsite` pointer, we need + // something to use as the initial default value for that callsite. + // Since we can't access a `DataInner` until it has had actual span data + // inserted into it, the null metadata will never actually be accessed. + struct NullCallsite; + impl tracing_core::callsite::Callsite for NullCallsite { + fn set_interest(&self, _: Interest) { + unreachable!( + "/!\\ Tried to register the null callsite /!\\\n \ + This should never have happened and is definitely a bug. \ + A `tracing` bug report would be appreciated." + ) + } + + fn metadata(&self) -> &Metadata<'_> { + unreachable!( + "/!\\ Tried to access the null callsite's metadata /!\\\n \ + This should never have happened and is definitely a bug. \ + A `tracing` bug report would be appreciated." + ) + } + } + + static NULL_CALLSITE: NullCallsite = NullCallsite; + static NULL_METADATA: Metadata<'static> = tracing_core::metadata! { + name: "", + target: "", + level: tracing_core::Level::TRACE, + fields: &[], + callsite: &NULL_CALLSITE, + kind: tracing_core::metadata::Kind::SPAN, + }; + + Self { + filter_map: FilterMap::default(), + metadata: &NULL_METADATA, + parent: None, + ref_count: AtomicUsize::new(0), + extensions: RwLock::new(ExtensionsInner::new()), + } + } +} + +impl Clear for DataInner { + /// Clears the span's data in place, dropping the parent's reference count. + fn clear(&mut self) { + // A span is not considered closed until all of its children have closed. + // Therefore, each span's `DataInner` holds a "reference" to the parent + // span, keeping the parent span open until all its children have closed. + // When we close a span, we must then decrement the parent's ref count + // (potentially, allowing it to close, if this child is the last reference + // to that span). + // We have to actually unpack the option inside the `get_default` + // closure, since it is a `FnMut`, but testing that there _is_ a value + // here lets us avoid the thread-local access if we don't need the + // dispatcher at all. + if self.parent.is_some() { + // Note that --- because `Layered::try_close` works by calling + // `try_close` on the inner subscriber and using the return value to + // determine whether to call the `Layer`'s `on_close` callback --- + // we must call `try_close` on the entire subscriber stack, rather + // than just on the registry. If the registry called `try_close` on + // itself directly, the layers wouldn't see the close notification. + let subscriber = dispatcher::get_default(Dispatch::clone); + if let Some(parent) = self.parent.take() { + let _ = subscriber.try_close(parent); + } + } + + // Clear (but do not deallocate!) the pooled `HashMap` for the span's extensions. + self.extensions + .get_mut() + .unwrap_or_else(|l| { + // This function can be called in a `Drop` impl, such as while + // panicking, so ignore lock poisoning. + l.into_inner() + }) + .clear(); + + self.filter_map = FilterMap::default(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{layer::Context, registry::LookupSpan, Layer}; + use std::{ + collections::HashMap, + sync::{Arc, Mutex, Weak}, + }; + use tracing::{self, subscriber::with_default}; + use tracing_core::{ + dispatcher, + span::{Attributes, Id}, + Subscriber, + }; + + #[derive(Debug)] + struct DoesNothing; + impl Layer for DoesNothing {} + + struct AssertionLayer; + impl Layer for AssertionLayer + where + S: Subscriber + for<'a> LookupSpan<'a>, + { + fn on_close(&self, id: Id, ctx: Context<'_, S>) { + dbg!(format_args!("closing {:?}", id)); + assert!(&ctx.span(&id).is_some()); + } + } + + #[test] + fn single_layer_can_access_closed_span() { + let subscriber = AssertionLayer.with_subscriber(Registry::default()); + + with_default(subscriber, || { + let span = tracing::debug_span!("span"); + drop(span); + }); + } + + #[test] + fn multiple_layers_can_access_closed_span() { + let subscriber = AssertionLayer + .and_then(AssertionLayer) + .with_subscriber(Registry::default()); + + with_default(subscriber, || { + let span = tracing::debug_span!("span"); + drop(span); + }); + } + + struct CloseLayer { + inner: Arc>, + } + + struct CloseHandle { + state: Arc>, + } + + #[derive(Default)] + struct CloseState { + open: HashMap<&'static str, Weak<()>>, + closed: Vec<(&'static str, Weak<()>)>, + } + + struct SetRemoved(Arc<()>); + + impl Layer for CloseLayer + where + S: Subscriber + for<'a> LookupSpan<'a>, + { + fn on_new_span(&self, _: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { + let span = ctx.span(id).expect("Missing span; this is a bug"); + let mut lock = self.inner.lock().unwrap(); + let is_removed = Arc::new(()); + assert!( + lock.open + .insert(span.name(), Arc::downgrade(&is_removed)) + .is_none(), + "test layer saw multiple spans with the same name, the test is probably messed up" + ); + let mut extensions = span.extensions_mut(); + extensions.insert(SetRemoved(is_removed)); + } + + fn on_close(&self, id: Id, ctx: Context<'_, S>) { + let span = if let Some(span) = ctx.span(&id) { + span + } else { + println!( + "span {:?} did not exist in `on_close`, are we panicking?", + id + ); + return; + }; + let name = span.name(); + println!("close {} ({:?})", name, id); + if let Ok(mut lock) = self.inner.lock() { + if let Some(is_removed) = lock.open.remove(name) { + assert!(is_removed.upgrade().is_some()); + lock.closed.push((name, is_removed)); + } + } + } + } + + impl CloseLayer { + fn new() -> (Self, CloseHandle) { + let state = Arc::new(Mutex::new(CloseState::default())); + ( + Self { + inner: state.clone(), + }, + CloseHandle { state }, + ) + } + } + + impl CloseState { + fn is_open(&self, span: &str) -> bool { + self.open.contains_key(span) + } + + fn is_closed(&self, span: &str) -> bool { + self.closed.iter().any(|(name, _)| name == &span) + } + } + + impl CloseHandle { + fn assert_closed(&self, span: &str) { + let lock = self.state.lock().unwrap(); + assert!( + lock.is_closed(span), + "expected {} to be closed{}", + span, + if lock.is_open(span) { + " (it was still open)" + } else { + ", but it never existed (is there a problem with the test?)" + } + ) + } + + fn assert_open(&self, span: &str) { + let lock = self.state.lock().unwrap(); + assert!( + lock.is_open(span), + "expected {} to be open{}", + span, + if lock.is_closed(span) { + " (it was still open)" + } else { + ", but it never existed (is there a problem with the test?)" + } + ) + } + + fn assert_removed(&self, span: &str) { + let lock = self.state.lock().unwrap(); + let is_removed = match lock.closed.iter().find(|(name, _)| name == &span) { + Some((_, is_removed)) => is_removed, + None => panic!( + "expected {} to be removed from the registry, but it was not closed {}", + span, + if lock.is_closed(span) { + " (it was still open)" + } else { + ", but it never existed (is there a problem with the test?)" + } + ), + }; + assert!( + is_removed.upgrade().is_none(), + "expected {} to have been removed from the registry", + span + ) + } + + fn assert_not_removed(&self, span: &str) { + let lock = self.state.lock().unwrap(); + let is_removed = match lock.closed.iter().find(|(name, _)| name == &span) { + Some((_, is_removed)) => is_removed, + None if lock.is_open(span) => return, + None => unreachable!(), + }; + assert!( + is_removed.upgrade().is_some(), + "expected {} to have been removed from the registry", + span + ) + } + + #[allow(unused)] // may want this for future tests + fn assert_last_closed(&self, span: Option<&str>) { + let lock = self.state.lock().unwrap(); + let last = lock.closed.last().map(|(span, _)| span); + assert_eq!( + last, + span.as_ref(), + "expected {:?} to have closed last", + span + ); + } + + fn assert_closed_in_order(&self, order: impl AsRef<[&'static str]>) { + let lock = self.state.lock().unwrap(); + let order = order.as_ref(); + for (i, name) in order.iter().enumerate() { + assert_eq!( + lock.closed.get(i).map(|(span, _)| span), + Some(name), + "expected close order: {:?}, actual: {:?}", + order, + lock.closed.iter().map(|(name, _)| name).collect::>() + ); + } + } + } + + #[test] + fn spans_are_removed_from_registry() { + let (close_layer, state) = CloseLayer::new(); + let subscriber = AssertionLayer + .and_then(close_layer) + .with_subscriber(Registry::default()); + + // Create a `Dispatch` (which is internally reference counted) so that + // the subscriber lives to the end of the test. Otherwise, if we just + // passed the subscriber itself to `with_default`, we could see the span + // be dropped when the subscriber itself is dropped, destroying the + // registry. + let dispatch = dispatcher::Dispatch::new(subscriber); + + dispatcher::with_default(&dispatch, || { + let span = tracing::debug_span!("span1"); + drop(span); + let span = tracing::info_span!("span2"); + drop(span); + }); + + state.assert_removed("span1"); + state.assert_removed("span2"); + + // Ensure the registry itself outlives the span. + drop(dispatch); + } + + #[test] + fn spans_are_only_closed_when_the_last_ref_drops() { + let (close_layer, state) = CloseLayer::new(); + let subscriber = AssertionLayer + .and_then(close_layer) + .with_subscriber(Registry::default()); + + // Create a `Dispatch` (which is internally reference counted) so that + // the subscriber lives to the end of the test. Otherwise, if we just + // passed the subscriber itself to `with_default`, we could see the span + // be dropped when the subscriber itself is dropped, destroying the + // registry. + let dispatch = dispatcher::Dispatch::new(subscriber); + + let span2 = dispatcher::with_default(&dispatch, || { + let span = tracing::debug_span!("span1"); + drop(span); + let span2 = tracing::info_span!("span2"); + let span2_clone = span2.clone(); + drop(span2); + span2_clone + }); + + state.assert_removed("span1"); + state.assert_not_removed("span2"); + + drop(span2); + state.assert_removed("span1"); + + // Ensure the registry itself outlives the span. + drop(dispatch); + } + + #[test] + fn span_enter_guards_are_dropped_out_of_order() { + let (close_layer, state) = CloseLayer::new(); + let subscriber = AssertionLayer + .and_then(close_layer) + .with_subscriber(Registry::default()); + + // Create a `Dispatch` (which is internally reference counted) so that + // the subscriber lives to the end of the test. Otherwise, if we just + // passed the subscriber itself to `with_default`, we could see the span + // be dropped when the subscriber itself is dropped, destroying the + // registry. + let dispatch = dispatcher::Dispatch::new(subscriber); + + dispatcher::with_default(&dispatch, || { + let span1 = tracing::debug_span!("span1"); + let span2 = tracing::info_span!("span2"); + + let enter1 = span1.enter(); + let enter2 = span2.enter(); + + drop(enter1); + drop(span1); + + state.assert_removed("span1"); + state.assert_not_removed("span2"); + + drop(enter2); + state.assert_not_removed("span2"); + + drop(span2); + state.assert_removed("span1"); + state.assert_removed("span2"); + }); + } + + #[test] + fn child_closes_parent() { + // This test asserts that if a parent span's handle is dropped before + // a child span's handle, the parent will remain open until child + // closes, and will then be closed. + + let (close_layer, state) = CloseLayer::new(); + let subscriber = close_layer.with_subscriber(Registry::default()); + + let dispatch = dispatcher::Dispatch::new(subscriber); + + dispatcher::with_default(&dispatch, || { + let span1 = tracing::info_span!("parent"); + let span2 = tracing::info_span!(parent: &span1, "child"); + + state.assert_open("parent"); + state.assert_open("child"); + + drop(span1); + state.assert_open("parent"); + state.assert_open("child"); + + drop(span2); + state.assert_closed("parent"); + state.assert_closed("child"); + }); + } + + #[test] + fn child_closes_grandparent() { + // This test asserts that, when a span is kept open by a child which + // is *itself* kept open by a child, closing the grandchild will close + // both the parent *and* the grandparent. + let (close_layer, state) = CloseLayer::new(); + let subscriber = close_layer.with_subscriber(Registry::default()); + + let dispatch = dispatcher::Dispatch::new(subscriber); + + dispatcher::with_default(&dispatch, || { + let span1 = tracing::info_span!("grandparent"); + let span2 = tracing::info_span!(parent: &span1, "parent"); + let span3 = tracing::info_span!(parent: &span2, "child"); + + state.assert_open("grandparent"); + state.assert_open("parent"); + state.assert_open("child"); + + drop(span1); + drop(span2); + state.assert_open("grandparent"); + state.assert_open("parent"); + state.assert_open("child"); + + drop(span3); + + state.assert_closed_in_order(&["child", "parent", "grandparent"]); + }); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/registry/stack.rs b/vendor/tracing-subscriber-0.3.3/src/registry/stack.rs new file mode 100644 index 000000000..4a3f7e59d --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/registry/stack.rs @@ -0,0 +1,77 @@ +pub(crate) use tracing_core::span::Id; + +#[derive(Debug)] +struct ContextId { + id: Id, + duplicate: bool, +} + +/// `SpanStack` tracks what spans are currently executing on a thread-local basis. +/// +/// A "separate current span" for each thread is a semantic choice, as each span +/// can be executing in a different thread. +#[derive(Debug, Default)] +pub(crate) struct SpanStack { + stack: Vec, +} + +impl SpanStack { + #[inline] + pub(super) fn push(&mut self, id: Id) -> bool { + let duplicate = self.stack.iter().any(|i| i.id == id); + self.stack.push(ContextId { id, duplicate }); + !duplicate + } + + #[inline] + pub(super) fn pop(&mut self, expected_id: &Id) -> bool { + if let Some((idx, _)) = self + .stack + .iter() + .enumerate() + .rev() + .find(|(_, ctx_id)| ctx_id.id == *expected_id) + { + let ContextId { id: _, duplicate } = self.stack.remove(idx); + return !duplicate; + } + false + } + + #[inline] + pub(crate) fn iter(&self) -> impl Iterator { + self.stack + .iter() + .rev() + .filter_map(|ContextId { id, duplicate }| if !*duplicate { Some(id) } else { None }) + } + + #[inline] + pub(crate) fn current(&self) -> Option<&Id> { + self.iter().next() + } +} + +#[cfg(test)] +mod tests { + use super::{Id, SpanStack}; + + #[test] + fn pop_last_span() { + let mut stack = SpanStack::default(); + let id = Id::from_u64(1); + stack.push(id.clone()); + + assert!(stack.pop(&id)); + } + + #[test] + fn pop_first_span() { + let mut stack = SpanStack::default(); + stack.push(Id::from_u64(1)); + stack.push(Id::from_u64(2)); + + let id = Id::from_u64(1); + assert!(stack.pop(&id)); + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/reload.rs b/vendor/tracing-subscriber-0.3.3/src/reload.rs new file mode 100644 index 000000000..b8ec67dfa --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/reload.rs @@ -0,0 +1,237 @@ +//! Wrapper for a `Layer` to allow it to be dynamically reloaded. +//! +//! This module provides a [`Layer` type] which wraps another type implementing +//! the [`Layer` trait], allowing the wrapped type to be replaced with another +//! instance of that type at runtime. +//! +//! This can be used in cases where a subset of `Subscriber` functionality +//! should be dynamically reconfigured, such as when filtering directives may +//! change at runtime. Note that this layer introduces a (relatively small) +//! amount of overhead, and should thus only be used as needed. +//! +//! [`Layer` type]: struct.Layer.html +//! [`Layer` trait]: ../layer/trait.Layer.html +use crate::layer; +use crate::sync::RwLock; + +use std::{ + error, fmt, + marker::PhantomData, + sync::{Arc, Weak}, +}; +use tracing_core::{ + callsite, span, + subscriber::{Interest, Subscriber}, + Event, Metadata, +}; + +/// Wraps a `Layer`, allowing it to be reloaded dynamically at runtime. +#[derive(Debug)] +pub struct Layer { + // TODO(eliza): this once used a `crossbeam_util::ShardedRwLock`. We may + // eventually wish to replace it with a sharded lock implementation on top + // of our internal `RwLock` wrapper type. If possible, we should profile + // this first to determine if it's necessary. + inner: Arc>, + _s: PhantomData, +} + +/// Allows reloading the state of an associated `Layer`. +#[derive(Debug)] +pub struct Handle { + inner: Weak>, + _s: PhantomData, +} + +/// Indicates that an error occurred when reloading a layer. +#[derive(Debug)] +pub struct Error { + kind: ErrorKind, +} + +#[derive(Debug)] +enum ErrorKind { + SubscriberGone, + Poisoned, +} + +// ===== impl Layer ===== + +impl crate::Layer for Layer +where + L: crate::Layer + 'static, + S: Subscriber, +{ + fn on_layer(&mut self, subscriber: &mut S) { + try_lock!(self.inner.write(), else return).on_layer(subscriber); + } + + #[inline] + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + try_lock!(self.inner.read(), else return Interest::sometimes()).register_callsite(metadata) + } + + #[inline] + fn enabled(&self, metadata: &Metadata<'_>, ctx: layer::Context<'_, S>) -> bool { + try_lock!(self.inner.read(), else return false).enabled(metadata, ctx) + } + + #[inline] + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_new_span(attrs, id, ctx) + } + + #[inline] + fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_record(span, values, ctx) + } + + #[inline] + fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_follows_from(span, follows, ctx) + } + + #[inline] + fn on_event(&self, event: &Event<'_>, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_event(event, ctx) + } + + #[inline] + fn on_enter(&self, id: &span::Id, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_enter(id, ctx) + } + + #[inline] + fn on_exit(&self, id: &span::Id, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_exit(id, ctx) + } + + #[inline] + fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_close(id, ctx) + } + + #[inline] + fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) { + try_lock!(self.inner.read()).on_id_change(old, new, ctx) + } +} + +impl Layer +where + L: crate::Layer + 'static, + S: Subscriber, +{ + /// Wraps the given `Layer`, returning a `Layer` and a `Handle` that allows + /// the inner type to be modified at runtime. + pub fn new(inner: L) -> (Self, Handle) { + let this = Self { + inner: Arc::new(RwLock::new(inner)), + _s: PhantomData, + }; + let handle = this.handle(); + (this, handle) + } + + /// Returns a `Handle` that can be used to reload the wrapped `Layer`. + pub fn handle(&self) -> Handle { + Handle { + inner: Arc::downgrade(&self.inner), + _s: PhantomData, + } + } +} + +// ===== impl Handle ===== + +impl Handle +where + L: crate::Layer + 'static, + S: Subscriber, +{ + /// Replace the current layer with the provided `new_layer`. + pub fn reload(&self, new_layer: impl Into) -> Result<(), Error> { + self.modify(|layer| { + *layer = new_layer.into(); + }) + } + + /// Invokes a closure with a mutable reference to the current layer, + /// allowing it to be modified in place. + pub fn modify(&self, f: impl FnOnce(&mut L)) -> Result<(), Error> { + let inner = self.inner.upgrade().ok_or(Error { + kind: ErrorKind::SubscriberGone, + })?; + + let mut lock = try_lock!(inner.write(), else return Err(Error::poisoned())); + f(&mut *lock); + // Release the lock before rebuilding the interest cache, as that + // function will lock the new layer. + drop(lock); + + callsite::rebuild_interest_cache(); + Ok(()) + } + + /// Returns a clone of the layer's current value if it still exists. + /// Otherwise, if the subscriber has been dropped, returns `None`. + pub fn clone_current(&self) -> Option + where + L: Clone, + { + self.with_current(L::clone).ok() + } + + /// Invokes a closure with a borrowed reference to the current layer, + /// returning the result (or an error if the subscriber no longer exists). + pub fn with_current(&self, f: impl FnOnce(&L) -> T) -> Result { + let inner = self.inner.upgrade().ok_or(Error { + kind: ErrorKind::SubscriberGone, + })?; + let inner = try_lock!(inner.read(), else return Err(Error::poisoned())); + Ok(f(&*inner)) + } +} + +impl Clone for Handle { + fn clone(&self) -> Self { + Handle { + inner: self.inner.clone(), + _s: PhantomData, + } + } +} + +// ===== impl Error ===== + +impl Error { + fn poisoned() -> Self { + Self { + kind: ErrorKind::Poisoned, + } + } + + /// Returns `true` if this error occurred because the layer was poisoned by + /// a panic on another thread. + pub fn is_poisoned(&self) -> bool { + matches!(self.kind, ErrorKind::Poisoned) + } + + /// Returns `true` if this error occurred because the `Subscriber` + /// containing the reloadable layer was dropped. + pub fn is_dropped(&self) -> bool { + matches!(self.kind, ErrorKind::SubscriberGone) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let msg = match self.kind { + ErrorKind::SubscriberGone => "subscriber no longer exists", + ErrorKind::Poisoned => "lock poisoned", + }; + f.pad(msg) + } +} + +impl error::Error for Error {} diff --git a/vendor/tracing-subscriber-0.3.3/src/sync.rs b/vendor/tracing-subscriber-0.3.3/src/sync.rs new file mode 100644 index 000000000..ec42b834a --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/sync.rs @@ -0,0 +1,57 @@ +//! Abstracts over sync primitive implementations. +//! +//! Optionally, we allow the Rust standard library's `RwLock` to be replaced +//! with the `parking_lot` crate's implementation. This may provide improved +//! performance in some cases. However, the `parking_lot` dependency is an +//! opt-in feature flag. Because `parking_lot::RwLock` has a slightly different +//! API than `std::sync::RwLock` (it does not support poisoning on panics), we +//! wrap it with a type that provides the same method signatures. This allows us +//! to transparently swap `parking_lot` in without changing code at the callsite. +#[allow(unused_imports)] // may be used later; +pub(crate) use std::sync::{LockResult, PoisonError, TryLockResult}; + +#[cfg(not(feature = "parking_lot"))] +pub(crate) use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; + +#[cfg(feature = "parking_lot")] +pub(crate) use self::parking_lot_impl::*; + +#[cfg(feature = "parking_lot")] +mod parking_lot_impl { + pub(crate) use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; + use std::sync::{LockResult, TryLockError, TryLockResult}; + + #[derive(Debug)] + pub(crate) struct RwLock { + inner: parking_lot::RwLock, + } + + impl RwLock { + pub(crate) fn new(val: T) -> Self { + Self { + inner: parking_lot::RwLock::new(val), + } + } + + #[inline] + pub(crate) fn get_mut(&mut self) -> LockResult<&mut T> { + Ok(self.inner.get_mut()) + } + + #[inline] + pub(crate) fn read(&self) -> LockResult> { + Ok(self.inner.read()) + } + + #[inline] + #[allow(dead_code)] // may be used later; + pub(crate) fn try_read(&self) -> TryLockResult> { + self.inner.try_read().ok_or(TryLockError::WouldBlock) + } + + #[inline] + pub(crate) fn write(&self) -> LockResult> { + Ok(self.inner.write()) + } + } +} diff --git a/vendor/tracing-subscriber-0.3.3/src/util.rs b/vendor/tracing-subscriber-0.3.3/src/util.rs new file mode 100644 index 000000000..1c98aa4d2 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/src/util.rs @@ -0,0 +1,153 @@ +//! Extension traits and other utilities to make working with subscribers more +//! ergonomic. +use core::fmt; +#[cfg(feature = "std")] +use std::error::Error; +use tracing_core::dispatcher::{self, Dispatch}; +#[cfg(feature = "tracing-log")] +use tracing_log::AsLog; + +/// Extension trait adding utility methods for subscriber initialization. +/// +/// This trait provides extension methods to make configuring and setting a +/// [default subscriber] more ergonomic. It is automatically implemented for all +/// types that can be converted into a [trace dispatcher]. Since `Dispatch` +/// implements `From` for all `T: Subscriber`, all `Subscriber` +/// implementations will implement this extension trait as well. Types which +/// can be converted into `Subscriber`s, such as builders that construct a +/// `Subscriber`, may implement `Into`, and will also receive an +/// implementation of this trait. +/// +/// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber +/// [trace dispatcher]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html +pub trait SubscriberInitExt +where + Self: Into, +{ + /// Sets `self` as the [default subscriber] in the current scope, returning a + /// guard that will unset it when dropped. + /// + /// If the "tracing-log" feature flag is enabled, this will also initialize + /// a [`log`] compatibility layer. This allows the subscriber to consume + /// `log::Record`s as though they were `tracing` `Event`s. + /// + /// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber + /// [`log`]: https://crates.io/log + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + fn set_default(self) -> dispatcher::DefaultGuard { + #[cfg(feature = "tracing-log")] + let _ = tracing_log::LogTracer::init(); + + dispatcher::set_default(&self.into()) + } + + /// Attempts to set `self` as the [global default subscriber] in the current + /// scope, returning an error if one is already set. + /// + /// If the "tracing-log" feature flag is enabled, this will also attempt to + /// initialize a [`log`] compatibility layer. This allows the subscriber to + /// consume `log::Record`s as though they were `tracing` `Event`s. + /// + /// This method returns an error if a global default subscriber has already + /// been set, or if a `log` logger has already been set (when the + /// "tracing-log" feature is enabled). + /// + /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber + /// [`log`]: https://crates.io/log + fn try_init(self) -> Result<(), TryInitError> { + dispatcher::set_global_default(self.into()).map_err(TryInitError::new)?; + + // Since we are setting the global default subscriber, we can + // opportunistically go ahead and set its global max level hint as + // the max level for the `log` crate as well. This should make + // skipping `log` diagnostics much faster. + #[cfg(feature = "tracing-log")] + tracing_log::LogTracer::builder() + // Note that we must call this *after* setting the global default + // subscriber, so that we get its max level hint. + .with_max_level(tracing_core::LevelFilter::current().as_log()) + .init() + .map_err(TryInitError::new)?; + + Ok(()) + } + + /// Attempts to set `self` as the [global default subscriber] in the current + /// scope, panicking if this fails. + /// + /// If the "tracing-log" feature flag is enabled, this will also attempt to + /// initialize a [`log`] compatibility layer. This allows the subscriber to + /// consume `log::Record`s as though they were `tracing` `Event`s. + /// + /// This method panics if a global default subscriber has already been set, + /// or if a `log` logger has already been set (when the "tracing-log" + /// feature is enabled). + /// + /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber + /// [`log`]: https://crates.io/log + fn init(self) { + self.try_init() + .expect("failed to set global default subscriber") + } +} + +impl SubscriberInitExt for T where T: Into {} + +/// Error returned by [`try_init`](SubscriberInitExt::try_init) if a global default subscriber could not be initialized. +pub struct TryInitError { + #[cfg(feature = "std")] + inner: Box, + + #[cfg(not(feature = "std"))] + _p: (), +} + +// ==== impl TryInitError ==== + +impl TryInitError { + #[cfg(feature = "std")] + fn new(e: impl Into>) -> Self { + Self { inner: e.into() } + } + + #[cfg(not(feature = "std"))] + fn new(_: T) -> Self { + Self { _p: () } + } +} + +impl fmt::Debug for TryInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(feature = "std")] + { + fmt::Debug::fmt(&self.inner, f) + } + + #[cfg(not(feature = "std"))] + { + f.write_str("TryInitError(())") + } + } +} + +impl fmt::Display for TryInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(feature = "std")] + { + fmt::Display::fmt(&self.inner, f) + } + + #[cfg(not(feature = "std"))] + { + f.write_str("failed to set global default subscriber") + } + } +} + +#[cfg(feature = "std")] +impl Error for TryInitError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + self.inner.source() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/cached_layer_filters_dont_break_other_layers.rs b/vendor/tracing-subscriber-0.3.3/tests/cached_layer_filters_dont_break_other_layers.rs new file mode 100644 index 000000000..00e98a994 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/cached_layer_filters_dont_break_other_layers.rs @@ -0,0 +1,123 @@ +#![cfg(feature = "registry")] +mod support; +use self::support::*; +use tracing::Level; +use tracing_subscriber::{filter::LevelFilter, prelude::*}; + +#[test] +fn layer_filters() { + let (unfiltered, unfiltered_handle) = unfiltered("unfiltered"); + let (filtered, filtered_handle) = filtered("filtered"); + + let _subscriber = tracing_subscriber::registry() + .with(unfiltered) + .with(filtered.with_filter(filter())) + .set_default(); + + events(); + + unfiltered_handle.assert_finished(); + filtered_handle.assert_finished(); +} + +#[test] +fn layered_layer_filters() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + let unfiltered = unfiltered1.and_then(unfiltered2); + + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + let filtered = filtered1 + .with_filter(filter()) + .and_then(filtered2.with_filter(filter())); + + let _subscriber = tracing_subscriber::registry() + .with(unfiltered) + .with(filtered) + .set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +#[test] +fn out_of_order() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + + let _subscriber = tracing_subscriber::registry() + .with(unfiltered1) + .with(filtered1.with_filter(filter())) + .with(unfiltered2) + .with(filtered2.with_filter(filter())) + .set_default(); + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +#[test] +fn mixed_layered() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + + let layered1 = filtered1.with_filter(filter()).and_then(unfiltered1); + let layered2 = unfiltered2.and_then(filtered2.with_filter(filter())); + + let _subscriber = tracing_subscriber::registry() + .with(layered1) + .with(layered2) + .set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +fn events() { + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); +} + +fn filter() -> LevelFilter { + LevelFilter::INFO +} + +fn unfiltered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(name) + .event(event::mock().at_level(Level::TRACE)) + .event(event::mock().at_level(Level::DEBUG)) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle() +} + +fn filtered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(name) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle() +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/duplicate_spans.rs b/vendor/tracing-subscriber-0.3.3/tests/duplicate_spans.rs new file mode 100644 index 000000000..c4a736f74 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/duplicate_spans.rs @@ -0,0 +1,48 @@ +#![cfg(all(feature = "env-filter", feature = "fmt"))] +mod support; +use tracing::{self, subscriber::with_default, Span}; +use tracing_subscriber::{filter::EnvFilter, FmtSubscriber}; + +#[test] +fn duplicate_spans() { + let subscriber = FmtSubscriber::builder() + .with_env_filter(EnvFilter::new("[root]=debug")) + .finish(); + + with_default(subscriber, || { + let root = tracing::debug_span!("root"); + root.in_scope(|| { + // root: + assert_eq!(root, Span::current(), "Current span must be 'root'"); + let leaf = tracing::debug_span!("leaf"); + leaf.in_scope(|| { + // root:leaf: + assert_eq!(leaf, Span::current(), "Current span must be 'leaf'"); + root.in_scope(|| { + // root:leaf: + assert_eq!( + leaf, + Span::current(), + "Current span must be 'leaf' after entering twice the 'root' span" + ); + }) + }); + // root: + assert_eq!( + root, + Span::current(), + "Current span must be root ('leaf' exited, nested 'root' exited)" + ); + + root.in_scope(|| { + assert_eq!(root, Span::current(), "Current span must be root"); + }); + // root: + assert_eq!( + root, + Span::current(), + "Current span must still be root after exiting nested 'root'" + ); + }); + }); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/field_filter.rs b/vendor/tracing-subscriber-0.3.3/tests/field_filter.rs new file mode 100644 index 000000000..12b4053b6 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/field_filter.rs @@ -0,0 +1,115 @@ +#![cfg(feature = "env-filter")] +mod support; +use self::support::*; +use tracing::{self, subscriber::with_default, Level}; +use tracing_subscriber::{filter::EnvFilter, prelude::*}; + +#[test] +#[cfg_attr(not(flaky_tests), ignore)] +fn field_filter_events() { + let filter: EnvFilter = "[{thing}]=debug".parse().expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event( + event::mock() + .at_level(Level::INFO) + .with_fields(field::mock("thing")), + ) + .event( + event::mock() + .at_level(Level::DEBUG) + .with_fields(field::mock("thing")), + ) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!(disabled = true); + tracing::info!("also disabled"); + tracing::info!(thing = 1); + tracing::debug!(thing = 2); + tracing::trace!(thing = 3); + }); + + finished.assert_finished(); +} + +#[test] +#[cfg_attr(not(flaky_tests), ignore)] +fn field_filter_spans() { + let filter: EnvFilter = "[{enabled=true}]=debug" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .enter(span::mock().named("span1")) + .event( + event::mock() + .at_level(Level::INFO) + .with_fields(field::mock("something")), + ) + .exit(span::mock().named("span1")) + .enter(span::mock().named("span2")) + .exit(span::mock().named("span2")) + .enter(span::mock().named("span3")) + .event( + event::mock() + .at_level(Level::DEBUG) + .with_fields(field::mock("something")), + ) + .exit(span::mock().named("span3")) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!("disabled"); + tracing::info!("also disabled"); + tracing::info_span!("span1", enabled = true).in_scope(|| { + tracing::info!(something = 1); + }); + tracing::debug_span!("span2", enabled = false, foo = "hi").in_scope(|| { + tracing::warn!(something = 2); + }); + tracing::trace_span!("span3", enabled = true, answer = 42).in_scope(|| { + tracing::debug!(something = 2); + }); + }); + + finished.assert_finished(); +} + +#[test] +fn record_after_created() { + let filter: EnvFilter = "[{enabled=true}]=debug" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .enter(span::mock().named("span")) + .exit(span::mock().named("span")) + .record( + span::mock().named("span"), + field::mock("enabled").with_value(&true), + ) + .enter(span::mock().named("span")) + .event(event::mock().at_level(Level::DEBUG)) + .exit(span::mock().named("span")) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + let span = tracing::info_span!("span", enabled = false); + span.in_scope(|| { + tracing::debug!("i'm disabled!"); + }); + + span.record("enabled", &true); + span.in_scope(|| { + tracing::debug!("i'm enabled!"); + }); + + tracing::debug!("i'm also disabled"); + }); + + finished.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/filter.rs b/vendor/tracing-subscriber-0.3.3/tests/filter.rs new file mode 100644 index 000000000..8386d34d2 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/filter.rs @@ -0,0 +1,187 @@ +#![cfg(feature = "env-filter")] + +mod support; +use self::support::*; +use tracing::{self, subscriber::with_default, Level}; +use tracing_subscriber::{ + filter::{EnvFilter, LevelFilter}, + prelude::*, +}; + +#[test] +fn level_filter_event() { + let filter: EnvFilter = "info".parse().expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!("this should be disabled"); + tracing::info!("this shouldn't be"); + tracing::debug!(target: "foo", "this should also be disabled"); + tracing::warn!(target: "foo", "this should be enabled"); + tracing::error!("this should be enabled too"); + }); + + finished.assert_finished(); +} + +#[test] +fn same_name_spans() { + let filter: EnvFilter = "[foo{bar}]=trace,[foo{baz}]=trace" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .new_span( + span::mock() + .named("foo") + .at_level(Level::TRACE) + .with_field(field::mock("bar")), + ) + .new_span( + span::mock() + .named("foo") + .at_level(Level::TRACE) + .with_field(field::mock("baz")), + ) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + with_default(subscriber, || { + tracing::trace_span!("foo", bar = 1); + tracing::trace_span!("foo", baz = 1); + }); + + finished.assert_finished(); +} + +#[test] +fn level_filter_event_with_target() { + let filter: EnvFilter = "info,stuff=debug".parse().expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) + .event(event::mock().at_level(Level::WARN).with_target("stuff")) + .event(event::mock().at_level(Level::ERROR)) + .event(event::mock().at_level(Level::ERROR).with_target("stuff")) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!("this should be disabled"); + tracing::info!("this shouldn't be"); + tracing::debug!(target: "stuff", "this should be enabled"); + tracing::debug!("but this shouldn't"); + tracing::trace!(target: "stuff", "and neither should this"); + tracing::warn!(target: "stuff", "this should be enabled"); + tracing::error!("this should be enabled too"); + tracing::error!(target: "stuff", "this should be enabled also"); + }); + + finished.assert_finished(); +} + +#[test] +fn not_order_dependent() { + // this test reproduces tokio-rs/tracing#623 + + let filter: EnvFilter = "stuff=debug,info".parse().expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) + .event(event::mock().at_level(Level::WARN).with_target("stuff")) + .event(event::mock().at_level(Level::ERROR)) + .event(event::mock().at_level(Level::ERROR).with_target("stuff")) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!("this should be disabled"); + tracing::info!("this shouldn't be"); + tracing::debug!(target: "stuff", "this should be enabled"); + tracing::debug!("but this shouldn't"); + tracing::trace!(target: "stuff", "and neither should this"); + tracing::warn!(target: "stuff", "this should be enabled"); + tracing::error!("this should be enabled too"); + tracing::error!(target: "stuff", "this should be enabled also"); + }); + + finished.assert_finished(); +} + +#[test] +fn add_directive_enables_event() { + // this test reproduces tokio-rs/tracing#591 + + // by default, use info level + let mut filter = EnvFilter::new(LevelFilter::INFO.to_string()); + + // overwrite with a more specific directive + filter = filter.add_directive("hello=trace".parse().expect("directive should parse")); + + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::INFO).with_target("hello")) + .event(event::mock().at_level(Level::TRACE).with_target("hello")) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::info!(target: "hello", "hello info"); + tracing::trace!(target: "hello", "hello trace"); + }); + + finished.assert_finished(); +} + +#[test] +fn span_name_filter_is_dynamic() { + let filter: EnvFilter = "info,[cool_span]=debug" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::INFO)) + .enter(span::mock().named("cool_span")) + .event(event::mock().at_level(Level::DEBUG)) + .enter(span::mock().named("uncool_span")) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::DEBUG)) + .exit(span::mock().named("uncool_span")) + .exit(span::mock().named("cool_span")) + .enter(span::mock().named("uncool_span")) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .exit(span::mock().named("uncool_span")) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!("this should be disabled"); + tracing::info!("this shouldn't be"); + let cool_span = tracing::info_span!("cool_span"); + let uncool_span = tracing::info_span!("uncool_span"); + + { + let _enter = cool_span.enter(); + tracing::debug!("i'm a cool event"); + tracing::trace!("i'm cool, but not cool enough"); + let _enter2 = uncool_span.enter(); + tracing::warn!("warning: extremely cool!"); + tracing::debug!("i'm still cool"); + } + + let _enter = uncool_span.enter(); + tracing::warn!("warning: not that cool"); + tracing::trace!("im not cool enough"); + tracing::error!("uncool error"); + }); + + finished.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/filter_log.rs b/vendor/tracing-subscriber-0.3.3/tests/filter_log.rs new file mode 100644 index 000000000..28e742501 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/filter_log.rs @@ -0,0 +1,63 @@ +#![cfg(all(feature = "env-filter", feature = "tracing-log"))] +mod support; +use self::support::*; +use tracing::{self, Level}; +use tracing_subscriber::{filter::EnvFilter, prelude::*}; + +mod my_module { + pub(crate) fn test_records() { + log::trace!("this should be disabled"); + log::info!("this shouldn't be"); + log::debug!("this should be disabled"); + log::warn!("this should be enabled"); + log::warn!(target: "something else", "this shouldn't be enabled"); + log::error!("this should be enabled too"); + } + + pub(crate) fn test_log_enabled() { + assert!( + log::log_enabled!(log::Level::Info), + "info should be enabled inside `my_module`" + ); + assert!( + !log::log_enabled!(log::Level::Debug), + "debug should not be enabled inside `my_module`" + ); + assert!( + log::log_enabled!(log::Level::Warn), + "warn should be enabled inside `my_module`" + ); + } +} + +#[test] +fn log_is_enabled() { + let filter: EnvFilter = "filter_log::my_module=info" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + + // Note: we have to set the global default in order to set the `log` max + // level, which can only be set once. + subscriber.with(filter).init(); + + my_module::test_records(); + log::info!("this is disabled"); + + my_module::test_log_enabled(); + assert!( + !log::log_enabled!(log::Level::Info), + "info should not be enabled outside `my_module`" + ); + assert!( + !log::log_enabled!(log::Level::Warn), + "warn should not be enabled outside `my_module`" + ); + + finished.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/fmt_max_level_hint.rs b/vendor/tracing-subscriber-0.3.3/tests/fmt_max_level_hint.rs new file mode 100644 index 000000000..57a0f6e3f --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/fmt_max_level_hint.rs @@ -0,0 +1,10 @@ +#![cfg(feature = "fmt")] +use tracing_subscriber::filter::LevelFilter; + +#[test] +fn fmt_sets_max_level_hint() { + tracing_subscriber::fmt() + .with_max_level(LevelFilter::DEBUG) + .init(); + assert_eq!(LevelFilter::current(), LevelFilter::DEBUG); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/hinted_layer_filters_dont_break_other_layers.rs b/vendor/tracing-subscriber-0.3.3/tests/hinted_layer_filters_dont_break_other_layers.rs new file mode 100644 index 000000000..897dae282 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/hinted_layer_filters_dont_break_other_layers.rs @@ -0,0 +1,131 @@ +#![cfg(feature = "registry")] +mod support; +use self::support::*; +use tracing::{Level, Metadata, Subscriber}; +use tracing_subscriber::{filter::DynFilterFn, layer::Context, prelude::*}; + +#[test] +fn layer_filters() { + let (unfiltered, unfiltered_handle) = unfiltered("unfiltered"); + let (filtered, filtered_handle) = filtered("filtered"); + + let subscriber = tracing_subscriber::registry() + .with(unfiltered) + .with(filtered.with_filter(filter())); + assert_eq!(subscriber.max_level_hint(), None); + let _subscriber = subscriber.set_default(); + + events(); + + unfiltered_handle.assert_finished(); + filtered_handle.assert_finished(); +} + +#[test] +fn layered_layer_filters() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + let unfiltered = unfiltered1.and_then(unfiltered2); + + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + let filtered = filtered1 + .with_filter(filter()) + .and_then(filtered2.with_filter(filter())); + + let subscriber = tracing_subscriber::registry() + .with(unfiltered) + .with(filtered); + assert_eq!(subscriber.max_level_hint(), None); + let _subscriber = subscriber.set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +#[test] +fn out_of_order() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + + let subscriber = tracing_subscriber::registry() + .with(unfiltered1) + .with(filtered1.with_filter(filter())) + .with(unfiltered2) + .with(filtered2.with_filter(filter())); + assert_eq!(subscriber.max_level_hint(), None); + let _subscriber = subscriber.set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +#[test] +fn mixed_layered() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + + let layered1 = filtered1.with_filter(filter()).and_then(unfiltered1); + let layered2 = unfiltered2.and_then(filtered2.with_filter(filter())); + + let subscriber = tracing_subscriber::registry().with(layered1).with(layered2); + assert_eq!(subscriber.max_level_hint(), None); + let _subscriber = subscriber.set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +fn events() { + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); +} + +fn filter() -> DynFilterFn { + DynFilterFn::new( + (|metadata: &Metadata<'_>, _: &tracing_subscriber::layer::Context<'_, S>| { + metadata.level() <= &Level::INFO + }) as fn(&Metadata<'_>, &Context<'_, S>) -> bool, + ) + .with_max_level_hint(Level::INFO) +} + +fn unfiltered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(name) + .event(event::mock().at_level(Level::TRACE)) + .event(event::mock().at_level(Level::DEBUG)) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle() +} + +fn filtered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(name) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle() +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filter_interests_are_cached.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filter_interests_are_cached.rs new file mode 100644 index 000000000..d89d3bf17 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filter_interests_are_cached.rs @@ -0,0 +1,69 @@ +#![cfg(feature = "registry")] +mod support; +use self::support::*; + +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; +use tracing::{Level, Subscriber}; +use tracing_subscriber::{filter, prelude::*}; + +#[test] +fn layer_filter_interests_are_cached() { + let seen = Arc::new(Mutex::new(HashMap::new())); + let seen2 = seen.clone(); + let filter = filter::filter_fn(move |meta| { + *seen + .lock() + .unwrap() + .entry(meta.callsite()) + .or_insert(0usize) += 1; + meta.level() == &Level::INFO + }); + + let (expect, handle) = layer::mock() + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let subscriber = tracing_subscriber::registry().with(expect.with_filter(filter)); + assert!(subscriber.max_level_hint().is_none()); + + let _subscriber = subscriber.set_default(); + + fn events() { + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); + } + + events(); + { + let lock = seen2.lock().unwrap(); + for (callsite, &count) in lock.iter() { + assert_eq!( + count, 1, + "callsite {:?} should have been seen 1 time (after first set of events)", + callsite + ); + } + } + + events(); + { + let lock = seen2.lock().unwrap(); + for (callsite, &count) in lock.iter() { + assert_eq!( + count, 1, + "callsite {:?} should have been seen 1 time (after second set of events)", + callsite + ); + } + } + + handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filters/boxed.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/boxed.rs new file mode 100644 index 000000000..0fe37188e --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/boxed.rs @@ -0,0 +1,42 @@ +use super::*; +use tracing_subscriber::{filter, prelude::*, Layer}; + +fn layer() -> (ExpectLayer, subscriber::MockHandle) { + layer::mock().done().run_with_handle() +} + +fn filter() -> filter::DynFilterFn { + // Use dynamic filter fn to disable interest caching and max-level hints, + // allowing us to put all of these tests in the same file. + filter::dynamic_filter_fn(|_, _| false) +} + +/// reproduces https://github.com/tokio-rs/tracing/issues/1563#issuecomment-921363629 +#[test] +fn box_works() { + let (layer, handle) = layer(); + let layer = Box::new(layer.with_filter(filter())); + + let _guard = tracing_subscriber::registry().with(layer).set_default(); + + for i in 0..2 { + tracing::info!(i); + } + + handle.assert_finished(); +} + +/// the same as `box_works` but with a type-erased `Box`. +#[test] +fn dyn_box_works() { + let (layer, handle) = layer(); + let layer: Box + Send + Sync + 'static> = Box::new(layer.with_filter(filter())); + + let _guard = tracing_subscriber::registry().with(layer).set_default(); + + for i in 0..2 { + tracing::info!(i); + } + + handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filters/downcast_raw.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/downcast_raw.rs new file mode 100644 index 000000000..b5f7e35ce --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/downcast_raw.rs @@ -0,0 +1,68 @@ +use tracing::Subscriber; +use tracing_subscriber::filter::Targets; +use tracing_subscriber::prelude::*; +use tracing_subscriber::Layer; + +#[test] +fn downcast_ref_to_inner_layer_and_filter() { + // Test that a filtered layer gives downcast_ref access to + // both the layer and the filter. + + struct WrappedLayer; + + impl Layer for WrappedLayer + where + S: Subscriber, + S: for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>, + { + } + + let layer = WrappedLayer; + let filter = Targets::new().with_default(tracing::Level::INFO); + let registry = tracing_subscriber::registry().with(layer.with_filter(filter)); + let dispatch = tracing::dispatcher::Dispatch::new(registry); + + // The filter is available + assert!(dispatch.downcast_ref::().is_some()); + // The wrapped layer is available + assert!(dispatch.downcast_ref::().is_some()); +} + +#[test] +fn forward_downcast_raw_to_layer() { + // Test that a filtered layer still gives its wrapped layer a chance to + // return a custom struct from downcast_raw. + // https://github.com/tokio-rs/tracing/issues/1618 + + struct WrappedLayer { + with_context: WithContext, + } + + struct WithContext; + + impl Layer for WrappedLayer + where + S: Subscriber, + S: for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>, + { + unsafe fn downcast_raw(&self, id: std::any::TypeId) -> Option<*const ()> { + match id { + id if id == std::any::TypeId::of::() => Some(self as *const _ as *const ()), + id if id == std::any::TypeId::of::() => { + Some(&self.with_context as *const _ as *const ()) + } + _ => None, + } + } + } + + let layer = WrappedLayer { + with_context: WithContext, + }; + let filter = Targets::new().with_default(tracing::Level::INFO); + let registry = tracing_subscriber::registry().with(layer.with_filter(filter)); + let dispatch = tracing::dispatcher::Dispatch::new(registry); + + // Types from a custom implementation of `downcast_raw` are available + assert!(dispatch.downcast_ref::().is_some()); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filters/filter_scopes.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/filter_scopes.rs new file mode 100644 index 000000000..7fd7d843b --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/filter_scopes.rs @@ -0,0 +1,131 @@ +use super::*; + +#[test] +fn filters_span_scopes() { + let (debug_layer, debug_handle) = layer::named("debug") + .enter(span::mock().at_level(Level::DEBUG)) + .enter(span::mock().at_level(Level::INFO)) + .enter(span::mock().at_level(Level::WARN)) + .enter(span::mock().at_level(Level::ERROR)) + .event(event::msg("hello world").in_scope(vec![ + span::mock().at_level(Level::ERROR), + span::mock().at_level(Level::WARN), + span::mock().at_level(Level::INFO), + span::mock().at_level(Level::DEBUG), + ])) + .exit(span::mock().at_level(Level::ERROR)) + .exit(span::mock().at_level(Level::WARN)) + .exit(span::mock().at_level(Level::INFO)) + .exit(span::mock().at_level(Level::DEBUG)) + .done() + .run_with_handle(); + let (info_layer, info_handle) = layer::named("info") + .enter(span::mock().at_level(Level::INFO)) + .enter(span::mock().at_level(Level::WARN)) + .enter(span::mock().at_level(Level::ERROR)) + .event(event::msg("hello world").in_scope(vec![ + span::mock().at_level(Level::ERROR), + span::mock().at_level(Level::WARN), + span::mock().at_level(Level::INFO), + ])) + .exit(span::mock().at_level(Level::ERROR)) + .exit(span::mock().at_level(Level::WARN)) + .exit(span::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + let (warn_layer, warn_handle) = layer::named("warn") + .enter(span::mock().at_level(Level::WARN)) + .enter(span::mock().at_level(Level::ERROR)) + .event(event::msg("hello world").in_scope(vec![ + span::mock().at_level(Level::ERROR), + span::mock().at_level(Level::WARN), + ])) + .exit(span::mock().at_level(Level::ERROR)) + .exit(span::mock().at_level(Level::WARN)) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(debug_layer.with_filter(LevelFilter::DEBUG)) + .with(info_layer.with_filter(LevelFilter::INFO)) + .with(warn_layer.with_filter(LevelFilter::WARN)) + .set_default(); + + { + let _trace = tracing::trace_span!("my_span").entered(); + let _debug = tracing::debug_span!("my_span").entered(); + let _info = tracing::info_span!("my_span").entered(); + let _warn = tracing::warn_span!("my_span").entered(); + let _error = tracing::error_span!("my_span").entered(); + tracing::error!("hello world"); + } + + debug_handle.assert_finished(); + info_handle.assert_finished(); + warn_handle.assert_finished(); +} + +#[test] +fn filters_interleaved_span_scopes() { + fn target_layer(target: &'static str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(format!("target_{}", target)) + .enter(span::mock().with_target(target)) + .enter(span::mock().with_target(target)) + .event(event::msg("hello world").in_scope(vec![ + span::mock().with_target(target), + span::mock().with_target(target), + ])) + .event( + event::msg("hello to my target") + .in_scope(vec![ + span::mock().with_target(target), + span::mock().with_target(target), + ]) + .with_target(target), + ) + .exit(span::mock().with_target(target)) + .exit(span::mock().with_target(target)) + .done() + .run_with_handle() + } + + let (a_layer, a_handle) = target_layer("a"); + let (b_layer, b_handle) = target_layer("b"); + let (all_layer, all_handle) = layer::named("all") + .enter(span::mock().with_target("b")) + .enter(span::mock().with_target("a")) + .event(event::msg("hello world").in_scope(vec![ + span::mock().with_target("a"), + span::mock().with_target("b"), + ])) + .exit(span::mock().with_target("a")) + .exit(span::mock().with_target("b")) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(all_layer.with_filter(LevelFilter::INFO)) + .with(a_layer.with_filter(filter::filter_fn(|meta| { + let target = meta.target(); + target == "a" || target == module_path!() + }))) + .with(b_layer.with_filter(filter::filter_fn(|meta| { + let target = meta.target(); + target == "b" || target == module_path!() + }))) + .set_default(); + + { + let _a1 = tracing::trace_span!(target: "a", "a/trace").entered(); + let _b1 = tracing::info_span!(target: "b", "b/info").entered(); + let _a2 = tracing::info_span!(target: "a", "a/info").entered(); + let _b2 = tracing::trace_span!(target: "b", "b/trace").entered(); + tracing::info!("hello world"); + tracing::debug!(target: "a", "hello to my target"); + tracing::debug!(target: "b", "hello to my target"); + } + + a_handle.assert_finished(); + b_handle.assert_finished(); + all_handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filters/main.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/main.rs new file mode 100644 index 000000000..2359584d7 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/main.rs @@ -0,0 +1,188 @@ +#![cfg(feature = "registry")] +#[path = "../support.rs"] +mod support; +use self::support::*; +mod boxed; +mod downcast_raw; +mod filter_scopes; +mod targets; +mod trees; + +use tracing::{level_filters::LevelFilter, Level}; +use tracing_subscriber::{filter, prelude::*}; + +#[test] +fn basic_layer_filters() { + let (trace_layer, trace_handle) = layer::named("trace") + .event(event::mock().at_level(Level::TRACE)) + .event(event::mock().at_level(Level::DEBUG)) + .event(event::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let (debug_layer, debug_handle) = layer::named("debug") + .event(event::mock().at_level(Level::DEBUG)) + .event(event::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let (info_layer, info_handle) = layer::named("info") + .event(event::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(trace_layer.with_filter(LevelFilter::TRACE)) + .with(debug_layer.with_filter(LevelFilter::DEBUG)) + .with(info_layer.with_filter(LevelFilter::INFO)) + .set_default(); + + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + + trace_handle.assert_finished(); + debug_handle.assert_finished(); + info_handle.assert_finished(); +} + +#[test] +fn basic_layer_filters_spans() { + let (trace_layer, trace_handle) = layer::named("trace") + .new_span(span::mock().at_level(Level::TRACE)) + .new_span(span::mock().at_level(Level::DEBUG)) + .new_span(span::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let (debug_layer, debug_handle) = layer::named("debug") + .new_span(span::mock().at_level(Level::DEBUG)) + .new_span(span::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let (info_layer, info_handle) = layer::named("info") + .new_span(span::mock().at_level(Level::INFO)) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(trace_layer.with_filter(LevelFilter::TRACE)) + .with(debug_layer.with_filter(LevelFilter::DEBUG)) + .with(info_layer.with_filter(LevelFilter::INFO)) + .set_default(); + + tracing::trace_span!("hello trace"); + tracing::debug_span!("hello debug"); + tracing::info_span!("hello info"); + + trace_handle.assert_finished(); + debug_handle.assert_finished(); + info_handle.assert_finished(); +} + +#[test] +fn global_filters_layers_still_work() { + let (expect, handle) = layer::mock() + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(expect) + .with(LevelFilter::INFO) + .set_default(); + + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); + + handle.assert_finished(); +} + +#[test] +fn global_filter_interests_are_cached() { + let (expect, handle) = layer::mock() + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(expect.with_filter(filter::filter_fn(|meta| { + assert!( + meta.level() <= &Level::INFO, + "enabled should not be called for callsites disabled by the global filter" + ); + meta.level() <= &Level::WARN + }))) + .with(LevelFilter::INFO) + .set_default(); + + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); + + handle.assert_finished(); +} + +#[test] +fn global_filters_affect_layer_filters() { + let (expect, handle) = layer::named("debug") + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(expect.with_filter(LevelFilter::DEBUG)) + .with(LevelFilter::INFO) + .set_default(); + + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); + + handle.assert_finished(); +} + +#[test] +fn filter_fn() { + let (all, all_handle) = layer::named("all_targets") + .event(event::msg("hello foo")) + .event(event::msg("hello bar")) + .done() + .run_with_handle(); + + let (foo, foo_handle) = layer::named("foo_target") + .event(event::msg("hello foo")) + .done() + .run_with_handle(); + + let (bar, bar_handle) = layer::named("bar_target") + .event(event::msg("hello bar")) + .done() + .run_with_handle(); + + let _subscriber = tracing_subscriber::registry() + .with(all) + .with(foo.with_filter(filter::filter_fn(|meta| meta.target().starts_with("foo")))) + .with(bar.with_filter(filter::filter_fn(|meta| meta.target().starts_with("bar")))) + .set_default(); + + tracing::trace!(target: "foo", "hello foo"); + tracing::trace!(target: "bar", "hello bar"); + + foo_handle.assert_finished(); + bar_handle.assert_finished(); + all_handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filters/targets.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/targets.rs new file mode 100644 index 000000000..c8133044b --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/targets.rs @@ -0,0 +1,59 @@ +use super::*; +use tracing_subscriber::{ + filter::{filter_fn, Targets}, + prelude::*, +}; + +#[test] +#[cfg_attr(not(feature = "tracing-log"), ignore)] +fn log_events() { + // Reproduces https://github.com/tokio-rs/tracing/issues/1563 + mod inner { + pub(super) const MODULE_PATH: &str = module_path!(); + + #[tracing::instrument] + pub(super) fn logs() { + log::debug!("inner"); + } + } + + let filter = Targets::new() + .with_default(LevelFilter::DEBUG) + .with_target(inner::MODULE_PATH, LevelFilter::WARN); + + let layer = + tracing_subscriber::layer::Identity::new().with_filter(filter_fn(move |_meta| true)); + + let _guard = tracing_subscriber::registry() + .with(filter) + .with(layer) + .set_default(); + + inner::logs(); +} + +#[test] +fn inner_layer_short_circuits() { + // This test ensures that when a global filter short-circuits `Interest` + // evaluation, we aren't left with a "dirty" per-layer filter state. + + let (layer, handle) = layer::mock() + .event(event::msg("hello world")) + .done() + .run_with_handle(); + + let filter = Targets::new().with_target("magic_target", LevelFilter::DEBUG); + + let _guard = tracing_subscriber::registry() + // Note: we don't just use a `LevelFilter` for the global filter here, + // because it will just return a max level filter, and the chain of + // `register_callsite` calls that would trigger the bug never happens... + .with(filter::filter_fn(|meta| meta.level() <= &Level::INFO)) + .with(layer.with_filter(filter)) + .set_default(); + + tracing::debug!("skip me please!"); + tracing::info!(target: "magic_target", "hello world"); + + handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/layer_filters/trees.rs b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/trees.rs new file mode 100644 index 000000000..18cdd8ccc --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/layer_filters/trees.rs @@ -0,0 +1,146 @@ +use super::*; + +#[test] +fn basic_trees() { + let (with_target, with_target_handle) = layer::named("info_with_target") + .event(event::mock().at_level(Level::INFO).with_target("my_target")) + .done() + .run_with_handle(); + + let (info, info_handle) = layer::named("info") + .event( + event::mock() + .at_level(Level::INFO) + .with_target(module_path!()), + ) + .event(event::mock().at_level(Level::INFO).with_target("my_target")) + .done() + .run_with_handle(); + + let (all, all_handle) = layer::named("all") + .event( + event::mock() + .at_level(Level::INFO) + .with_target(module_path!()), + ) + .event(event::mock().at_level(Level::TRACE)) + .event(event::mock().at_level(Level::INFO).with_target("my_target")) + .event( + event::mock() + .at_level(Level::TRACE) + .with_target("my_target"), + ) + .done() + .run_with_handle(); + + let info_tree = info + .and_then( + with_target.with_filter(filter::filter_fn(|meta| dbg!(meta.target()) == "my_target")), + ) + .with_filter(LevelFilter::INFO); + + let subscriber = tracing_subscriber::registry().with(info_tree).with(all); + let _guard = dbg!(subscriber).set_default(); + + tracing::info!("hello world"); + tracing::trace!("hello trace"); + tracing::info!(target: "my_target", "hi to my target"); + tracing::trace!(target: "my_target", "hi to my target at trace"); + + all_handle.assert_finished(); + info_handle.assert_finished(); + with_target_handle.assert_finished(); +} + +#[test] +fn filter_span_scopes() { + fn target_layer(target: &'static str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(format!("target_{}", target)) + .enter(span::mock().with_target(target).at_level(Level::INFO)) + .event( + event::msg("hello world") + .in_scope(vec![span::mock().with_target(target).at_level(Level::INFO)]), + ) + .exit(span::mock().with_target(target).at_level(Level::INFO)) + .done() + .run_with_handle() + } + + let (a_layer, a_handle) = target_layer("a"); + let (b_layer, b_handle) = target_layer("b"); + let (info_layer, info_handle) = layer::named("info") + .enter(span::mock().with_target("b").at_level(Level::INFO)) + .enter(span::mock().with_target("a").at_level(Level::INFO)) + .event(event::msg("hello world").in_scope(vec![ + span::mock().with_target("a").at_level(Level::INFO), + span::mock().with_target("b").at_level(Level::INFO), + ])) + .exit(span::mock().with_target("a").at_level(Level::INFO)) + .exit(span::mock().with_target("b").at_level(Level::INFO)) + .done() + .run_with_handle(); + + let full_scope = vec![ + span::mock().with_target("b").at_level(Level::TRACE), + span::mock().with_target("a").at_level(Level::INFO), + span::mock().with_target("b").at_level(Level::INFO), + span::mock().with_target("a").at_level(Level::TRACE), + ]; + let (all_layer, all_handle) = layer::named("all") + .enter(span::mock().with_target("a").at_level(Level::TRACE)) + .enter(span::mock().with_target("b").at_level(Level::INFO)) + .enter(span::mock().with_target("a").at_level(Level::INFO)) + .enter(span::mock().with_target("b").at_level(Level::TRACE)) + .event(event::msg("hello world").in_scope(full_scope.clone())) + .event( + event::msg("hello to my target") + .with_target("a") + .in_scope(full_scope.clone()), + ) + .event( + event::msg("hello to my target") + .with_target("b") + .in_scope(full_scope), + ) + .exit(span::mock().with_target("b").at_level(Level::TRACE)) + .exit(span::mock().with_target("a").at_level(Level::INFO)) + .exit(span::mock().with_target("b").at_level(Level::INFO)) + .exit(span::mock().with_target("a").at_level(Level::TRACE)) + .done() + .run_with_handle(); + + let a_layer = a_layer.with_filter(filter::filter_fn(|meta| { + let target = meta.target(); + target == "a" || target == module_path!() + })); + + let b_layer = b_layer.with_filter(filter::filter_fn(|meta| { + let target = meta.target(); + target == "b" || target == module_path!() + })); + + let info_tree = info_layer + .and_then(a_layer) + .and_then(b_layer) + .with_filter(LevelFilter::INFO); + + let subscriber = tracing_subscriber::registry() + .with(info_tree) + .with(all_layer); + let _guard = dbg!(subscriber).set_default(); + + { + let _a1 = tracing::trace_span!(target: "a", "a/trace").entered(); + let _b1 = tracing::info_span!(target: "b", "b/info").entered(); + let _a2 = tracing::info_span!(target: "a", "a/info").entered(); + let _b2 = tracing::trace_span!(target: "b", "b/trace").entered(); + tracing::info!("hello world"); + tracing::debug!(target: "a", "hello to my target"); + tracing::debug!(target: "b", "hello to my target"); + } + + all_handle.assert_finished(); + info_handle.assert_finished(); + a_handle.assert_finished(); + b_handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/multiple_layer_filter_interests_cached.rs b/vendor/tracing-subscriber-0.3.3/tests/multiple_layer_filter_interests_cached.rs new file mode 100644 index 000000000..5c25e7f03 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/multiple_layer_filter_interests_cached.rs @@ -0,0 +1,131 @@ +#![cfg(feature = "registry")] +mod support; +use self::support::*; + +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; +use tracing::{Level, Subscriber}; +use tracing_subscriber::{filter, prelude::*}; + +#[test] +fn multiple_layer_filter_interests_are_cached() { + // This layer will return Interest::always for INFO and lower. + let seen_info = Arc::new(Mutex::new(HashMap::new())); + let seen_info2 = seen_info.clone(); + let filter = filter::filter_fn(move |meta| { + *seen_info + .lock() + .unwrap() + .entry(*meta.level()) + .or_insert(0usize) += 1; + meta.level() <= &Level::INFO + }); + let seen_info = seen_info2; + + let (info_layer, info_handle) = layer::named("info") + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + let info_layer = info_layer.with_filter(filter); + + // This layer will return Interest::always for WARN and lower. + let seen_warn = Arc::new(Mutex::new(HashMap::new())); + let seen_warn2 = seen_warn.clone(); + let filter = filter::filter_fn(move |meta| { + *seen_warn + .lock() + .unwrap() + .entry(*meta.level()) + .or_insert(0usize) += 1; + meta.level() <= &Level::WARN + }); + let seen_warn = seen_warn2; + + let (warn_layer, warn_handle) = layer::named("warn") + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + let warn_layer = warn_layer.with_filter(filter); + + let subscriber = tracing_subscriber::registry() + .with(warn_layer) + .with(info_layer); + assert!(subscriber.max_level_hint().is_none()); + + let _subscriber = subscriber.set_default(); + + fn events() { + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); + } + + events(); + { + let lock = seen_info.lock().unwrap(); + for (&level, &count) in lock.iter() { + if level == Level::INFO { + continue; + } + assert_eq!( + count, 1, + "level {:?} should have been seen 1 time by the INFO layer (after first set of events)", + level + ); + } + + let lock = seen_warn.lock().unwrap(); + for (&level, &count) in lock.iter() { + if level == Level::INFO { + continue; + } + assert_eq!( + count, 1, + "level {:?} should have been seen 1 time by the WARN layer (after first set of events)", + level + ); + } + } + + events(); + { + let lock = seen_info.lock().unwrap(); + for (&level, &count) in lock.iter() { + if level == Level::INFO { + continue; + } + assert_eq!( + count, 1, + "level {:?} should have been seen 1 time by the INFO layer (after second set of events)", + level + ); + } + + let lock = seen_warn.lock().unwrap(); + for (&level, &count) in lock.iter() { + if level == Level::INFO { + continue; + } + assert_eq!( + count, 1, + "level {:?} should have been seen 1 time by the WARN layer (after second set of events)", + level + ); + } + } + + info_handle.assert_finished(); + warn_handle.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/registry_max_level_hint.rs b/vendor/tracing-subscriber-0.3.3/tests/registry_max_level_hint.rs new file mode 100644 index 000000000..f94c8a1fb --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/registry_max_level_hint.rs @@ -0,0 +1,11 @@ +#![cfg(all(feature = "registry", feature = "fmt"))] +use tracing_subscriber::{filter::LevelFilter, prelude::*}; + +#[test] +fn registry_sets_max_level_hint() { + tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer()) + .with(LevelFilter::DEBUG) + .init(); + assert_eq!(LevelFilter::current(), LevelFilter::DEBUG); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/registry_with_subscriber.rs b/vendor/tracing-subscriber-0.3.3/tests/registry_with_subscriber.rs new file mode 100644 index 000000000..3f8d99b1d --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/registry_with_subscriber.rs @@ -0,0 +1,25 @@ +#![cfg(feature = "registry")] +use tracing_futures::{Instrument, WithSubscriber}; +use tracing_subscriber::prelude::*; + +#[tokio::test] +async fn future_with_subscriber() { + let _default = tracing_subscriber::registry().init(); + let span = tracing::info_span!("foo"); + let _e = span.enter(); + let span = tracing::info_span!("bar"); + let _e = span.enter(); + tokio::spawn( + async { + async { + let span = tracing::Span::current(); + println!("{:?}", span); + } + .instrument(tracing::info_span!("hi")) + .await + } + .with_subscriber(tracing_subscriber::registry()), + ) + .await + .unwrap(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/reload.rs b/vendor/tracing-subscriber-0.3.3/tests/reload.rs new file mode 100644 index 000000000..5fe422e08 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/reload.rs @@ -0,0 +1,81 @@ +#![cfg(feature = "reload")] +use std::sync::atomic::{AtomicUsize, Ordering}; +use tracing_core::{ + span::{Attributes, Id, Record}, + subscriber::Interest, + Event, Metadata, Subscriber, +}; +use tracing_subscriber::{layer, prelude::*, reload::*}; + +pub struct NopSubscriber; + +impl Subscriber for NopSubscriber { + fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { + Interest::never() + } + + fn enabled(&self, _: &Metadata<'_>) -> bool { + false + } + + fn new_span(&self, _: &Attributes<'_>) -> Id { + Id::from_u64(1) + } + + fn record(&self, _: &Id, _: &Record<'_>) {} + fn record_follows_from(&self, _: &Id, _: &Id) {} + fn event(&self, _: &Event<'_>) {} + fn enter(&self, _: &Id) {} + fn exit(&self, _: &Id) {} +} + +#[test] +fn reload_handle() { + static FILTER1_CALLS: AtomicUsize = AtomicUsize::new(0); + static FILTER2_CALLS: AtomicUsize = AtomicUsize::new(0); + + enum Filter { + One, + Two, + } + + impl tracing_subscriber::Layer for Filter { + fn register_callsite(&self, m: &Metadata<'_>) -> Interest { + println!("REGISTER: {:?}", m); + Interest::sometimes() + } + + fn enabled(&self, m: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { + println!("ENABLED: {:?}", m); + match self { + Filter::One => FILTER1_CALLS.fetch_add(1, Ordering::SeqCst), + Filter::Two => FILTER2_CALLS.fetch_add(1, Ordering::SeqCst), + }; + true + } + } + fn event() { + tracing::trace!("my event"); + } + + let (layer, handle) = Layer::new(Filter::One); + + let subscriber = tracing_core::dispatcher::Dispatch::new(layer.with_subscriber(NopSubscriber)); + + tracing_core::dispatcher::with_default(&subscriber, || { + assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 0); + assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0); + + event(); + + assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1); + assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0); + + handle.reload(Filter::Two).expect("should reload"); + + event(); + + assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1); + assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 1); + }) +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/same_len_filters.rs b/vendor/tracing-subscriber-0.3.3/tests/same_len_filters.rs new file mode 100644 index 000000000..b525ea6fd --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/same_len_filters.rs @@ -0,0 +1,81 @@ +// These tests include field filters with no targets, so they have to go in a +// separate file. +#![cfg(feature = "env-filter")] +mod support; +use self::support::*; +use tracing::{self, subscriber::with_default, Level}; +use tracing_subscriber::{filter::EnvFilter, prelude::*}; + +#[test] +fn same_length_targets() { + let filter: EnvFilter = "foo=trace,bar=trace".parse().expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event(event::mock().at_level(Level::TRACE)) + .event(event::mock().at_level(Level::TRACE)) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + + with_default(subscriber, || { + tracing::trace!(target: "foo", "foo"); + tracing::trace!(target: "bar", "bar"); + }); + + finished.assert_finished(); +} + +#[test] +fn same_num_fields_event() { + let filter: EnvFilter = "[{foo}]=trace,[{bar}]=trace" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .event( + event::mock() + .at_level(Level::TRACE) + .with_fields(field::mock("foo")), + ) + .event( + event::mock() + .at_level(Level::TRACE) + .with_fields(field::mock("bar")), + ) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + with_default(subscriber, || { + tracing::trace!(foo = 1); + tracing::trace!(bar = 3); + }); + + finished.assert_finished(); +} + +#[test] +fn same_num_fields_and_name_len() { + let filter: EnvFilter = "[foo{bar=1}]=trace,[baz{boz=1}]=trace" + .parse() + .expect("filter should parse"); + let (subscriber, finished) = subscriber::mock() + .new_span( + span::mock() + .named("foo") + .at_level(Level::TRACE) + .with_field(field::mock("bar")), + ) + .new_span( + span::mock() + .named("baz") + .at_level(Level::TRACE) + .with_field(field::mock("boz")), + ) + .done() + .run_with_handle(); + let subscriber = subscriber.with(filter); + with_default(subscriber, || { + tracing::trace_span!("foo", bar = 1); + tracing::trace_span!("baz", boz = 1); + }); + + finished.assert_finished(); +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/support.rs b/vendor/tracing-subscriber-0.3.3/tests/support.rs new file mode 100644 index 000000000..848ebdc63 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/support.rs @@ -0,0 +1,412 @@ +#![allow(missing_docs, dead_code)] +pub use self::support::{event, field, span, subscriber}; +// This has to have the same name as the module in `tracing`. +// path attribute requires referenced module to have same name so allow module inception here +#[allow(clippy::module_inception)] +#[path = "../../tracing/tests/support/mod.rs"] +mod support; + +use self::{ + event::MockEvent, + span::{MockSpan, NewSpan}, + subscriber::{Expect, MockHandle}, +}; +use tracing_core::{ + span::{Attributes, Id, Record}, + Event, Subscriber, +}; +use tracing_subscriber::{ + layer::{Context, Layer}, + registry::{LookupSpan, SpanRef}, +}; + +use std::{ + collections::VecDeque, + fmt, + sync::{Arc, Mutex}, +}; + +pub mod layer { + use super::ExpectLayerBuilder; + + pub fn mock() -> ExpectLayerBuilder { + ExpectLayerBuilder { + expected: Default::default(), + name: std::thread::current() + .name() + .map(String::from) + .unwrap_or_default(), + } + } + + pub fn named(name: impl std::fmt::Display) -> ExpectLayerBuilder { + mock().named(name) + } +} + +pub struct ExpectLayerBuilder { + expected: VecDeque, + name: String, +} + +pub struct ExpectLayer { + expected: Arc>>, + current: Mutex>, + name: String, +} + +impl ExpectLayerBuilder { + /// Overrides the name printed by the mock subscriber's debugging output. + /// + /// The debugging output is displayed if the test panics, or if the test is + /// run with `--nocapture`. + /// + /// By default, the mock subscriber's name is the name of the test + /// (*technically*, the name of the thread where it was created, which is + /// the name of the test unless tests are run with `--test-threads=1`). + /// When a test has only one mock subscriber, this is sufficient. However, + /// some tests may include multiple subscribers, in order to test + /// interactions between multiple subscribers. In that case, it can be + /// helpful to give each subscriber a separate name to distinguish where the + /// debugging output comes from. + pub fn named(mut self, name: impl fmt::Display) -> Self { + use std::fmt::Write; + if !self.name.is_empty() { + write!(&mut self.name, "::{}", name).unwrap(); + } else { + self.name = name.to_string(); + } + self + } + + pub fn enter(mut self, span: MockSpan) -> Self { + self.expected.push_back(Expect::Enter(span)); + self + } + + pub fn event(mut self, event: MockEvent) -> Self { + self.expected.push_back(Expect::Event(event)); + self + } + + pub fn exit(mut self, span: MockSpan) -> Self { + self.expected.push_back(Expect::Exit(span)); + self + } + + pub fn done(mut self) -> Self { + self.expected.push_back(Expect::Nothing); + self + } + + pub fn record(mut self, span: MockSpan, fields: I) -> Self + where + I: Into, + { + self.expected.push_back(Expect::Visit(span, fields.into())); + self + } + + pub fn new_span(mut self, new_span: I) -> Self + where + I: Into, + { + self.expected.push_back(Expect::NewSpan(new_span.into())); + self + } + + pub fn run(self) -> ExpectLayer { + ExpectLayer { + expected: Arc::new(Mutex::new(self.expected)), + name: self.name, + current: Mutex::new(Vec::new()), + } + } + + pub fn run_with_handle(self) -> (ExpectLayer, MockHandle) { + let expected = Arc::new(Mutex::new(self.expected)); + let handle = MockHandle::new(expected.clone(), self.name.clone()); + let layer = ExpectLayer { + expected, + name: self.name, + current: Mutex::new(Vec::new()), + }; + (layer, handle) + } +} + +impl ExpectLayer { + fn check_span_ref<'spans, S>( + &self, + expected: &MockSpan, + actual: &SpanRef<'spans, S>, + what_happened: impl fmt::Display, + ) where + S: LookupSpan<'spans>, + { + if let Some(exp_name) = expected.name() { + assert_eq!( + actual.name(), + exp_name, + "\n[{}] expected {} a span named {:?}\n\ + [{}] but it was named {:?} instead (span {} {:?})", + self.name, + what_happened, + exp_name, + self.name, + actual.name(), + actual.name(), + actual.id() + ); + } + + if let Some(exp_level) = expected.level() { + let actual_level = actual.metadata().level(); + assert_eq!( + actual_level, + &exp_level, + "\n[{}] expected {} a span at {:?}\n\ + [{}] but it was at {:?} instead (span {} {:?})", + self.name, + what_happened, + exp_level, + self.name, + actual_level, + actual.name(), + actual.id(), + ); + } + + if let Some(exp_target) = expected.target() { + let actual_target = actual.metadata().target(); + assert_eq!( + actual_target, + exp_target, + "\n[{}] expected {} a span with target {:?}\n\ + [{}] but it had the target {:?} instead (span {} {:?})", + self.name, + what_happened, + exp_target, + self.name, + actual_target, + actual.name(), + actual.id(), + ); + } + } +} + +impl Layer for ExpectLayer +where + S: Subscriber + for<'a> LookupSpan<'a>, +{ + fn register_callsite( + &self, + metadata: &'static tracing::Metadata<'static>, + ) -> tracing_core::Interest { + println!("[{}] register_callsite {:#?}", self.name, metadata); + tracing_core::Interest::always() + } + + fn on_record(&self, _: &Id, _: &Record<'_>, _: Context<'_, S>) { + unimplemented!( + "so far, we don't have any tests that need an `on_record` \ + implementation.\nif you just wrote one that does, feel free to \ + implement it!" + ); + } + + fn on_event(&self, event: &Event<'_>, cx: Context<'_, S>) { + let name = event.metadata().name(); + println!( + "[{}] event: {}; level: {}; target: {}", + self.name, + name, + event.metadata().level(), + event.metadata().target(), + ); + match self.expected.lock().unwrap().pop_front() { + None => {} + Some(Expect::Event(mut expected)) => { + let get_parent_name = || cx.event_span(event).map(|span| span.name().to_string()); + expected.check(event, get_parent_name, &self.name); + let mut current_scope = cx.event_scope(event).into_iter().flatten(); + let expected_scope = expected.scope_mut(); + let mut i = 0; + for (expected, actual) in expected_scope.iter_mut().zip(&mut current_scope) { + println!( + "[{}] event_scope[{}] actual={} ({:?}); expected={}", + self.name, + i, + actual.name(), + actual.id(), + expected + ); + self.check_span_ref( + expected, + &actual, + format_args!("the {}th span in the event's scope to be", i), + ); + i += 1; + } + let remaining_expected = &expected_scope[i..]; + assert!( + remaining_expected.is_empty(), + "\n[{}] did not observe all expected spans in event scope!\n[{}] missing: {:#?}", + self.name, + self.name, + remaining_expected, + ); + assert!( + current_scope.next().is_none(), + "\n[{}] did not expect all spans in the actual event scope!", + self.name, + ); + } + Some(ex) => ex.bad(&self.name, format_args!("observed event {:#?}", event)), + } + } + + fn on_follows_from(&self, _span: &Id, _follows: &Id, _: Context<'_, S>) { + // TODO: it should be possible to expect spans to follow from other spans + } + + fn on_new_span(&self, span: &Attributes<'_>, id: &Id, cx: Context<'_, S>) { + let meta = span.metadata(); + println!( + "[{}] new_span: name={:?}; target={:?}; id={:?};", + self.name, + meta.name(), + meta.target(), + id + ); + let mut expected = self.expected.lock().unwrap(); + let was_expected = matches!(expected.front(), Some(Expect::NewSpan(_))); + if was_expected { + if let Expect::NewSpan(mut expected) = expected.pop_front().unwrap() { + let get_parent_name = || { + span.parent() + .and_then(|id| cx.span(id)) + .or_else(|| cx.lookup_current()) + .map(|span| span.name().to_string()) + }; + expected.check(span, get_parent_name, &self.name); + } + } + } + + fn on_enter(&self, id: &Id, cx: Context<'_, S>) { + let span = cx + .span(id) + .unwrap_or_else(|| panic!("[{}] no span for ID {:?}", self.name, id)); + println!("[{}] enter: {}; id={:?};", self.name, span.name(), id); + match self.expected.lock().unwrap().pop_front() { + None => {} + Some(Expect::Enter(ref expected_span)) => { + self.check_span_ref(expected_span, &span, "to enter"); + } + Some(ex) => ex.bad(&self.name, format_args!("entered span {:?}", span.name())), + } + self.current.lock().unwrap().push(id.clone()); + } + + fn on_exit(&self, id: &Id, cx: Context<'_, S>) { + if std::thread::panicking() { + // `exit()` can be called in `drop` impls, so we must guard against + // double panics. + println!("[{}] exit {:?} while panicking", self.name, id); + return; + } + let span = cx + .span(id) + .unwrap_or_else(|| panic!("[{}] no span for ID {:?}", self.name, id)); + println!("[{}] exit: {}; id={:?};", self.name, span.name(), id); + match self.expected.lock().unwrap().pop_front() { + None => {} + Some(Expect::Exit(ref expected_span)) => { + self.check_span_ref(expected_span, &span, "to exit"); + let curr = self.current.lock().unwrap().pop(); + assert_eq!( + Some(id), + curr.as_ref(), + "[{}] exited span {:?}, but the current span was {:?}", + self.name, + span.name(), + curr.as_ref().and_then(|id| cx.span(id)).map(|s| s.name()) + ); + } + Some(ex) => ex.bad(&self.name, format_args!("exited span {:?}", span.name())), + }; + } + + fn on_close(&self, id: Id, cx: Context<'_, S>) { + if std::thread::panicking() { + // `try_close` can be called in `drop` impls, so we must guard against + // double panics. + println!("[{}] close {:?} while panicking", self.name, id); + return; + } + let span = cx.span(&id); + let name = span.as_ref().map(|span| { + println!("[{}] close_span: {}; id={:?};", self.name, span.name(), id,); + span.name() + }); + if name.is_none() { + println!("[{}] drop_span: id={:?}", self.name, id); + } + if let Ok(mut expected) = self.expected.try_lock() { + let was_expected = match expected.front() { + Some(Expect::DropSpan(ref expected_span)) => { + // Don't assert if this function was called while panicking, + // as failing the assertion can cause a double panic. + if !::std::thread::panicking() { + if let Some(ref span) = span { + self.check_span_ref(expected_span, span, "to close"); + } + } + true + } + Some(Expect::Event(_)) => { + if !::std::thread::panicking() { + panic!( + "[{}] expected an event, but dropped span {} (id={:?}) instead", + self.name, + name.unwrap_or(""), + id + ); + } + true + } + _ => false, + }; + if was_expected { + expected.pop_front(); + } + } + } + + fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>) { + panic!("well-behaved subscribers should never do this to us, lol"); + } +} + +impl fmt::Debug for ExpectLayer { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("ExpectLayer"); + s.field("name", &self.name); + + if let Ok(expected) = self.expected.try_lock() { + s.field("expected", &expected); + } else { + s.field("expected", &format_args!("")); + } + + if let Ok(current) = self.current.try_lock() { + s.field("current", &format_args!("{:?}", ¤t)); + } else { + s.field("current", &format_args!("")); + } + + s.finish() + } +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/unhinted_layer_filters_dont_break_other_layers.rs b/vendor/tracing-subscriber-0.3.3/tests/unhinted_layer_filters_dont_break_other_layers.rs new file mode 100644 index 000000000..9fa5c6bd4 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/unhinted_layer_filters_dont_break_other_layers.rs @@ -0,0 +1,123 @@ +#![cfg(feature = "registry")] +mod support; +use self::support::*; +use tracing::Level; +use tracing_subscriber::{filter::DynFilterFn, prelude::*}; + +#[test] +fn layer_filters() { + let (unfiltered, unfiltered_handle) = unfiltered("unfiltered"); + let (filtered, filtered_handle) = filtered("filtered"); + + let _subscriber = tracing_subscriber::registry() + .with(unfiltered) + .with(filtered.with_filter(filter())) + .set_default(); + + events(); + + unfiltered_handle.assert_finished(); + filtered_handle.assert_finished(); +} + +#[test] +fn layered_layer_filters() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + let unfiltered = unfiltered1.and_then(unfiltered2); + + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + let filtered = filtered1 + .with_filter(filter()) + .and_then(filtered2.with_filter(filter())); + + let _subscriber = tracing_subscriber::registry() + .with(unfiltered) + .with(filtered) + .set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +#[test] +fn out_of_order() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + + let _subscriber = tracing_subscriber::registry() + .with(unfiltered1) + .with(filtered1.with_filter(filter())) + .with(unfiltered2) + .with(filtered2.with_filter(filter())) + .set_default(); + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +#[test] +fn mixed_layered() { + let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); + let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); + let (filtered1, filtered1_handle) = filtered("filtered_1"); + let (filtered2, filtered2_handle) = filtered("filtered_2"); + + let layered1 = filtered1.with_filter(filter()).and_then(unfiltered1); + let layered2 = unfiltered2.and_then(filtered2.with_filter(filter())); + + let _subscriber = tracing_subscriber::registry() + .with(layered1) + .with(layered2) + .set_default(); + + events(); + + unfiltered1_handle.assert_finished(); + unfiltered2_handle.assert_finished(); + filtered1_handle.assert_finished(); + filtered2_handle.assert_finished(); +} + +fn events() { + tracing::trace!("hello trace"); + tracing::debug!("hello debug"); + tracing::info!("hello info"); + tracing::warn!("hello warn"); + tracing::error!("hello error"); +} + +fn filter() -> DynFilterFn { + DynFilterFn::new(|metadata, _| metadata.level() <= &Level::INFO) +} + +fn unfiltered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(name) + .event(event::mock().at_level(Level::TRACE)) + .event(event::mock().at_level(Level::DEBUG)) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle() +} + +fn filtered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { + layer::named(name) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle() +} diff --git a/vendor/tracing-subscriber-0.3.3/tests/utils.rs b/vendor/tracing-subscriber-0.3.3/tests/utils.rs new file mode 100644 index 000000000..ff025a2a2 --- /dev/null +++ b/vendor/tracing-subscriber-0.3.3/tests/utils.rs @@ -0,0 +1,39 @@ +#![cfg(feature = "std")] +mod support; +use self::support::*; +use tracing_subscriber::prelude::*; + +#[test] +fn init_ext_works() { + let (subscriber, finished) = subscriber::mock() + .event( + event::mock() + .at_level(tracing::Level::INFO) + .with_target("init_works"), + ) + .done() + .run_with_handle(); + + let _guard = subscriber.set_default(); + tracing::info!(target: "init_works", "it worked!"); + finished.assert_finished(); +} + +#[test] +#[cfg(feature = "fmt")] +fn builders_are_init_ext() { + tracing_subscriber::fmt().set_default(); + let _ = tracing_subscriber::fmt() + .with_target(false) + .compact() + .try_init(); +} + +#[test] +#[cfg(all(feature = "fmt", feature = "env-filter"))] +fn layered_is_init_ext() { + tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer()) + .with(tracing_subscriber::EnvFilter::new("foo=info")) + .set_default(); +} diff --git a/vendor/tracing-subscriber/.cargo-checksum.json b/vendor/tracing-subscriber/.cargo-checksum.json deleted file mode 100644 index 6c6c14337..000000000 --- a/vendor/tracing-subscriber/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"299c9f1c6c293156f3d0b9cd203c676b40ae173c9b1c2ee32ad360c1c11351b7","Cargo.toml":"488b9c72556062f1b1a8eca5d98bbe369f2e54fb103e9a23a0c2885e4bb8a086","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"b34fd001abef8b8e1455ad0f1f5e8e13eb578aafc60ea877772adb4c2c9fc39a","benches/enter.rs":"4a94a04e2abd07950ef2f0b646f4dcdf4ff00abf6396edb5a53c8b41b7691b1a","benches/filter.rs":"6374005ffa47fa19880bb95e3e37406f40ea72a02c5136f4d5eb4c663d452b18","benches/filter_log.rs":"612716bdf9a188093e84d014a4847f18157f148f7d64e54150cd5c91ac709a8a","benches/fmt.rs":"5a0ff37967ffef3a221eebb78855d031e2e883a8a67528c8e794cc6f16cbee8a","benches/support/mod.rs":"72bef51154da9c9b3d81300195c1929a818858fa4b4fc2aa07b49ca586f4cd39","src/field/debug.rs":"4ab50198a0b042d92fefa77b5cac0aef7ba6936149fa555f4b6e2036dcd7f2d7","src/field/delimited.rs":"5e7967637dc3181c097637dcb2a95f35db16583b5fc293b30211db5779ab21ab","src/field/display.rs":"da8cfcb22a39f451f075e2c3a9ce5193c6afe19853cdbd643239657cac5b7e47","src/field/mod.rs":"cb8ab273159f42fc8ebe71c82acc63c962e546328fc4aa9fd5948ce996ef9e05","src/filter/directive.rs":"6341c3a1c8b6d33171647964c35816317c81b03bb098b493f1f1a22222f6ce84","src/filter/env/builder.rs":"8f527b1b0e3d9c572046235e0304146a574fe114b757af90a1c07851a07ba2cf","src/filter/env/directive.rs":"ecd2a7ffb882869f8ea9b0398f5af58ce1797a216b9dc9086c21363d1d500e77","src/filter/env/field.rs":"e1e32a2fc39884c9a5df1d5047128e43f1d0720c0b9daa6bf1e08ca9bcc5f537","src/filter/env/mod.rs":"8403df3f061a1c266b6ab6b30b03c6eb32c1c9354037a2d1eeb36817932e6ea5","src/filter/filter_fn.rs":"0debbc4a4b4d2a57b2a06905017ac908bf34b0a64aaf961535fbf6f4d5a700a9","src/filter/layer_filters/combinator.rs":"abf90b8d7a21486b28f20d4b648395b2b95a35b526bbdaba63bd2c0181ae9e87","src/filter/layer_filters/mod.rs":"2046a860b21751791dae61d20219b3d59049b84fb289ea1fca7796d214c5643c","src/filter/level.rs":"cc449757aac47caaf19dd5ba4d74c8efbcd7531fcd6c13da0c5f6fdda12cc9ca","src/filter/mod.rs":"8ebfd0dc92415ff27ec552f20919e598842a87186f13f120449053a96e1e3307","src/filter/targets.rs":"eaa11d620017269770da5b2b97302b3beb81187242912260ca98e6d60ea77780","src/fmt/fmt_layer.rs":"5042d3e2eba5f68e9041c94b52f26ab17b84f68c54d16e4c0edd9d3a3699f727","src/fmt/format/json.rs":"554985ed40f7c59787aae87626144241ca973929e33979c54f821b673b71fec9","src/fmt/format/mod.rs":"a5f6b879802d353192235cf85aa8653afa3e8ead09955e631a39415324ce42d2","src/fmt/format/pretty.rs":"30fac9a916f3b9f572efa3b650c6dab7d86a57ce903cdbba6c6c0a52064cf238","src/fmt/mod.rs":"d5274d1f8106dc7497d2be7c6d874aeca15b9ca0fd4e0c6775d3774e75b30099","src/fmt/time/datetime.rs":"778d4604d800e46b940087394e7b72750738b554e02aea523fa9820ab0768c08","src/fmt/time/mod.rs":"30c97a9d3abd099f52c4c91c7b5f0d29ed9d54d80d1718c6fb74bfd664589de1","src/fmt/time/time_crate.rs":"1bfd59516a583e396afc1770250aa8c06b52f6162a6e7b2cadb860b7eebd9d76","src/fmt/writer.rs":"1931125cf14019b66b42a9ff95e5794f344697f799c021b4a7d48fd7eb7b58f4","src/layer/context.rs":"77137d8b2810c9059ce7838c3b665748bcb9765487d6103b92596e08b0e9e84b","src/layer/layered.rs":"945e42296ce3e86aa405eb31efdef4346cdfd84111f36700cc73e473e3ce5b28","src/layer/mod.rs":"b4febff42ea5ae12b92b8c73b7c691d9486e671446da99669fc5348314721cc9","src/layer/tests.rs":"3e974d627c4bc4269cfa10c82c890e596c9d46af8e6bc03c6c117bde1237e948","src/lib.rs":"8c1a26a319318768432b1025a2d0b08544bf2698b0a278fbb07211e22b22cd73","src/macros.rs":"e184bffc6b5999c48e365ad08343dca764a5fb711b789beb26bd1d5f1d767726","src/prelude.rs":"088635def33be9a4c4b6ed934dc22540c555e27d62f7625a43aa9c0e525ca467","src/registry/extensions.rs":"0418b39287bbc06cc95b8cecd6a25aa808b8e04714d842340ff75db458cafe5b","src/registry/mod.rs":"76627b056ce39d006708a6273b6418d001b688f016f58aa546e7821d1ef7f3bb","src/registry/sharded.rs":"aaac353632b1bbb804048b40cdfce9877688efa0679ae42ab36a095fd3e3877f","src/registry/stack.rs":"9ef333d6a8a28a064e80ff1e376dbb07bc597009010ec332b2dc3ab435d737c2","src/reload.rs":"caec4e23cf879ccc7c16bccbc99e20b8a20e27565c4edc6c527e094b7d0bb097","src/sync.rs":"7f78f3de5b618a999be0e61f936a233975e7769f1ebb55a0e48c3d199e9c45e3","src/util.rs":"55b4e9d63112f9d5a12a287273a9b1212741058384332d3edc024168cacfd627","tests/cached_layer_filters_dont_break_other_layers.rs":"b2084542a014abeff821b30b2b8c21e32bfdcffae53ce5335fb588f557fa4244","tests/duplicate_spans.rs":"3bf35184fb7d1dc5f33e5098820febbec37ef3ccd06b693d11b5585affb60ff4","tests/env_filter/main.rs":"b2d89ee7aaf94f0563e4e5b025cf43186ec61657b763b7c0ae010ff548635251","tests/env_filter/per_layer.rs":"19e9998922f24ec368fcbcda406f43a95335551c4c1669b509bbfc1ef216432a","tests/event_enabling.rs":"15e301a8ff6c74c454547dad15a47b5f11fc54e539162191f21462b6d5080830","tests/field_filter.rs":"fb8735801ba7ecabb421ca361bd1c846841aee63eecbdd665f9544a1cec70f67","tests/filter_log.rs":"086f1e708a2e7389024d7e36d963947909d94c1975db92f4fc425b5cba2af533","tests/fmt_max_level_hint.rs":"d4c6d6f976ae41ab8052fa610a7337ad7150802cbd5634cb30fc45c1f215cfcd","tests/hinted_layer_filters_dont_break_other_layers.rs":"d5ba9cfb6784cf59f007e673ad549dc722d109f6b3d4a69f6aa11b25ca10b469","tests/layer_filter_interests_are_cached.rs":"d036d1c4bc3754e94ebfdda9c841f4858ccec40aba0720f3fbf26c817bfe5a83","tests/layer_filters/boxed.rs":"04db459721a26d6502a2b3fbe42154c5a451021a9374a18c017d10971f44e0c0","tests/layer_filters/combinators.rs":"cdbfaa37fa5b0439ec2ae8028601d22120ff2a42867a2af8a3b27fc58e70cb6c","tests/layer_filters/downcast_raw.rs":"9b90ead571543cbe14e89b4fe637360d9baf3069f6f656ed3bdf65e7318648f1","tests/layer_filters/filter_scopes.rs":"02611bc58d0d8a67a127eca8cab1b2d9a9901bd2c8a8daad41adf6089b28aee0","tests/layer_filters/main.rs":"fe0ed219b79bcbb2ece4c224ee5bf05662fe3b23a224f746b273afdb1abc0fbd","tests/layer_filters/targets.rs":"138e3f9ddd68571d94c5aff9d54ee2fbc5f44724c6ee42477a411740ccb79ee6","tests/layer_filters/trees.rs":"4df7b5cf12da44a9255c56e5b80e2b0cf84820230ba916f324c67bc3ee4e4605","tests/layer_filters/vec.rs":"eaf2e7fe0a76633cc02bc729513202a5fb169e2bdb5a8042d8c7bd1f7092691d","tests/multiple_layer_filter_interests_cached.rs":"1ea195f03e58d715228ec1b604f85bda2fc82812d05b2f6370d5edd34a035f32","tests/option.rs":"071af56d21e1438b112c7698790328f4797d2d4dd4c7e4857ea8d4825f1fac89","tests/registry_max_level_hint.rs":"ba386d32b8d13832d7009163241c3d0723488c0393d85647eb9368776251e4fc","tests/registry_with_subscriber.rs":"61a545e1bf3f75efd0dd18c20bb93e8a1f2e0158b342179a94228c4cbd5bb9cc","tests/reload.rs":"8f169b60ab67bbc171dd7e576236b901293b5baa08ea469765a042375855e0f4","tests/same_len_filters.rs":"eceb745f7f5b6c8737c1860a58e2cf98a048fc486dee4379e94485f41c92c925","tests/support.rs":"d5d8ae7a143bda971e24dcba01137be0efea957d732b43502fd845c3bc952f8b","tests/unhinted_layer_filters_dont_break_other_layers.rs":"519cfef4977e511af938546d4208c645a28248c8ed8666daf180f0ad32f0a261","tests/utils.rs":"2c37d9f39010767190f72cb2b3faa3131985764aa547027197108299a9a6bb9e","tests/vec.rs":"d1176f3e1b0954129792a28282b95084d417143b0cc4e35887b95cee3c675392","tests/vec_subscriber_filter_interests_cached.rs":"115a0f097cd649c570eabe74f82791bbe15b2de32a2eef403575661798aadd82"},"package":"60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"} \ No newline at end of file diff --git a/vendor/tracing-subscriber/CHANGELOG.md b/vendor/tracing-subscriber/CHANGELOG.md deleted file mode 100644 index e2ac4e7c3..000000000 --- a/vendor/tracing-subscriber/CHANGELOG.md +++ /dev/null @@ -1,1225 +0,0 @@ -# 0.3.15 (Jul 20, 2022) - -This release fixes a bug where the `reload` layer would fail to pass through -`max_level_hint` to the underlying layer, potentially breaking filtering. - -### Fixed - -- **reload**: pass through `max_level_hint` to the inner `Layer` ([#2204]) - -Thanks to @guswynn for contributing to this release! - -[#2204]: https://github.com/tokio-rs/tracing/pull/2204 - -# 0.3.14 (Jul 1, 2022) - -This release fixes multiple filtering bugs in the `Layer` implementations for -`Option` and `Vec`. - -### Fixed - -- **layer**: `Layer::event_enabled` implementation for `Option>` - returning `false` when the `Option` is `None`, disabling all events globally - ([#2193]) -- **layer**: `Layer::max_level_hint` implementation for `Option>` - incorrectly disabling max level filtering when the option is `None` ([#2195]) -- **layer**: `Layer::max_level_hint` implementation for `Vec>` - returning `LevelFilter::ERROR` rather than `LevelFilter::OFF` when the `Vec` - is empty ([#2195]) - -Thanks to @CAD97 and @guswynn for contributing to this release! - -[#2193]: https://github.com/tokio-rs/tracing/pull/2193 -[#2195]: https://github.com/tokio-rs/tracing/pull/2195 - -# 0.3.13 (Jun 30, 2022) (YANKED) - -This release of `tracing-subscriber` fixes a compilation failure due to an -incorrect `tracing-core` dependency that was introduced in v0.3.12. - -### Changed - -- **tracing_core**: Updated minimum dependency version to 0.1.28 ([#2190]) - -[#2190]: https://github.com/tokio-rs/tracing/pull/2190 - -# 0.3.12 (Jun 29, 2022) (YANKED) - -This release of `tracing-subscriber` adds a new `Layer::event_enabled` method, -which allows `Layer`s to filter events *after* their field values are recorded; -a `Filter` implementation for `reload::Layer`, to make using `reload` with -per-layer filtering more ergonomic, and additional inherent method downcasting -APIs for the `Layered` type. In addition, it includes dependency updates, and -minor fixes for documentation and feature flagging. - -### Added - -- **layer**: `Layer::event_enabled` method, which can be implemented to filter - events based on their field values ([#2008]) -- **reload**: `Filter` implementation for `reload::Layer` ([#2159]) -- **layer**: `Layered::downcast_ref` and `Layered::is` inherent methods - ([#2160]) - -### Changed - -- **parking_lot**: Updated dependency on `parking_lot` to 0.13.0 ([#2143]) -- Replaced `lazy_static` dependency with `once_cell` ([#2147]) - -### Fixed - -- Don't enable `tracing-core` features by default ([#2107]) -- Several documentation link and typo fixes ([#2064], [#2068], #[2077], [#2161], - [#1088]) - -Thanks to @ben0x539, @jamesmunns, @georgemp, @james7132, @jswrenn, @CAD97, and -@guswynn for contributing to this release! - -[#2008]: https://github.com/tokio-rs/tracing/pull/2008 -[#2159]: https://github.com/tokio-rs/tracing/pull/2159 -[#2160]: https://github.com/tokio-rs/tracing/pull/2160 -[#2143]: https://github.com/tokio-rs/tracing/pull/2143 -[#2107]: https://github.com/tokio-rs/tracing/pull/2107 -[#2064]: https://github.com/tokio-rs/tracing/pull/2064 -[#2068]: https://github.com/tokio-rs/tracing/pull/2068 -[#2077]: https://github.com/tokio-rs/tracing/pull/2077 -[#2161]: https://github.com/tokio-rs/tracing/pull/2161 -[#1088]: https://github.com/tokio-rs/tracing/pull/1088 - -# 0.3.11 (Apr 9, 2022) - -This is a bugfix release for the `Filter` implementation for `EnvFilter` added -in [v0.3.10]. - -### Fixed - -- **env-filter**: Added missing `Filter::on_record` callback to `EnvFilter`'s - `Filter` impl ([#2058]) -- **env-filter**: Fixed method resolution issues when calling `EnvFilter` - methods with both the `Filter` and `Layer` traits in scope ([#2057]) -- **env-filter**: Fixed `EnvFilter::builder().parse()` and other parsing methods - returning an error when parsing an empty string ([#2052]) - -Thanks to new contributor @Ma124 for contributing to this release! - -[v0.3.10]: https://github.com/tokio-rs/tracing/releases/tag/tracing-subscriber-0.3.10 -[#2058]: https://github.com/tokio-rs/tracing/pull/2058 -[#2057]: https://github.com/tokio-rs/tracing/pull/2057 -[#2052]: https://github.com/tokio-rs/tracing/pull/2052 - -# 0.3.10 (Apr 1, 2022) - -This release adds several new features, including a `Filter` implementation and -new builder API for `EnvFilter`, support for using a `Vec where L: Layer` as -a `Layer`, and a number of smaller API improvements to make working with dynamic -and reloadable layers easier. - -### Added - -- **registry**: Implement `Filter` for `EnvFilter`, allowing it to be used with - per-layer filtering ([#1983]) -- **registry**: `Filter::on_new_span`, `Filter::on_enter`, - `Filter::on_exit`, `Filter::on_close` and `Filter::on_record` callbacks to - allow `Filter`s to track span states internally ([#1973], [#2017], [#2031]) -- **registry**: `Filtered::filter` and `Filtered::filter_mut` accessors - ([#1959]) -- **registry**: `Filtered::inner` and `Filtered::inner_mut` accessors to borrow - the wrapped `Layer` ([#2034]) -- **layer**: Implement `Layer` for `Vec`, to allow composing together - a dynamically sized list of `Layer`s ([#2027]) -- **layer**: `Layer::boxed` method to make type-erasing `Layer`s easier - ([#2026]) -- **fmt**: `fmt::Layer::writer` and `fmt::Layer::writer_mut` accessors ([#2034]) -- **fmt**: `fmt::Layer::set_ansi` method to allow changing the ANSI formatting - configuration at runtime ([#2034]) -- **env-filter**: `EnvFilter::builder` to configure a new `EnvFilter` prior to - parsing it ([#2035]) -- Several documentation fixes and improvements ([#1972], [#1971], [#2023], - [#2023]) - -### Fixed - -- **fmt**: `fmt::Layer`'s auto traits no longer depend on the `Subscriber` type - parameter's auto traits ([#2025]) -- **env-filter**: Fixed missing help text when the `ansi` feature is disabled - ([#2029]) - -Thanks to new contributors @TimoFreiberg and @wagenet, as well as @CAD97 for -contributing to this release! - -[#1983]: https://github.com/tokio-rs/tracing/pull/1983 -[#1973]: https://github.com/tokio-rs/tracing/pull/1973 -[#2017]: https://github.com/tokio-rs/tracing/pull/2017 -[#2031]: https://github.com/tokio-rs/tracing/pull/2031 -[#1959]: https://github.com/tokio-rs/tracing/pull/1959 -[#2034]: https://github.com/tokio-rs/tracing/pull/2034 -[#2027]: https://github.com/tokio-rs/tracing/pull/2027 -[#2026]: https://github.com/tokio-rs/tracing/pull/2026 -[#2035]: https://github.com/tokio-rs/tracing/pull/2035 -[#1972]: https://github.com/tokio-rs/tracing/pull/1972 -[#1971]: https://github.com/tokio-rs/tracing/pull/1971 -[#2023]: https://github.com/tokio-rs/tracing/pull/2023 -[#2025]: https://github.com/tokio-rs/tracing/pull/2025 -[#2029]: https://github.com/tokio-rs/tracing/pull/2029 - -# 0.3.9 (Feb 17, 2022) - -This release updates the minimum supported Rust version (MSRV) to 1.49.0, and -updates the (optional) dependency on `parking_lot` to v0.12. - -### Changed - -- Updated minimum supported Rust version (MSRV) to 1.49.0 ([#1913]) -- `parking_lot`: updated to v0.12 ([008339d]) - -### Added - -- **fmt**: Documentation improvements ([#1926], [#1927]) - -[#1913]: https://github.com/tokio-rs/tracing/pull/1913 -[#1926]: https://github.com/tokio-rs/tracing/pull/1926 -[#1927]: https://github.com/tokio-rs/tracing/pull/1927 -[008339d]: https://github.com/tokio-rs/tracing/commit/008339d1e8750ffe7b4634fc7789bda0c522424f - -# 0.3.8 (Feb 4, 2022) - -This release adds *experimental* support for recording structured field -values using the [`valuable`] crate to the `format::Json` formatter. In -particular, user-defined types which are recorded using their -[`valuable::Valuable`] implementations will be serialized as JSON objects, -rather than using their `fmt::Debug` representation. See [this blog post][post] -for details on `valuable`. - -Note that `valuable` support currently requires `--cfg tracing_unstable`. See -the documentation for details. - -Additionally, this release includes a number of other smaller API improvements. - -### Added - -- **json**: Experimental support for recording [`valuable`] values as structured - JSON ([#1862], [#1901]) -- **filter**: `Targets::would_enable` method for testing if a `Targets` filter - would enable a given target ([#1903]) -- **fmt**: `map_event_format`, `map_fmt_fields`, and `map_writer` methods to - `fmt::Layer` and `fmt::SubscriberBuilder` ([#1871]) - -### Changed - -- `tracing-core`: updated to [0.1.22][core-0.1.22] - -### Fixed - -- Set `smallvec` minimal version to 1.2.0, to fix compilation errors with `-Z - minimal-versions` ([#1890]) -- Minor documentation fixes ([#1902], [#1893]) - -Thanks to @guswynn, @glts, and @lilyball for contributing to this release! - -[`valuable`]: https://crates.io/crates/valuable -[`valuable::Valuable`]: https://docs.rs/valuable/latest/valuable/trait.Valuable.html -[post]: https://tokio.rs/blog/2021-05-valuable -[core-0.1.22]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.22 -[#1862]: https://github.com/tokio-rs/tracing/pull/1862 -[#1901]: https://github.com/tokio-rs/tracing/pull/1901 -[#1903]: https://github.com/tokio-rs/tracing/pull/1903 -[#1871]: https://github.com/tokio-rs/tracing/pull/1871 -[#1890]: https://github.com/tokio-rs/tracing/pull/1890 -[#1902]: https://github.com/tokio-rs/tracing/pull/1902 -[#1893]: https://github.com/tokio-rs/tracing/pull/1893 - -# 0.3.7 (Jan 25, 2022) - -This release adds combinators for combining filters. - -Additionally, this release also updates the `thread-local` crate to v1.1.4, -fixing warnings for the security advisory [RUSTSEC-2022-0006]. Note that -previous versions of `tracing-subscriber` did not use any of the `thread-local` -crate's APIs effected by the vulnerability. However, updating the version fixes -warnings emitted by `cargo audit` and similar tools. - -### Added - -- **filter**: Added combinators for combining filters ([#1578]) - -### Fixed - -- **registry**: Updated `thread-local` to v1.1.4 ([#1858]) - -Thanks to new contributor @matze for contributing to this release! - -[RUSTSEC-2022-0006]: https://rustsec.org/advisories/RUSTSEC-2022-0006 -[#1578]: https://github.com/tokio-rs/tracing/pull/1578 -[#1858]: https://github.com/tokio-rs/tracing/pull/1858 - -# 0.3.6 (Jan 14, 2022) - -This release adds configuration options to `tracing_subscriber::fmt` to log -source code locations for events. -### Added - -- **fmt**: Added `with_file` and `with_line_number` - configuration methods to `fmt::Format`, `fmt::SubscriberBuilder`, and - `fmt::Layer` ([#1773]) - -### Fixed - -- **fmt**: Removed incorrect leading comma from span fields with the `Pretty` - formatter ([#1833]) - -### Deprecated - -- **fmt**: Deprecated `Pretty::with_source_location`, as it can now be replaced - by the more general `Format`, `SubscriberBuilder`, and `Layer` methods - ([#1773]) - -Thanks to new contributor @renecouto for contributing to this release! - -[#1773]: https://github.com/tokio-rs/tracing/pull/1773 -[#1833]: https://github.com/tokio-rs/tracing/pull/1833 - -# 0.3.5 (Dec 29, 2021) - -This release re-enables `RUST_LOG` filtering in `tracing_subscriber::fmt`'s -default initialization methods, and adds an `OffsetLocalTime` formatter for -using local timestamps with the `time` crate. - -### Added - -- **fmt**: Added `OffsetLocalTime` formatter to `fmt::time` for formatting local - timestamps with a fixed offset ([#1772]) - -### Fixed - -- **fmt**: Added a `Targets` filter to `fmt::init()` and `fmt::try_init()` when - the "env-filter" feature is disabled, so that `RUST_LOG` is still honored - ([#1781]) - -Thanks to @marienz and @ishitatsuyuki for contributing to this release! - -[#1772]: https://github.com/tokio-rs/tracing/pull/1772 -[#1781]: https://github.com/tokio-rs/tracing/pull/1781 - -# 0.3.4 (Dec 23, 2021) - -This release contains bugfixes for the `fmt` module, as well as documentation -improvements. - -### Fixed - -- **fmt**: Fixed `fmt` not emitting log lines when timestamp formatting fails - ([#1689]) -- **fmt**: Fixed double space before thread IDs with `Pretty` formatter - ([#1778]) -- Several documentation improvements ([#1608], [#1699], [#1701]) - -[#1689]: https://github.com/tokio-rs/tracing/pull/1689 -[#1778]: https://github.com/tokio-rs/tracing/pull/1778 -[#1608]: https://github.com/tokio-rs/tracing/pull/1608 -[#1699]: https://github.com/tokio-rs/tracing/pull/1699 -[#1701]: https://github.com/tokio-rs/tracing/pull/1701 - -Thanks to new contributors @Swatinem and @rukai for contributing to this -release! - -# 0.3.3 (Nov 29, 2021) - -This release fixes a pair of regressions in `tracing-subscriber`'s `fmt` module. - -### Fixed - -- **fmt**: Fixed missing event fields with `Compact` formatter ([#1755]) -- **fmt**: Fixed `PrettyFields` formatter (and thus `format::Pretty` event - formatter) ignoring the `fmt::Layer`'s ANSI color code configuration ([#1747]) - -[#1755]: https://github.com/tokio-rs/tracing/pull/1755 -[#1747]: https://github.com/tokio-rs/tracing/pull/1747 - -# 0.3.2 (Nov 19, 2021) - -### Fixed - -- **fmt**: Fixed `MakeWriter` filtering not working with `BoxMakeWriter` - ([#1694]) - -### Added - -- **fmt**: `Writer::has_ansi_escapes` method to check if an output supports ANSI - terminal formatting escape codes ([#1696]) -- **fmt**: Added additional ANSI terminal formatting to field formatters when - supported ([#1702]) -- **fmt**: Added `FmtContext::span_scope`, `FmtContext::event_scope`, and - `FmtContext::parent_span` methods for accessing the current span and its scope - when formatting an event ([#1728]) -- **fmt**: Improved documentation on implementing event formatters ([#1727]) - -[#1694]: https://github.com/tokio-rs/tracing/pull/1694 -[#1696]: https://github.com/tokio-rs/tracing/pull/1696 -[#1702]: https://github.com/tokio-rs/tracing/pull/1702 -[#1728]: https://github.com/tokio-rs/tracing/pull/1728 -[#1727]: https://github.com/tokio-rs/tracing/pull/1727 -# 0.3.1 (Oct 25, 2021) - -This release fixes a few issues related to feature flagging. - -### Fixed - -- **time**: Compilation error when enabling the "time" feature flag without also - enabling the "local-time" feature flag ([#1685]) -- **registry**: Unused method warnings when the "std" feature is enabled but the - "registry" feature is disabled ([#1686]) - -[#1685]: https://github.com/tokio-rs/tracing/pull/1685 -[#1686]: https://github.com/tokio-rs/tracing/pull/1686 - -# 0.3.0 (Oct 22, 2021) - -This is a breaking release of `tracing-subscriber`. The primary breaking change -in this release is the removal of the dependency on the [`chrono` crate], due to -[RUSTSEC-2020-0159]. To replace `chrono`, support is added for formatting -timestamps using the [`time` crate] instead. - -In addition, this release includes a number of other breaking API changes, such -as adding (limited) support for `#![no_std]` targets, removing previously -deprecated APIs, and more. - -### Breaking Changes - -- Removed APIs deprecated in the v0.2.x release series. -- Renamed `Layer::new_span` to `Layer::on_new_span` ([#1674]) -- Removed `Layer` impl for `Arc>` and `Arc + ...>` - ([#1649]) -- Replaced the [`chrono` crate] with the [`time` crate] for timestamp formatting, to - resolve [RUSTSEC-2020-0159] ([#1646]) -- Removed `json` and `env-filter` from default features. They must now be - enabled explictly ([#1647]). This means that `RUST_LOG`-based filters _will not_ - work unless the `env-filter` feature is enabled. -- Changed `FormatEvent::format_event` and `FormatFields::format_fields` - trait methods to take a `Writer` type, rather than a `&mut dyn fmt::Write` - trait object ([#1661]) -- Changed the signature of the `MakeWriter` trait by adding a lifetime parameter - ([#781]) - -### Changed - -- **layer**: Renamed `Layer::new_span` to `Layer::on_new_span` ([#1674]) -- **fmt**: Changed `FormatEvent::format_event` and `FormatFields::format_fields` - trait methods to take a `Writer` type, rather than a `&mut dyn fmt::Write` - trait object ([#1661]) -- **json**, **env-filter**: `json` and `env-filter` feature flags are no longer - enabled by default ([#1647]) -### Removed - -- Removed deprecated `CurrentSpan` type ([#1320]) -- **registry**: Removed deprecated `SpanRef::parents` iterator, replaced by - `SpanRef::scope` in [#1431] ([#1648)]) -- **layer**: Removed deprecated `Context::scope` iterator, replaced by - `Context::span_scope` and `Context::event_scope` in [#1431] and [#1434] - ([#1648)]) -- **layer**: Removed `Layer` impl for `Arc>` and - `Arc + ...>`. These interfere with per-layer filtering. ([#1649]) -- **fmt**: Removed deprecated `LayerBuilder` type ([#1673]) -- **fmt**: Removed `fmt::Layer::on_event` (renamed to `fmt::Layer::fmt_event`) - ([#1673]) -- **fmt**, **chrono**: Removed the `chrono` feature flag and APIs for using the - [`chrono` crate] for timestamp formatting ([#1646]) -### Added - -- **fmt**, **time**: `LocalTime` and `UtcTime` types for formatting timestamps - using the [`time` crate] ([#1646]) -- **fmt**: Added a lifetime parameter to the `MakeWriter` trait, allowing it to - return a borrowed writer. This enables implementations of `MakeWriter` for - types such as `Mutex` and `std::fs::File`. ([#781]) -- **env-filter**: Documentation improvements ([#1637]) -- Support for some APIs on `#![no_std]` targets, by disabling the `std` feature - flag ([#1660]) - -Thanks to @Folyd and @nmathewson for contributing to this release! - -[#1320]: https://github.com/tokio-rs/tracing/pull/1320 -[#1673]: https://github.com/tokio-rs/tracing/pull/1673 -[#1674]: https://github.com/tokio-rs/tracing/pull/1674 -[#1646]: https://github.com/tokio-rs/tracing/pull/1646 -[#1647]: https://github.com/tokio-rs/tracing/pull/1647 -[#1648]: https://github.com/tokio-rs/tracing/pull/1648 -[#1649]: https://github.com/tokio-rs/tracing/pull/1649 -[#1660]: https://github.com/tokio-rs/tracing/pull/1660 -[#1661]: https://github.com/tokio-rs/tracing/pull/1661 -[#1431]: https://github.com/tokio-rs/tracing/pull/1431 -[#1434]: https://github.com/tokio-rs/tracing/pull/1434 -[#781]: https://github.com/tokio-rs/tracing/pull/781 - -[`chrono` crate]: https://crates.io/crates/chrono -[`time` crate]: https://crates.io/crates/time -[RUSTSEC-2020-0159]: https://rustsec.org/advisories/RUSTSEC-2020-0159.html - -# 0.2.25 (October 5, 2021) - -This release fixes an issue where a `Layer` implementation's custom -`downcast_raw` implementation was lost when wrapping that layer with a per-layer -filter. - -### Fixed - -- **registry**: Forward `Filtered::downcast_raw` to wrapped `Layer` ([#1619]) - -### Added - -- Documentation improvements ([#1596], [#1601]) - -Thanks to @bryanburgers for contributing to this release! - -[#1619]: https://github.com/tokio-rs/tracing/pull/1619 -[#1601]: https://github.com/tokio-rs/tracing/pull/1601 -[#1596]: https://github.com/tokio-rs/tracing/pull/1596 - -# 0.2.24 (September 19, 2021) - -This release contains a number of bug fixes, including a fix for -`tracing-subscriber` failing to compile on the minimum supported Rust version of -1.42.0. It also adds `IntoIterator` implementations for the `Targets` type. - -### Fixed - -- Fixed compilation on Rust 1.42.0 ([#1580], [#1581]) -- **registry**: Ensure per-layer filter `enabled` state is cleared when a global - filter short-circuits filter evaluation ([#1575]) -- **layer**: Fixed `Layer::on_layer` not being called for `Box`ed `Layer`s, - which broke per-layer filtering ([#1576]) - -### Added - -- **filter**: Added `Targets::iter`, returning an iterator over the set of - target-level pairs enabled by a `Targets` filter ([#1574]) -- **filter**: Added `IntoIterator` implementations for `Targets` and `&Targets` - ([#1574]) - -Thanks to new contributor @connec for contributing to this release! - -[#1580]: https://github.com/tokio-rs/tracing/pull/1580 -[#1581]: https://github.com/tokio-rs/tracing/pull/1581 -[#1575]: https://github.com/tokio-rs/tracing/pull/1575 -[#1576]: https://github.com/tokio-rs/tracing/pull/1576 -[#1574]: https://github.com/tokio-rs/tracing/pull/1574 - -# 0.2.23 (September 16, 2021) - -This release fixes a few bugs in the per-layer filtering API added in v0.2.21. - -### Fixed - -- **env-filter**: Fixed excessive `EnvFilter` memory use ([#1568]) -- **filter**: Fixed a panic that may occur in debug mode when using per-layer - filters together with global filters ([#1569]) -- Fixed incorrect documentation formatting ([#1572]) - -[#1568]: https://github.com/tokio-rs/tracing/pull/1568 -[#1569]: https://github.com/tokio-rs/tracing/pull/1569 -[#1572]: https://github.com/tokio-rs/tracing/pull/1572 - -# 0.2.22 (September 13, 2021) - -This fixes a regression where the `filter::ParseError` type was accidentally -renamed. - -### Fixed - -- **filter**: Fix `filter::ParseError` accidentally being renamed to - `filter::DirectiveParseError` ([#1558]) - -[#1558]: https://github.com/tokio-rs/tracing/pull/1558 - -# 0.2.21 (September 12, 2021) - -This release introduces the [`Filter`] trait, a new API for [per-layer -filtering][plf]. This allows controlling which spans and events are recorded by -various layers individually, rather than globally. - -In addition, it adds a new [`Targets`] filter, which provides a lighter-weight -version of the filtering provided by [`EnvFilter`], as well as other smaller API -improvements and fixes. - -### Deprecated - -- **registry**: `SpanRef::parent_id`, which cannot properly support per-layer - filtering. Use `.parent().map(SpanRef::id)` instead. ([#1523]) - -### Fixed - -- **layer** `Context` methods that are provided when the `Subscriber` implements - `LookupSpan` no longer require the "registry" feature flag ([#1525]) -- **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` - type parameter to implement `Debug` ([#1528]) - -### Added - -- **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, - and other APIs for per-layer filtering ([#1523]) -- **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) - and per-layer (`Filter`) filtering for closures and function pointers - ([#1523]) -- **filter**: `Targets` filter, which implements a lighter-weight form of - `EnvFilter`-like filtering ([#1550]) -- **env-filter**: Added support for filtering on floating-point values ([#1507]) -- **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a -`Subscriber` ([#1523]) -- **layer**: `Layer` implementations for `Box` and `Arc` where `L: Layer` - ([#1536]) -- **layer**: `Layer` implementations for `Box + Send + Sync + 'static>` - and `Arc + Send + Sync + 'static>` ([#1536]) -- A number of small documentation fixes and improvements ([#1553], [#1544], - [#1539], [#1524]) - -Special thanks to new contributors @jsgf and @maxburke for contributing to this -release! - -[`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html -[plf]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering -[`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html -[`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html -[#1507]: https://github.com/tokio-rs/tracing/pull/1507 -[#1523]: https://github.com/tokio-rs/tracing/pull/1523 -[#1524]: https://github.com/tokio-rs/tracing/pull/1524 -[#1525]: https://github.com/tokio-rs/tracing/pull/1525 -[#1528]: https://github.com/tokio-rs/tracing/pull/1528 -[#1539]: https://github.com/tokio-rs/tracing/pull/1539 -[#1544]: https://github.com/tokio-rs/tracing/pull/1544 -[#1550]: https://github.com/tokio-rs/tracing/pull/1550 -[#1553]: https://github.com/tokio-rs/tracing/pull/1553 - -# 0.2.20 (August 17, 2021) - -### Fixed - -- **fmt**: Fixed `fmt` printing only the first `source` for errors with a chain - of sources ([#1460]) -- **fmt**: Fixed missing space between level and event in the `Pretty` formatter - ([#1498]) -- **json**: Fixed `Json` formatter not honoring `without_time` and `with_level` - configurations ([#1463]) - -### Added - -- **registry**: Improved panic message when cloning a span whose ID doesn't - exist, to aid in debugging issues with multiple subscribers ([#1483]) -- **registry**: Improved documentation on span ID generation ([#1453]) - -[#1460]: https://github.com/tokio-rs/tracing/pull/1460 -[#1483]: https://github.com/tokio-rs/tracing/pull/1483 -[#1463]: https://github.com/tokio-rs/tracing/pull/1463 -[#1453]: https://github.com/tokio-rs/tracing/pull/1453 -[#1498]: https://github.com/tokio-rs/tracing/pull/1498 - -Thanks to new contributors @joshtriplett and @lerouxrgd, and returning -contributor @teozkr, for contributing to this release! - -# 0.2.19 (June 25, 2021) - -### Deprecated - -- **registry**: `SpanRef::parents`, `SpanRef::from_root`, and `Context::scope` - iterators, which are replaced by new `SpanRef::scope` and `Scope::from_root` - iterators ([#1413]) - -### Added - -- **registry**: `SpanRef::scope` method, which returns a leaf-to-root `Iterator` - including the leaf span ([#1413]) -- **registry**: `Scope::from_root` method, which reverses the `scope` iterator - to iterate root-to-leaf ([#1413]) -- **registry**: `Context::event_span` method, which looks up the parent span of - an event ([#1434]) -- **registry**: `Context::event_scope` method, returning a `Scope` iterator over - the span scope of an event ([#1434]) -- **fmt**: `MakeWriter::make_writer_for` method, which allows returning a - different writer based on a span or event's metadata ([#1141]) -- **fmt**: `MakeWriterExt` trait, with `with_max_level`, `with_min_level`, - `with_filter`, `and`, and `or_else` combinators ([#1274]) -- **fmt**: `MakeWriter` implementation for `Arc where &W: io::Write` - ([#1274]) - -Thanks to @teozkr and @Folyd for contributing to this release! - -[#1413]: https://github.com/tokio-rs/tracing/pull/1413 -[#1434]: https://github.com/tokio-rs/tracing/pull/1434 -[#1141]: https://github.com/tokio-rs/tracing/pull/1141 -[#1274]: https://github.com/tokio-rs/tracing/pull/1274 - -# 0.2.18 (April 30, 2021) - -### Deprecated - -- Deprecated the `CurrentSpan` type, which is inefficient and largely superseded - by the `registry` API ([#1321]) - -### Fixed - -- **json**: Invalid JSON emitted for events in spans with no fields ([#1333]) -- **json**: Missing span data for synthesized new span, exit, and close events - ([#1334]) -- **fmt**: Extra space before log lines when timestamps are disabled ([#1355]) - -### Added - -- **env-filter**: Support for filters on spans whose names contain any - characters other than `{` and `]` ([#1368]) - -Thanks to @Folyd, and new contributors @akinnane and @aym-v for contributing to -this release! - -[#1321]: https://github.com/tokio-rs/tracing/pull/1321 -[#1333]: https://github.com/tokio-rs/tracing/pull/1333 -[#1334]: https://github.com/tokio-rs/tracing/pull/1334 -[#1355]: https://github.com/tokio-rs/tracing/pull/1355 -[#1368]: https://github.com/tokio-rs/tracing/pull/1368 - -# 0.2.17 (March 12, 2021) - -### Fixed - -- **fmt**: `Pretty` formatter now honors `with_ansi(false)` to disable ANSI - terminal formatting ([#1240]) -- **fmt**: Fixed extra padding when using `Pretty` formatter ([#1275]) -- **chrono**: Removed extra trailing space with `ChronoLocal` time formatter - ([#1103]) - -### Added - -- **fmt**: Added `FmtContext::current_span()` method, returning the current span - ([#1290]) -- **fmt**: `FmtSpan` variants may now be combined using the `|` operator for - more granular control over what span events are generated ([#1277]) - -Thanks to new contributors @cratelyn, @dignati, and @zicklag, as well as @Folyd, -@matklad, and @najamelan, for contributing to this release! - -[#1240]: https://github.com/tokio-rs/tracing/pull/1240 -[#1275]: https://github.com/tokio-rs/tracing/pull/1275 -[#1103]: https://github.com/tokio-rs/tracing/pull/1103 -[#1290]: https://github.com/tokio-rs/tracing/pull/1290 -[#1277]: https://github.com/tokio-rs/tracing/pull/1277 - -# 0.2.16 (February 19, 2021) - -### Fixed - -- **env-filter**: Fixed directives where the level is in mixed case (such as - `Info`) failing to parse ([#1126]) -- **fmt**: Fixed `fmt::Subscriber` not providing a max-level hint ([#1251]) -- `tracing-subscriber` no longer enables `tracing` and `tracing-core`'s default - features ([#1144]) - -### Changed - -- **chrono**: Updated `chrono` dependency to 0.4.16 ([#1189]) -- **log**: Updated `tracing-log` dependency to 0.1.2 - -Thanks to @salewski, @taiki-e, @davidpdrsn and @markdingram for contributing to -this release! - -[#1126]: https://github.com/tokio-rs/tracing/pull/1126 -[#1251]: https://github.com/tokio-rs/tracing/pull/1251 -[#1144]: https://github.com/tokio-rs/tracing/pull/1144 -[#1189]: https://github.com/tokio-rs/tracing/pull/1189 - -# 0.2.15 (November 2, 2020) - -### Fixed - -- **fmt**: Fixed wrong lifetime parameters on `FormatFields` impl for - `FmtContext` ([#1082]) - -### Added - -- **fmt**: `format::Pretty`, an aesthetically pleasing, human-readable event - formatter for local development and user-facing CLIs ([#1080]) -- **fmt**: `FmtContext::field_format`, which returns the subscriber's field - formatter ([#1082]) - -[#1082]: https://github.com/tokio-rs/tracing/pull/1082 -[#1080]: https://github.com/tokio-rs/tracing/pull/1080 - -# 0.2.14 (October 22, 2020) - -### Fixed - -- **registry**: Fixed `Registry::new` allocating an excessively large amount of - memory, most of which would never be used ([#1064]) - -### Changed - -- **registry**: Improved `new_span` performance by reusing `HashMap` allocations - for `Extensions` ([#1064]) -- **registry**: Significantly improved the performance of `Registry::enter` and - `Registry::exit` ([#1058]) - -[#1064]: https://github.com/tokio-rs/tracing/pull/1064 -[#1058]: https://github.com/tokio-rs/tracing/pull/1058 - -# 0.2.13 (October 7, 2020) - -### Changed - -- Updated `tracing-core` to 0.1.17 ([#992]) - -### Added - -- **env-filter**: Added support for filtering on targets which contain dashes - ([#1014]) -- **env-filter**: Added a warning when creating an `EnvFilter` that contains - directives that would enable a level disabled by the `tracing` crate's - `static_max_level` features ([#1021]) - -Thanks to @jyn514 and @bkchr for contributing to this release! - -[#992]: https://github.com/tokio-rs/tracing/pull/992 -[#1014]: https://github.com/tokio-rs/tracing/pull/1014 -[#1021]: https://github.com/tokio-rs/tracing/pull/1021 - -# 0.2.12 (September 11, 2020) - -### Fixed - -- **env-filter**: Fixed a regression where `Option` lost its - `Into` impl ([#966]) -- **env-filter**: Fixed `EnvFilter` enabling spans that should not be enabled - when multiple subscribers are in use ([#927]) - -### Changed - -- **json**: `format::Json` now outputs fields in a more readable order ([#892]) -- Updated `tracing-core` dependency to 0.1.16 - -### Added - -- **fmt**: Add `BoxMakeWriter` for erasing the type of a `MakeWriter` - implementation ([#958]) -- **fmt**: Add `TestWriter` `MakeWriter` implementation to support libtest - output capturing ([#938]) -- **layer**: Add `Layer` impl for `Option where T: Layer` ([#910]) -- **env-filter**: Add `From` impl for `Directive` ([#918]) -- Multiple documentation fixes and improvements - -Thanks to @Pothulapati, @samrg472, @bryanburgers, @keetonian, and @SriRamanujam -for contributing to this release! - -[#927]: https://github.com/tokio-rs/tracing/pull/927 -[#966]: https://github.com/tokio-rs/tracing/pull/966 -[#958]: https://github.com/tokio-rs/tracing/pull/958 -[#892]: https://github.com/tokio-rs/tracing/pull/892 -[#938]: https://github.com/tokio-rs/tracing/pull/938 -[#910]: https://github.com/tokio-rs/tracing/pull/910 -[#918]: https://github.com/tokio-rs/tracing/pull/918 - -# 0.2.11 (August 10, 2020) - -### Fixed - -- **env-filter**: Incorrect max level hint when filters involving span field - values are in use (#907) -- **registry**: Fixed inconsistent span stacks when multiple registries are in - use on the same thread (#901) - -### Changed - -- **env-filter**: `regex` dependency enables fewer unused feature flags (#899) - -Thanks to @bdonlan and @jeromegn for contributing to this release! - -# 0.2.10 (July 31, 2020) - -### Fixed - -- **docs**: Incorrect formatting (#862) - -### Changed - -- **filter**: `LevelFilter` is now a re-export of the - `tracing_core::LevelFilter` type, it can now be used interchangably with the - versions in `tracing` and `tracing-core` (#853) -- **filter**: Significant performance improvements when comparing `LevelFilter`s - and `Level`s (#853) -- Updated the minimum `tracing-core` dependency to 0.1.12 (#853) - -### Added - -- **filter**: `LevelFilter` and `EnvFilter` now participate in `tracing-core`'s - max level hinting, improving performance significantly in some use cases where - levels are disabled globally (#853) - -# 0.2.9 (July 23, 2020) - -### Fixed - -- **fmt**: Fixed compilation failure on MSRV when the `chrono` feature is - disabled (#844) - -### Added - -- **fmt**: Span lookup methods defined by `layer::Context` are now also provided - by `FmtContext` (#834) - -# 0.2.8 (July 17, 2020) - -### Changed - -- **fmt**: When the `chrono` dependency is enabled, the `SystemTime` timestamp - formatter now emits human-readable timestamps rather than using `SystemTime`'s - `fmt::Debug`implementation (`chrono` is still required for customized - timestamp formatting) (#807) -- **ansi**: Updated `ansi_term` dependency to 0.12 (#816) - -### Added - -- **json**: `with_span_list` method to configure the JSON formatter to include a - list of all spans in the current trace in formatting events (similarly to the - text formatter) (#741) -- **json**: `with_current_span` method to configure the JSON formatter to include - a field for the _current_ span (the leaf of the trace) in formatted events - (#741) -- **fmt**: `with_thread_names` and `with_thread_ids` methods to configure - `fmt::Subscriber`s and `fmt::Layer`s to include the thread name and/or thread ID - of the current thread when formatting events (#818) - -Thanks to new contributors @mockersf, @keetonian, and @Pothulapati for -contributing to this release! - -# 0.2.7 (July 1, 2020) - -### Changed - -- **parking_lot**: Updated the optional `parking_lot` dependency to accept the - latest `parking_lot` version (#774) - -### Fixed - -- **fmt**: Fixed events with explicitly overridden parent spans being formatted - as though they were children of the current span (#767) - -### Added - -- **fmt**: Added the option to print synthesized events when spans are created, - entered, exited, and closed, including span durations (#761) -- Documentation clarification and improvement (#762, #769) - -Thanks to @rkuhn, @greenwoodcm, and @Ralith for contributing to this release! - -# 0.2.6 (June 19, 2020) - -### Fixed - -- **fmt**: Fixed an issue in the JSON formatter where using `Span::record` would - result in malformed spans (#709) - -# 0.2.5 (April 21, 2020) - -### Changed - -- **fmt**: Bump sharded-slab dependency (#679) - -### Fixed - -- **fmt**: remove trailing space in `ChronoUtc` `format_time` (#677) - -# 0.2.4 (April 6, 2020) - -This release includes several API ergonomics improvements, including shorthand -constructors for many types, and an extension trait for initializing subscribers -using method-chaining style. Additionally, several bugs in less commonly used -`fmt` APIs were fixed. - -### Added - -- **fmt**: Shorthand free functions for constructing most types in `fmt` - (including `tracing_subscriber::fmt()` to return a `SubscriberBuilder`, - `tracing_subscriber::fmt::layer()` to return a format `Layer`, etc) (#660) -- **registry**: Shorthand free function `tracing_subscriber::registry()` to - construct a new registry (#660) -- Added `SubscriberInitExt` extension trait for more ergonomic subscriber - initialization (#660) - -### Changed - -- **fmt**: Moved `LayerBuilder` methods to `Layer` (#655) - -### Deprecated - -- **fmt**: `LayerBuilder`, as `Layer` now implements all builder methods (#655) - -### Fixed - -- **fmt**: Fixed `Compact` formatter not omitting levels with - `with_level(false)` (#657) -- **fmt**: Fixed `fmt::Layer` duplicating the fields for a new span if another - layer has already formatted its fields (#634) -- **fmt**: Added missing space when using `record` to add new fields to a span - that already has fields (#659) -- Updated outdated documentation (#647) - - -# 0.2.3 (March 5, 2020) - -### Fixed - -- **env-filter**: Regression where filter directives were selected in the order - they were listed, rather than most specific first (#624) - -# 0.2.2 (February 27, 2020) - -### Added - -- **fmt**: Added `flatten_event` to `SubscriberBuilder` (#599) -- **fmt**: Added `with_level` to `SubscriberBuilder` (#594) - -# 0.2.1 (February 13, 2020) - -### Changed - -- **filter**: `EnvFilter` directive selection now behaves correctly (i.e. like - `env_logger`) (#583) - -### Fixed - -- **filter**: Fixed `EnvFilter` incorrectly allowing less-specific filter - directives to enable events that are disabled by more-specific filters (#583) -- **filter**: Multiple significant `EnvFilter` performance improvements, - especially when filtering events generated by `log` records (#578, #583) -- **filter**: Replaced `BTreeMap` with `Vec` in `DirectiveSet`, improving - iteration performance significantly with typical numbers of filter directives - (#580) - -A big thank-you to @samschlegel for lots of help with `EnvFilter` performance -tuning in this release! - -# 0.2.0 (February 4, 2020) - -### Breaking Changes - -- **fmt**: Renamed `Context` to `FmtContext` (#420, #425) -- **fmt**: Renamed `Builder` to `SubscriberBuilder` (#420) -- **filter**: Removed `Filter`. Use `EnvFilter` instead (#434) - -### Added - -- **registry**: `Registry`, a `Subscriber` implementation that `Layer`s can use - as a high-performance, in-memory span store. (#420, #425, #432, #433, #435) -- **registry**: Added `LookupSpan` trait, implemented by `Subscriber`s to expose - stored span data to `Layer`s (#420) -- **fmt**: Added `fmt::Layer`, to allow composing log formatting with other `Layer`s -- **fmt**: Added support for JSON field and event formatting (#377, #415) -- **filter**: Documentation for filtering directives (#554) - -### Changed - -- **fmt**: Renamed `Context` to `FmtContext` (#420, #425) (BREAKING) -- **fmt**: Renamed `Builder` to `SubscriberBuilder` (#420) (BREAKING) -- **fmt**: Reimplemented `fmt::Subscriber` in terms of the `Registry` - and `Layer`s (#420) - -### Removed - -- **filter**: Removed `Filter`. Use `EnvFilter` instead (#434) (BREAKING) - -### Fixed - -- **fmt**: Fixed memory leaks in the slab used to store per-span data - (3c35048) -- **fmt**: `fmt::SubscriberBuilder::init` not setting up `log` compatibility - (#489) -- **fmt**: Spans closed by a child span closing not also closing _their_ - parents (#514) -- **Layer**: Fixed `Layered` subscribers failing to downcast to their own type - (#549) -- **Layer**: Fixed `Layer::downcast_ref` returning invalid references (#454) - -# 0.2.0-alpha.6 (February 3, 2020) - -### Fixed - -- **fmt**: Fixed empty `{}` printed after spans with no fields (f079f2d) -- **fmt**: Fixed inconsistent formatting when ANSI colors are disabled (506a482) -- **fmt**: Fixed mis-aligned levels when ANSI colors are disabled (eba1adb) -- Fixed warnings on nightly Rust compilers (#558) - -# 0.2.0-alpha.5 (January 31, 2020) - -### Added - -- **env_filter**: Documentation for filtering directives (#554) -- **registry**, **env_filter**: Updated `smallvec` dependency to 0.1 (#543) - -### Fixed - -- **registry**: Fixed a memory leak in the slab used to store per-span data - (3c35048) -- **Layer**: Fixed `Layered` subscribers failing to downcast to their own type - (#549) -- **fmt**: Fixed a panic when multiple layers insert `FormattedFields` - extensions from the same formatter type (1c3bb70) -- **fmt**: Fixed `fmt::Layer::on_record` inserting a new `FormattedFields` when - formatted fields for a span already exist (1c3bb70) - -# 0.2.0-alpha.4 (January 11, 2020) - -### Fixed - -- **registry**: Removed inadvertently committed `dbg!` macros (#533) - -# 0.2.0-alpha.3 (January 10, 2020) - -### Added - -- **fmt**: Public `FormattedFields::new` constructor (#478) -- **fmt**: Added examples to `fmt::Layer` documentation (#510) -- Documentation now shows what feature flags are required by each API item (#525) - -### Fixed - -- **fmt**: Missing space between timestamp and level (#480) -- **fmt**: Incorrect formatting with `with_target(false)` (#481) -- **fmt**: `fmt::SubscriberBuilder::init` not setting up `log` compatibility - (#489) -- **registry**: Spans exited out of order not being closed properly on exit - (#509) -- **registry**: Memory leak when spans are closed by a child span closing (#514) -- **registry**: Spans closed by a child span closing not also closing _their_ - parents (#514) -- Compilation errors with `no-default-features` (#499, #500) - -# 0.2.0-alpha.2 (December 8, 2019) - -### Added - -- `LookupSpans` implementation for `Layered` (#448) -- `SpanRef::from_root` to iterate over a span's parents from the root (#460) -- `Context::scope`, to iterate over the current context from the root (#460) -- `Context::lookup_current`, which returns a `SpanRef` to the current - span's data (#460) - -### Changed - -- Lifetimes on some new `Context` methods to be less restrictive (#460) - -### Fixed - -- `Layer::downcast_ref` returning invalid references (#454) -- Compilation failure on 32-bit platforms (#462) -- Compilation failure with ANSI formatters (#438) - -# 0.2.0-alpha.1 (November 18, 2019) - -### Added - -- `Registry`, a reusable span store that `Layer`s can use a - high-performance, in-memory store. (#420, #425, #432, #433, #435) -- Reimplemented `fmt::Subscriber` in terms of the `Registry` - and `Layer`s (#420) -- Add benchmarks for fmt subscriber (#421) -- Add support for JSON field and event formatting (#377, #415) - -### Changed - -- **BREAKING**: Change `fmt::format::FormatFields` and - `fmt::format::FormatEvent` to accept a mandatory `FmtContext`. These - `FormatFields` and `FormatEvent` will likely see additional breaking - changes in subsequent alpha. (#420, #425) -- **BREAKING**: Removed `Filter`. Use `EnvFilter` instead (#434) - -### Contributers - -Thanks to all the contributers to this release! - -- @pimeys for #377 and #415 - -# 0.1.6 (October 29, 2019) - -### Added - -- Add `init` and `try_init` functions to `FmtSubscriber` (#385) -- Add `ChronoUtc` and `ChronoLocal` timers, RFC 3339 support (#387) -- Add `tracing::subscriber::set_default` which sets the default - subscriber and returns a drop guard. This drop guard will reset the - dispatch on drop (#388). - -### Fixed - -- Fix default level for `EnvFilter`. Setting `RUST_LOG=target` - previously only the `ERROR` level, while it should enable everything. - `tracing-subscriber` now defaults to `TRACE` if no level is specified - (#401) -- Fix `tracing-log` feature flag for init + try_init. The feature flag - `tracing_log` was used instead of the correct `tracing-log`. As a - result, both `tracing-log` and `tracing_log` needed to be specified in - order to initialize the global logger. Only `tracing-log` needs to be - specified now (#400). - -### Contributers - -Thanks to all the contributers to this release! - -- @emschwartz for #385, #387, #400 and #401 -- @bIgBV for #388 - -# 0.1.5 (October 7, 2019) - -### Fixed - -- Spans not being closed properly when `FmtSubscriber::current_span` is used - (#371) - -# 0.1.4 (September 26, 2019) - -### Fixed - -- Spans entered twice on the same thread sometimes being completely exited when - the more deeply-nested entry is exited (#361) -- Setting `with_ansi(false)` on `FmtSubscriber` not disabling ANSI color - formatting for timestamps (#354) -- Incorrect reference counting in `FmtSubscriber` that could cause spans to not - be closed when all references are dropped (#366) - -# 0.1.3 (September 16, 2019) - -### Fixed - -- `Layered` subscribers not properly forwarding calls to `current_span` - (#350) - -# 0.1.2 (September 12, 2019) - -### Fixed - -- `EnvFilter` ignoring directives with targets that are the same number of - characters (#333) -- `EnvFilter` failing to properly apply filter directives to events generated - from `log` records by`tracing-log` (#344) - -### Changed - -- Renamed `Filter` to `EnvFilter`, deprecated `Filter` (#339) -- Renamed "filter" feature flag to "env-filter", deprecated "filter" (#339) -- `FmtSubscriber` now defaults to enabling only the `INFO` level and above when - a max level filter or `EnvFilter` is not set (#336) -- Made `parking_lot` dependency an opt-in feature flag (#348) - -### Added - -- `EnvFilter::add_directive` to add new directives to filters after they are - constructed (#334) -- `fmt::Builder::with_max_level` to set a global level filter for a - `FmtSubscriber` without requiring the use of `EnvFilter` (#336) -- `Layer` implementation for `LevelFilter` (#336) -- `EnvFilter` now implements `fmt::Display` (#329) - -### Removed - -- Removed dependency on `crossbeam-util` (#348) - -# 0.1.1 (September 4, 2019) - -### Fixed - -- Potential double panic in `CurrentSpan` (#325) - -# 0.1.0 (September 3, 2019) - -- Initial release diff --git a/vendor/tracing-subscriber/Cargo.toml b/vendor/tracing-subscriber/Cargo.toml deleted file mode 100644 index dd432c4ac..000000000 --- a/vendor/tracing-subscriber/Cargo.toml +++ /dev/null @@ -1,232 +0,0 @@ -# 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 = "2018" -rust-version = "1.49.0" -name = "tracing-subscriber" -version = "0.3.15" -authors = [ - "Eliza Weisman ", - "David Barsky ", - "Tokio Contributors ", -] -description = """ -Utilities for implementing and composing `tracing` subscribers. -""" -homepage = "https://tokio.rs" -readme = "README.md" -keywords = [ - "logging", - "tracing", - "metrics", - "subscriber", -] -categories = [ - "development-tools::debugging", - "development-tools::profiling", - "asynchronous", -] -license = "MIT" -repository = "https://github.com/tokio-rs/tracing" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = [ - "--cfg", - "docsrs", -] - -[[bench]] -name = "filter" -harness = false - -[[bench]] -name = "filter_log" -harness = false - -[[bench]] -name = "fmt" -harness = false - -[[bench]] -name = "enter" -harness = false - -[dependencies.ansi_term] -version = "0.12" -optional = true - -[dependencies.matchers] -version = "0.1.0" -optional = true - -[dependencies.once_cell] -version = "1.12" -optional = true - -[dependencies.parking_lot] -version = "0.12" -optional = true - -[dependencies.regex] -version = "1" -features = ["std"] -optional = true -default-features = false - -[dependencies.serde] -version = "1.0" -optional = true - -[dependencies.serde_json] -version = "1.0" -optional = true - -[dependencies.sharded-slab] -version = "0.1.0" -optional = true - -[dependencies.smallvec] -version = "1.2.0" -optional = true - -[dependencies.thread_local] -version = "1.1.4" -optional = true - -[dependencies.time] -version = "0.3" -features = ["formatting"] -optional = true - -[dependencies.tracing] -version = "0.1" -optional = true -default-features = false - -[dependencies.tracing-core] -version = "0.1.28" -default-features = false - -[dependencies.tracing-log] -version = "0.1.2" -features = [ - "log-tracer", - "std", -] -optional = true -default-features = false - -[dependencies.tracing-serde] -version = "0.1.3" -optional = true - -[dev-dependencies.criterion] -version = "0.3" -default_features = false - -[dev-dependencies.log] -version = "0.4" - -[dev-dependencies.regex] -version = "1" -features = ["std"] -default-features = false - -[dev-dependencies.time] -version = "0.3" -features = [ - "formatting", - "macros", -] - -[dev-dependencies.tokio] -version = "1" -features = [ - "rt", - "macros", -] - -[dev-dependencies.tracing] -version = "0.1" - -[dev-dependencies.tracing-futures] -version = "0.2" -features = [ - "std-future", - "std", -] -default-features = false - -[dev-dependencies.tracing-log] -version = "0.1.2" - -[features] -alloc = [] -ansi = [ - "fmt", - "ansi_term", -] -default = [ - "smallvec", - "fmt", - "ansi", - "tracing-log", - "std", -] -env-filter = [ - "matchers", - "regex", - "once_cell", - "tracing", - "std", - "thread_local", -] -fmt = [ - "registry", - "std", -] -json = [ - "tracing-serde", - "serde", - "serde_json", -] -local-time = ["time/local-offset"] -registry = [ - "sharded-slab", - "thread_local", - "std", -] -std = [ - "alloc", - "tracing-core/std", -] -valuable = [ - "tracing-core/valuable", - "valuable_crate", - "valuable-serde", - "tracing-serde/valuable", -] - -[target."cfg(tracing_unstable)".dependencies.valuable-serde] -version = "0.1.0" -optional = true -default_features = false - -[target."cfg(tracing_unstable)".dependencies.valuable_crate] -version = "0.1.0" -optional = true -default_features = false -package = "valuable" - -[badges.maintenance] -status = "experimental" diff --git a/vendor/tracing-subscriber/LICENSE b/vendor/tracing-subscriber/LICENSE deleted file mode 100644 index cdb28b4b5..000000000 --- a/vendor/tracing-subscriber/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2019 Tokio 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. diff --git a/vendor/tracing-subscriber/README.md b/vendor/tracing-subscriber/README.md deleted file mode 100644 index ba2b4e1c3..000000000 --- a/vendor/tracing-subscriber/README.md +++ /dev/null @@ -1,61 +0,0 @@ -![Tracing — Structured, application-level diagnostics][splash] - -[splash]: https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/splash.svg - -# tracing-subscriber - -Utilities for implementing and composing [`tracing`][tracing] subscribers. - -[![Crates.io][crates-badge]][crates-url] -[![Documentation][docs-badge]][docs-url] -[![Documentation (master)][docs-master-badge]][docs-master-url] -[![MIT licensed][mit-badge]][mit-url] -[![Build Status][actions-badge]][actions-url] -[![Discord chat][discord-badge]][discord-url] -![maintenance status][maint-badge] - -[Documentation][docs-url] | [Chat][discord-url] - -[tracing]: https://github.com/tokio-rs/tracing/tree/master/tracing -[tracing-fmt]: https://github.com/tokio-rs/tracing/tree/master/tracing-subscriber -[crates-badge]: https://img.shields.io/crates/v/tracing-subscriber.svg -[crates-url]: https://crates.io/crates/tracing-subscriber -[docs-badge]: https://docs.rs/tracing-subscriber/badge.svg -[docs-url]: https://docs.rs/tracing-subscriber/0.3.15 -[docs-master-badge]: https://img.shields.io/badge/docs-master-blue -[docs-master-url]: https://tracing-rs.netlify.com/tracing_subscriber -[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg -[mit-url]: LICENSE -[actions-badge]: https://github.com/tokio-rs/tracing/workflows/CI/badge.svg -[actions-url]:https://github.com/tokio-rs/tracing/actions?query=workflow%3ACI -[discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white -[discord-url]: https://discord.gg/EeF3cQw -[maint-badge]: https://img.shields.io/badge/maintenance-experimental-blue.svg - -*Compiler support: [requires `rustc` 1.49+][msrv]* - -[msrv]: #supported-rust-versions - -## Supported Rust Versions - -Tracing is built against the latest stable release. The minimum supported -version is 1.49. The current Tracing version is not guaranteed to build on Rust -versions earlier than the minimum supported version. - -Tracing follows the same compiler support policies as the rest of the Tokio -project. The current stable Rust compiler and the three most recent minor -versions before it will always be supported. For example, if the current stable -compiler version is 1.45, the minimum supported version will not be increased -past 1.42, three minor versions prior. Increasing the minimum supported compiler -version is not considered a semver breaking change as long as doing so complies -with this policy. - -## License - -This project is licensed under the [MIT license](LICENSE). - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Tracing by you, shall be licensed as MIT, without any additional -terms or conditions. diff --git a/vendor/tracing-subscriber/benches/enter.rs b/vendor/tracing-subscriber/benches/enter.rs deleted file mode 100644 index 49c6e730a..000000000 --- a/vendor/tracing-subscriber/benches/enter.rs +++ /dev/null @@ -1,64 +0,0 @@ -use criterion::{criterion_group, criterion_main, Criterion}; -use tracing_subscriber::prelude::*; - -fn enter(c: &mut Criterion) { - let mut group = c.benchmark_group("enter"); - let _subscriber = tracing_subscriber::fmt() - .with_max_level(tracing::Level::INFO) - .finish() - .set_default(); - group.bench_function("enabled", |b| { - let span = tracing::info_span!("foo"); - b.iter_with_large_drop(|| span.enter()) - }); - group.bench_function("disabled", |b| { - let span = tracing::debug_span!("foo"); - b.iter_with_large_drop(|| span.enter()) - }); -} - -fn enter_exit(c: &mut Criterion) { - let mut group = c.benchmark_group("enter_exit"); - let _subscriber = tracing_subscriber::fmt() - .with_max_level(tracing::Level::INFO) - .finish() - .set_default(); - group.bench_function("enabled", |b| { - let span = tracing::info_span!("foo"); - b.iter(|| span.enter()) - }); - group.bench_function("disabled", |b| { - let span = tracing::debug_span!("foo"); - b.iter(|| span.enter()) - }); -} - -fn enter_many(c: &mut Criterion) { - let mut group = c.benchmark_group("enter_many"); - let _subscriber = tracing_subscriber::fmt() - .with_max_level(tracing::Level::INFO) - .finish() - .set_default(); - group.bench_function("enabled", |b| { - let span1 = tracing::info_span!("span1"); - let _e1 = span1.enter(); - let span2 = tracing::info_span!("span2"); - let _e2 = span2.enter(); - let span3 = tracing::info_span!("span3"); - let _e3 = span3.enter(); - let span = tracing::info_span!("foo"); - b.iter_with_large_drop(|| span.enter()) - }); - group.bench_function("disabled", |b| { - let span1 = tracing::info_span!("span1"); - let _e1 = span1.enter(); - let span2 = tracing::info_span!("span2"); - let _e2 = span2.enter(); - let span3 = tracing::info_span!("span3"); - let _e3 = span3.enter(); - let span = tracing::debug_span!("foo"); - b.iter_with_large_drop(|| span.enter()) - }); -} -criterion_group!(benches, enter, enter_exit, enter_many); -criterion_main!(benches); diff --git a/vendor/tracing-subscriber/benches/filter.rs b/vendor/tracing-subscriber/benches/filter.rs deleted file mode 100644 index 91ab9c91d..000000000 --- a/vendor/tracing-subscriber/benches/filter.rs +++ /dev/null @@ -1,308 +0,0 @@ -use criterion::{criterion_group, criterion_main, Criterion}; -use std::time::Duration; -use tracing::{dispatcher::Dispatch, span, Event, Id, Metadata}; -use tracing_subscriber::{prelude::*, EnvFilter}; - -mod support; -use support::MultithreadedBench; - -/// A subscriber that is enabled but otherwise does nothing. -struct EnabledSubscriber; - -impl tracing::Subscriber for EnabledSubscriber { - fn new_span(&self, span: &span::Attributes<'_>) -> Id { - let _ = span; - Id::from_u64(0xDEAD_FACE) - } - - fn event(&self, event: &Event<'_>) { - let _ = event; - } - - fn record(&self, span: &Id, values: &span::Record<'_>) { - let _ = (span, values); - } - - fn record_follows_from(&self, span: &Id, follows: &Id) { - let _ = (span, follows); - } - - fn enabled(&self, metadata: &Metadata<'_>) -> bool { - let _ = metadata; - true - } - - fn enter(&self, span: &Id) { - let _ = span; - } - - fn exit(&self, span: &Id) { - let _ = span; - } -} - -fn bench_static(c: &mut Criterion) { - let mut group = c.benchmark_group("static"); - - group.bench_function("baseline_single_threaded", |b| { - tracing::subscriber::with_default(EnabledSubscriber, || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - tracing::debug!(target: "static_filter", "hi"); - tracing::warn!(target: "static_filter", "hi"); - tracing::trace!(target: "foo", "hi"); - }) - }); - }); - group.bench_function("single_threaded", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - tracing::debug!(target: "static_filter", "hi"); - tracing::warn!(target: "static_filter", "hi"); - tracing::trace!(target: "foo", "hi"); - }) - }); - }); - group.bench_function("enabled_one", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("enabled_many", |b| { - let filter = "foo=debug,bar=trace,baz=error,quux=warn,static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_level_one", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::debug!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_level_many", |b| { - let filter = "foo=debug,bar=info,baz=error,quux=warn,static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::trace!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_one", |b| { - let filter = "foo=info".parse::().expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_many", |b| { - let filter = "foo=debug,bar=trace,baz=error,quux=warn,whibble=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("baseline_multithreaded", |b| { - let dispatch = Dispatch::new(EnabledSubscriber); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - tracing::info!(target: "static_filter", "hi"); - }) - .thread(|| { - tracing::debug!(target: "static_filter", "hi"); - }) - .thread(|| { - tracing::warn!(target: "static_filter", "hi"); - }) - .thread(|| { - tracing::warn!(target: "foo", "hi"); - }) - .run(); - total += elapsed; - } - total - }) - }); - group.bench_function("multithreaded", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - tracing::info!(target: "static_filter", "hi"); - }) - .thread(|| { - tracing::debug!(target: "static_filter", "hi"); - }) - .thread(|| { - tracing::warn!(target: "static_filter", "hi"); - }) - .thread(|| { - tracing::warn!(target: "foo", "hi"); - }) - .run(); - total += elapsed; - } - total - }); - }); - group.finish(); -} - -fn bench_dynamic(c: &mut Criterion) { - let mut group = c.benchmark_group("dynamic"); - - group.bench_function("baseline_single_threaded", |b| { - tracing::subscriber::with_default(EnabledSubscriber, || { - b.iter(|| { - tracing::info_span!("foo").in_scope(|| { - tracing::info!("hi"); - tracing::debug!("hi"); - }); - tracing::info_span!("bar").in_scope(|| { - tracing::warn!("hi"); - }); - tracing::trace!("hi"); - }) - }); - }); - group.bench_function("single_threaded", |b| { - let filter = "[foo]=trace".parse::().expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info_span!("foo").in_scope(|| { - tracing::info!("hi"); - tracing::debug!("hi"); - }); - tracing::info_span!("bar").in_scope(|| { - tracing::warn!("hi"); - }); - tracing::trace!("hi"); - }) - }); - }); - group.bench_function("baseline_multithreaded", |b| { - let dispatch = Dispatch::new(EnabledSubscriber); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - tracing::info!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - tracing::debug!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("bar"); - let _ = span.enter(); - tracing::debug!("hi"); - }) - .thread(|| { - tracing::trace!("hi"); - }) - .run(); - total += elapsed; - } - total - }) - }); - group.bench_function("multithreaded", |b| { - let filter = "[foo]=trace".parse::().expect("should parse"); - let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - tracing::info!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - tracing::debug!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("bar"); - let _ = span.enter(); - tracing::debug!("hi"); - }) - .thread(|| { - tracing::trace!("hi"); - }) - .run(); - total += elapsed; - } - total - }) - }); - - group.finish(); -} - -fn bench_mixed(c: &mut Criterion) { - let mut group = c.benchmark_group("mixed"); - group.bench_function("disabled", |b| { - let filter = "[foo]=trace,bar[quux]=debug,[{baz}]=debug,asdf=warn,wibble=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_by_level", |b| { - let filter = "[foo]=info,bar[quux]=debug,asdf=warn,static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::trace!(target: "static_filter", "hi"); - }) - }); - }); -} - -criterion_group!(benches, bench_static, bench_dynamic, bench_mixed); -criterion_main!(benches); diff --git a/vendor/tracing-subscriber/benches/filter_log.rs b/vendor/tracing-subscriber/benches/filter_log.rs deleted file mode 100644 index 4dcf3b4ec..000000000 --- a/vendor/tracing-subscriber/benches/filter_log.rs +++ /dev/null @@ -1,315 +0,0 @@ -use criterion::{criterion_group, criterion_main, Criterion}; -use std::time::Duration; -use tracing::{dispatcher::Dispatch, span, Event, Id, Metadata}; -use tracing_subscriber::{prelude::*, EnvFilter}; - -mod support; -use support::MultithreadedBench; - -/// A subscriber that is enabled but otherwise does nothing. -struct EnabledSubscriber; - -impl tracing::Subscriber for EnabledSubscriber { - fn new_span(&self, span: &span::Attributes<'_>) -> Id { - let _ = span; - Id::from_u64(0xDEAD_FACE) - } - - fn event(&self, event: &Event<'_>) { - let _ = event; - } - - fn record(&self, span: &Id, values: &span::Record<'_>) { - let _ = (span, values); - } - - fn record_follows_from(&self, span: &Id, follows: &Id) { - let _ = (span, follows); - } - - fn enabled(&self, metadata: &Metadata<'_>) -> bool { - let _ = metadata; - true - } - - fn enter(&self, span: &Id) { - let _ = span; - } - - fn exit(&self, span: &Id) { - let _ = span; - } -} - -fn bench_static(c: &mut Criterion) { - let _ = tracing_log::LogTracer::init(); - - let mut group = c.benchmark_group("log/static"); - - group.bench_function("baseline_single_threaded", |b| { - tracing::subscriber::with_default(EnabledSubscriber, || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - log::debug!(target: "static_filter", "hi"); - log::warn!(target: "static_filter", "hi"); - log::trace!(target: "foo", "hi"); - }) - }); - }); - group.bench_function("single_threaded", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - log::debug!(target: "static_filter", "hi"); - log::warn!(target: "static_filter", "hi"); - log::trace!(target: "foo", "hi"); - }) - }); - }); - group.bench_function("enabled_one", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("enabled_many", |b| { - let filter = "foo=debug,bar=trace,baz=error,quux=warn,static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_level_one", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::debug!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_level_many", |b| { - let filter = "foo=debug,bar=info,baz=error,quux=warn,static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::trace!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_one", |b| { - let filter = "foo=info".parse::().expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_many", |b| { - let filter = "foo=debug,bar=trace,baz=error,quux=warn,whibble=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("baseline_multithreaded", |b| { - let dispatch = Dispatch::new(EnabledSubscriber); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - log::info!(target: "static_filter", "hi"); - }) - .thread(|| { - log::debug!(target: "static_filter", "hi"); - }) - .thread(|| { - log::warn!(target: "static_filter", "hi"); - }) - .thread(|| { - log::warn!(target: "foo", "hi"); - }) - .run(); - total += elapsed; - } - total - }) - }); - group.bench_function("multithreaded", |b| { - let filter = "static_filter=info" - .parse::() - .expect("should parse"); - let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - log::info!(target: "static_filter", "hi"); - }) - .thread(|| { - log::debug!(target: "static_filter", "hi"); - }) - .thread(|| { - log::warn!(target: "static_filter", "hi"); - }) - .thread(|| { - log::warn!(target: "foo", "hi"); - }) - .run(); - total += elapsed; - } - total - }); - }); - group.finish(); -} - -fn bench_dynamic(c: &mut Criterion) { - let _ = tracing_log::LogTracer::init(); - - let mut group = c.benchmark_group("log/dynamic"); - - group.bench_function("baseline_single_threaded", |b| { - tracing::subscriber::with_default(EnabledSubscriber, || { - b.iter(|| { - tracing::info_span!("foo").in_scope(|| { - log::info!("hi"); - log::debug!("hi"); - }); - tracing::info_span!("bar").in_scope(|| { - log::warn!("hi"); - }); - log::trace!("hi"); - }) - }); - }); - group.bench_function("single_threaded", |b| { - let filter = "[foo]=trace".parse::().expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - tracing::info_span!("foo").in_scope(|| { - log::info!("hi"); - log::debug!("hi"); - }); - tracing::info_span!("bar").in_scope(|| { - log::warn!("hi"); - }); - log::trace!("hi"); - }) - }); - }); - group.bench_function("baseline_multithreaded", |b| { - let dispatch = Dispatch::new(EnabledSubscriber); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - log::info!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - log::debug!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("bar"); - let _ = span.enter(); - log::debug!("hi"); - }) - .thread(|| { - log::trace!("hi"); - }) - .run(); - total += elapsed; - } - total - }) - }); - group.bench_function("multithreaded", |b| { - let filter = "[foo]=trace".parse::().expect("should parse"); - let dispatch = Dispatch::new(EnabledSubscriber.with(filter)); - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - log::info!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("foo"); - let _ = span.enter(); - log::debug!("hi"); - }) - .thread(|| { - let span = tracing::info_span!("bar"); - let _ = span.enter(); - log::debug!("hi"); - }) - .thread(|| { - log::trace!("hi"); - }) - .run(); - total += elapsed; - } - total - }) - }); - - group.finish(); -} - -fn bench_mixed(c: &mut Criterion) { - let _ = tracing_log::LogTracer::init(); - - let mut group = c.benchmark_group("log/mixed"); - - group.bench_function("disabled", |b| { - let filter = "[foo]=trace,bar[quux]=debug,[{baz}]=debug,asdf=warn,wibble=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::info!(target: "static_filter", "hi"); - }) - }); - }); - group.bench_function("disabled_by_level", |b| { - let filter = "[foo]=info,bar[quux]=debug,asdf=warn,static_filter=info" - .parse::() - .expect("should parse"); - tracing::subscriber::with_default(EnabledSubscriber.with(filter), || { - b.iter(|| { - log::trace!(target: "static_filter", "hi"); - }) - }); - }); -} - -criterion_group!(benches, bench_static, bench_dynamic, bench_mixed); -criterion_main!(benches); diff --git a/vendor/tracing-subscriber/benches/fmt.rs b/vendor/tracing-subscriber/benches/fmt.rs deleted file mode 100644 index a039e66d4..000000000 --- a/vendor/tracing-subscriber/benches/fmt.rs +++ /dev/null @@ -1,331 +0,0 @@ -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; -use std::{io, time::Duration}; - -mod support; -use support::MultithreadedBench; - -/// A fake writer that doesn't actually do anything. -/// -/// We want to measure the subscriber's overhead, *not* the performance of -/// stdout/file writers. Using a no-op Write implementation lets us only measure -/// the subscriber's overhead. -struct NoWriter; - -impl io::Write for NoWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl NoWriter { - fn new() -> Self { - Self - } -} - -fn bench_new_span(c: &mut Criterion) { - bench_thrpt(c, "new_span", |group, i| { - group.bench_with_input(BenchmarkId::new("single_thread", i), i, |b, &i| { - tracing::dispatcher::with_default(&mk_dispatch(), || { - b.iter(|| { - for n in 0..i { - let _span = tracing::info_span!("span", n); - } - }) - }); - }); - group.bench_with_input(BenchmarkId::new("multithreaded", i), i, |b, &i| { - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - let dispatch = mk_dispatch(); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(move || { - for n in 0..i { - let _span = tracing::info_span!("span", n); - } - }) - .thread(move || { - for n in 0..i { - let _span = tracing::info_span!("span", n); - } - }) - .thread(move || { - for n in 0..i { - let _span = tracing::info_span!("span", n); - } - }) - .thread(move || { - for n in 0..i { - let _span = tracing::info_span!("span", n); - } - }) - .run(); - total += elapsed; - } - total - }) - }); - }); -} - -type Group<'a> = criterion::BenchmarkGroup<'a, criterion::measurement::WallTime>; -fn bench_thrpt(c: &mut Criterion, name: &'static str, mut f: impl FnMut(&mut Group<'_>, &usize)) { - const N_SPANS: &[usize] = &[1, 10, 50]; - - let mut group = c.benchmark_group(name); - for spans in N_SPANS { - group.throughput(Throughput::Elements(*spans as u64)); - f(&mut group, spans); - } - group.finish(); -} - -fn mk_dispatch() -> tracing::Dispatch { - let subscriber = tracing_subscriber::FmtSubscriber::builder() - .with_writer(NoWriter::new) - .finish(); - tracing::Dispatch::new(subscriber) -} - -fn bench_event(c: &mut Criterion) { - bench_thrpt(c, "event", |group, i| { - group.bench_with_input(BenchmarkId::new("root/single_threaded", i), i, |b, &i| { - let dispatch = mk_dispatch(); - tracing::dispatcher::with_default(&dispatch, || { - b.iter(|| { - for n in 0..i { - tracing::info!(n); - } - }) - }); - }); - group.bench_with_input(BenchmarkId::new("root/multithreaded", i), i, |b, &i| { - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - let dispatch = mk_dispatch(); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread(move || { - for n in 0..i { - tracing::info!(n); - } - }) - .thread(move || { - for n in 0..i { - tracing::info!(n); - } - }) - .thread(move || { - for n in 0..i { - tracing::info!(n); - } - }) - .thread(move || { - for n in 0..i { - tracing::info!(n); - } - }) - .run(); - total += elapsed; - } - total - }) - }); - group.bench_with_input( - BenchmarkId::new("unique_parent/single_threaded", i), - i, - |b, &i| { - tracing::dispatcher::with_default(&mk_dispatch(), || { - let span = tracing::info_span!("unique_parent", foo = false); - let _guard = span.enter(); - b.iter(|| { - for n in 0..i { - tracing::info!(n); - } - }) - }); - }, - ); - group.bench_with_input( - BenchmarkId::new("unique_parent/multithreaded", i), - i, - |b, &i| { - b.iter_custom(|iters| { - let mut total = Duration::from_secs(0); - let dispatch = mk_dispatch(); - for _ in 0..iters { - let bench = MultithreadedBench::new(dispatch.clone()); - let elapsed = bench - .thread_with_setup(move |start| { - let span = tracing::info_span!("unique_parent", foo = false); - let _guard = span.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }) - .thread_with_setup(move |start| { - let span = tracing::info_span!("unique_parent", foo = false); - let _guard = span.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }) - .thread_with_setup(move |start| { - let span = tracing::info_span!("unique_parent", foo = false); - let _guard = span.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }) - .thread_with_setup(move |start| { - let span = tracing::info_span!("unique_parent", foo = false); - let _guard = span.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }) - .run(); - total += elapsed; - } - total - }) - }, - ); - group.bench_with_input( - BenchmarkId::new("shared_parent/multithreaded", i), - i, - |b, &i| { - b.iter_custom(|iters| { - let dispatch = mk_dispatch(); - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let parent = tracing::dispatcher::with_default(&dispatch, || { - tracing::info_span!("shared_parent", foo = "hello world") - }); - let bench = MultithreadedBench::new(dispatch.clone()); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - for n in 0..i { - tracing::info!(n); - } - }); - let elapsed = bench.run(); - total += elapsed; - } - total - }) - }, - ); - group.bench_with_input( - BenchmarkId::new("multi-parent/multithreaded", i), - i, - |b, &i| { - b.iter_custom(|iters| { - let dispatch = mk_dispatch(); - let mut total = Duration::from_secs(0); - for _ in 0..iters { - let parent = tracing::dispatcher::with_default(&dispatch, || { - tracing::info_span!("multiparent", foo = "hello world") - }); - let bench = MultithreadedBench::new(dispatch.clone()); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - let mut span = tracing::info_span!("parent"); - for n in 0..i { - let s = tracing::info_span!(parent: &span, "parent2", n, i); - s.in_scope(|| { - tracing::info!(n); - }); - span = s; - } - }); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - let mut span = tracing::info_span!("parent"); - for n in 0..i { - let s = tracing::info_span!(parent: &span, "parent2", n, i); - s.in_scope(|| { - tracing::info!(n); - }); - span = s; - } - }); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - let mut span = tracing::info_span!("parent"); - for n in 0..i { - let s = tracing::info_span!(parent: &span, "parent2", n, i); - s.in_scope(|| { - tracing::info!(n); - }); - span = s; - } - }); - let parent2 = parent.clone(); - bench.thread_with_setup(move |start| { - let _guard = parent2.enter(); - start.wait(); - let mut span = tracing::info_span!("parent"); - for n in 0..i { - let s = tracing::info_span!(parent: &span, "parent2", n, i); - s.in_scope(|| { - tracing::info!(n); - }); - span = s; - } - }); - let elapsed = bench.run(); - total += elapsed; - } - total - }) - }, - ); - }); -} - -criterion_group!(benches, bench_new_span, bench_event); -criterion_main!(benches); diff --git a/vendor/tracing-subscriber/benches/support/mod.rs b/vendor/tracing-subscriber/benches/support/mod.rs deleted file mode 100644 index 25e9e7e22..000000000 --- a/vendor/tracing-subscriber/benches/support/mod.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::{ - sync::{Arc, Barrier}, - thread, - time::{Duration, Instant}, -}; -use tracing::dispatcher::Dispatch; - -#[derive(Clone)] -pub(super) struct MultithreadedBench { - start: Arc, - end: Arc, - dispatch: Dispatch, -} - -impl MultithreadedBench { - pub(super) fn new(dispatch: Dispatch) -> Self { - Self { - start: Arc::new(Barrier::new(5)), - end: Arc::new(Barrier::new(5)), - dispatch, - } - } - - pub(super) fn thread(&self, f: impl FnOnce() + Send + 'static) -> &Self { - self.thread_with_setup(|start| { - start.wait(); - f() - }) - } - - pub(super) fn thread_with_setup(&self, f: impl FnOnce(&Barrier) + Send + 'static) -> &Self { - let this = self.clone(); - thread::spawn(move || { - let dispatch = this.dispatch.clone(); - tracing::dispatcher::with_default(&dispatch, move || { - f(&*this.start); - this.end.wait(); - }) - }); - self - } - - pub(super) fn run(&self) -> Duration { - self.start.wait(); - let t0 = Instant::now(); - self.end.wait(); - t0.elapsed() - } -} diff --git a/vendor/tracing-subscriber/src/field/debug.rs b/vendor/tracing-subscriber/src/field/debug.rs deleted file mode 100644 index cc67d29fe..000000000 --- a/vendor/tracing-subscriber/src/field/debug.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! `MakeVisitor` wrappers for working with `fmt::Debug` fields. -use super::{MakeVisitor, VisitFmt, VisitOutput}; -use tracing_core::field::{Field, Visit}; - -use core::fmt; - -/// A visitor wrapper that ensures any `fmt::Debug` fields are formatted using -/// the alternate (`:#`) formatter. -#[derive(Debug, Clone)] -pub struct Alt(V); - -// TODO(eliza): When `error` as a primitive type is stable, add a -// `DisplayErrors` wrapper... - -// === impl Alt === -// -impl Alt { - /// Wraps the provided visitor so that any `fmt::Debug` fields are formatted - /// using the alternative (`:#`) formatter. - pub fn new(inner: V) -> Self { - Alt(inner) - } -} - -impl MakeVisitor for Alt -where - V: MakeVisitor, -{ - type Visitor = Alt; - - #[inline] - fn make_visitor(&self, target: T) -> Self::Visitor { - Alt(self.0.make_visitor(target)) - } -} - -impl Visit for Alt -where - V: Visit, -{ - #[inline] - fn record_f64(&mut self, field: &Field, value: f64) { - self.0.record_f64(field, value) - } - - #[inline] - fn record_i64(&mut self, field: &Field, value: i64) { - self.0.record_i64(field, value) - } - - #[inline] - fn record_u64(&mut self, field: &Field, value: u64) { - self.0.record_u64(field, value) - } - - #[inline] - fn record_bool(&mut self, field: &Field, value: bool) { - self.0.record_bool(field, value) - } - - /// Visit a string value. - fn record_str(&mut self, field: &Field, value: &str) { - self.0.record_str(field, value) - } - - // TODO(eliza): add RecordError when stable - // fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { - // self.record_debug(field, &format_args!("{}", value)) - // } - - #[inline] - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - self.0.record_debug(field, &format_args!("{:#?}", value)) - } -} - -impl VisitOutput for Alt -where - V: VisitOutput, -{ - #[inline] - fn finish(self) -> O { - self.0.finish() - } -} - -feature! { - #![feature = "std"] - use super::VisitWrite; - use std::io; - - impl VisitWrite for Alt - where - V: VisitWrite, - { - #[inline] - fn writer(&mut self) -> &mut dyn io::Write { - self.0.writer() - } - } -} - -impl VisitFmt for Alt -where - V: VisitFmt, -{ - #[inline] - fn writer(&mut self) -> &mut dyn fmt::Write { - self.0.writer() - } -} diff --git a/vendor/tracing-subscriber/src/field/delimited.rs b/vendor/tracing-subscriber/src/field/delimited.rs deleted file mode 100644 index 98634cea9..000000000 --- a/vendor/tracing-subscriber/src/field/delimited.rs +++ /dev/null @@ -1,184 +0,0 @@ -//! A `MakeVisitor` wrapper that separates formatted fields with a delimiter. -use super::{MakeVisitor, VisitFmt, VisitOutput}; - -use core::fmt; -use tracing_core::field::{Field, Visit}; - -/// A `MakeVisitor` wrapper that wraps a visitor that writes formatted output so -/// that a delimiter is inserted between writing formatted field values. -#[derive(Debug, Clone)] -pub struct Delimited { - delimiter: D, - inner: V, -} - -/// A visitor wrapper that inserts a delimiter after the wrapped visitor formats -/// a field value. -#[derive(Debug)] -pub struct VisitDelimited { - delimiter: D, - seen: bool, - inner: V, - err: fmt::Result, -} - -// === impl Delimited === - -impl MakeVisitor for Delimited -where - D: AsRef + Clone, - V: MakeVisitor, - V::Visitor: VisitFmt, -{ - type Visitor = VisitDelimited; - fn make_visitor(&self, target: T) -> Self::Visitor { - let inner = self.inner.make_visitor(target); - VisitDelimited::new(self.delimiter.clone(), inner) - } -} - -impl Delimited { - /// Returns a new [`MakeVisitor`] implementation that wraps `inner` so that - /// it will format each visited field separated by the provided `delimiter`. - /// - /// [`MakeVisitor`]: super::MakeVisitor - pub fn new(delimiter: D, inner: V) -> Self { - Self { delimiter, inner } - } -} - -// === impl VisitDelimited === - -impl VisitDelimited { - /// Returns a new [`Visit`] implementation that wraps `inner` so that - /// each formatted field is separated by the provided `delimiter`. - /// - /// [`Visit`]: tracing_core::field::Visit - pub fn new(delimiter: D, inner: V) -> Self { - Self { - delimiter, - inner, - seen: false, - err: Ok(()), - } - } - - fn delimit(&mut self) - where - V: VisitFmt, - D: AsRef, - { - if self.err.is_err() { - return; - } - - if self.seen { - self.err = self.inner.writer().write_str(self.delimiter.as_ref()); - } - - self.seen = true; - } -} - -impl Visit for VisitDelimited -where - V: VisitFmt, - D: AsRef, -{ - fn record_i64(&mut self, field: &Field, value: i64) { - self.delimit(); - self.inner.record_i64(field, value); - } - - fn record_u64(&mut self, field: &Field, value: u64) { - self.delimit(); - self.inner.record_u64(field, value); - } - - fn record_bool(&mut self, field: &Field, value: bool) { - self.delimit(); - self.inner.record_bool(field, value); - } - - fn record_str(&mut self, field: &Field, value: &str) { - self.delimit(); - self.inner.record_str(field, value); - } - - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - self.delimit(); - self.inner.record_debug(field, value); - } -} - -impl VisitOutput for VisitDelimited -where - V: VisitFmt, - D: AsRef, -{ - fn finish(self) -> fmt::Result { - self.err?; - self.inner.finish() - } -} - -impl VisitFmt for VisitDelimited -where - V: VisitFmt, - D: AsRef, -{ - fn writer(&mut self) -> &mut dyn fmt::Write { - self.inner.writer() - } -} - -#[cfg(test)] -#[cfg(all(test, feature = "alloc"))] -mod test { - use super::*; - use crate::field::test_util::*; - - #[test] - fn delimited_visitor() { - let mut s = String::new(); - let visitor = DebugVisitor::new(&mut s); - let mut visitor = VisitDelimited::new(", ", visitor); - - TestAttrs1::with(|attrs| attrs.record(&mut visitor)); - visitor.finish().unwrap(); - - assert_eq!( - s.as_str(), - "question=\"life, the universe, and everything\", tricky=true, can_you_do_it=true" - ); - } - - #[test] - fn delimited_new_visitor() { - let make = Delimited::new("; ", MakeDebug); - - TestAttrs1::with(|attrs| { - let mut s = String::new(); - { - let mut v = make.make_visitor(&mut s); - attrs.record(&mut v); - } - assert_eq!( - s.as_str(), - "question=\"life, the universe, and everything\"; tricky=true; can_you_do_it=true" - ); - }); - - TestAttrs2::with(|attrs| { - let mut s = String::new(); - { - let mut v = make.make_visitor(&mut s); - attrs.record(&mut v); - } - assert_eq!( - s.as_str(), - "question=None; question.answer=42; tricky=true; can_you_do_it=false" - ); - }); - } -} diff --git a/vendor/tracing-subscriber/src/field/display.rs b/vendor/tracing-subscriber/src/field/display.rs deleted file mode 100644 index 78a039ce1..000000000 --- a/vendor/tracing-subscriber/src/field/display.rs +++ /dev/null @@ -1,117 +0,0 @@ -//! `MakeVisitor` wrappers for working with `fmt::Display` fields. -use super::{MakeVisitor, VisitFmt, VisitOutput}; -use tracing_core::field::{Field, Visit}; - -use core::fmt; - -/// A visitor wrapper that ensures any strings named "message" are formatted -/// using `fmt::Display` -#[derive(Debug, Clone)] -pub struct Messages(V); - -// TODO(eliza): When `error` as a primitive type is stable, add a -// `DisplayErrors` wrapper... - -// === impl Messages === -// -impl Messages { - /// Returns a new [`MakeVisitor`] implementation that will wrap `inner` so - /// that any strings named `message` are formatted using `fmt::Display`. - /// - /// [`MakeVisitor`]: super::MakeVisitor - pub fn new(inner: V) -> Self { - Messages(inner) - } -} - -impl MakeVisitor for Messages -where - V: MakeVisitor, -{ - type Visitor = Messages; - - #[inline] - fn make_visitor(&self, target: T) -> Self::Visitor { - Messages(self.0.make_visitor(target)) - } -} - -impl Visit for Messages -where - V: Visit, -{ - #[inline] - fn record_f64(&mut self, field: &Field, value: f64) { - self.0.record_f64(field, value) - } - - #[inline] - fn record_i64(&mut self, field: &Field, value: i64) { - self.0.record_i64(field, value) - } - - #[inline] - fn record_u64(&mut self, field: &Field, value: u64) { - self.0.record_u64(field, value) - } - - #[inline] - fn record_bool(&mut self, field: &Field, value: bool) { - self.0.record_bool(field, value) - } - - /// Visit a string value. - fn record_str(&mut self, field: &Field, value: &str) { - if field.name() == "message" { - self.0.record_debug(field, &format_args!("{}", value)) - } else { - self.0.record_str(field, value) - } - } - - // TODO(eliza): add RecordError when stable - // fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { - // self.record_debug(field, &format_args!("{}", value)) - // } - - #[inline] - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - self.0.record_debug(field, value) - } -} - -impl VisitOutput for Messages -where - V: VisitOutput, -{ - #[inline] - fn finish(self) -> O { - self.0.finish() - } -} - -feature! { - #![feature = "std"] - use super::VisitWrite; - use std::io; - - impl VisitWrite for Messages - where - V: VisitWrite, - { - #[inline] - fn writer(&mut self) -> &mut dyn io::Write { - self.0.writer() - } - } -} - -impl VisitFmt for Messages -where - V: VisitFmt, -{ - #[inline] - fn writer(&mut self) -> &mut dyn fmt::Write { - self.0.writer() - } -} diff --git a/vendor/tracing-subscriber/src/field/mod.rs b/vendor/tracing-subscriber/src/field/mod.rs deleted file mode 100644 index 5dfddb362..000000000 --- a/vendor/tracing-subscriber/src/field/mod.rs +++ /dev/null @@ -1,366 +0,0 @@ -//! Utilities for working with [fields] and [field visitors]. -//! -//! [fields]: tracing_core::field -//! [field visitors]: tracing_core::field::Visit -use core::{fmt, marker::PhantomData}; -pub use tracing_core::field::Visit; -use tracing_core::{ - span::{Attributes, Record}, - Event, -}; -pub mod debug; -pub mod delimited; -pub mod display; - -/// Creates new [visitors]. -/// -/// A type implementing `MakeVisitor` represents a composable factory for types -/// implementing the [`Visit` trait][visitors]. The `MakeVisitor` trait defines -/// a single function, `make_visitor`, which takes in a `T`-typed `target` and -/// returns a type implementing `Visit` configured for that target. A target may -/// be a string, output stream, or data structure that the visitor will record -/// data to, configuration variables that determine the visitor's behavior, or -/// `()` when no input is required to produce a visitor. -/// -/// [visitors]: tracing_core::field::Visit -pub trait MakeVisitor { - /// The visitor type produced by this `MakeVisitor`. - type Visitor: Visit; - - /// Make a new visitor for the provided `target`. - fn make_visitor(&self, target: T) -> Self::Visitor; -} - -/// A [visitor] that produces output once it has visited a set of fields. -/// -/// [visitor]: tracing_core::field::Visit -pub trait VisitOutput: Visit { - /// Completes the visitor, returning any output. - /// - /// This is called once a full set of fields has been visited. - fn finish(self) -> Out; - - /// Visit a set of fields, and return the output of finishing the visitor - /// once the fields have been visited. - fn visit(mut self, fields: &R) -> Out - where - R: RecordFields, - Self: Sized, - { - fields.record(&mut self); - self.finish() - } -} - -/// Extension trait implemented by types which can be recorded by a [visitor]. -/// -/// This allows writing code that is generic over `tracing_core`'s -/// [`span::Attributes`][attr], [`span::Record`][rec], and [`Event`][event] -/// types. These types all provide inherent `record` methods that allow a -/// visitor to record their fields, but there is no common trait representing this. -/// -/// With `RecordFields`, we can write code like this: -/// ``` -/// use tracing_core::field::Visit; -/// # use tracing_core::field::Field; -/// use tracing_subscriber::field::RecordFields; -/// -/// struct MyVisitor { -/// // ... -/// } -/// # impl MyVisitor { fn new() -> Self { Self{} } } -/// impl Visit for MyVisitor { -/// // ... -/// # fn record_debug(&mut self, _: &Field, _: &dyn std::fmt::Debug) {} -/// } -/// -/// fn record_with_my_visitor(r: R) -/// where -/// R: RecordFields, -/// { -/// let mut visitor = MyVisitor::new(); -/// r.record(&mut visitor); -/// } -/// ``` -/// [visitor]: tracing_core::field::Visit -/// [attr]: tracing_core::span::Attributes -/// [rec]: tracing_core::span::Record -/// [event]: tracing_core::event::Event -pub trait RecordFields: crate::sealed::Sealed { - /// Record all the fields in `self` with the provided `visitor`. - fn record(&self, visitor: &mut dyn Visit); -} - -/// Extension trait implemented for all `MakeVisitor` implementations that -/// produce a visitor implementing `VisitOutput`. -pub trait MakeOutput -where - Self: MakeVisitor + crate::sealed::Sealed<(T, Out)>, - Self::Visitor: VisitOutput, -{ - /// Visits all fields in `fields` with a new visitor constructed from - /// `target`. - fn visit_with(&self, target: T, fields: &F) -> Out - where - F: RecordFields, - { - self.make_visitor(target).visit(fields) - } -} - -feature! { - #![feature = "std"] - use std::io; - - /// Extension trait implemented by visitors to indicate that they write to an - /// `io::Write` instance, and allow access to that writer. - pub trait VisitWrite: VisitOutput> { - /// Returns the writer that this visitor writes to. - fn writer(&mut self) -> &mut dyn io::Write; - } -} - -/// Extension trait implemented by visitors to indicate that they write to a -/// `fmt::Write` instance, and allow access to that writer. -pub trait VisitFmt: VisitOutput { - /// Returns the formatter that this visitor writes to. - fn writer(&mut self) -> &mut dyn fmt::Write; -} - -/// Extension trait providing `MakeVisitor` combinators. -pub trait MakeExt -where - Self: MakeVisitor + Sized, - Self: crate::sealed::Sealed>, -{ - /// Wraps `self` so that any `fmt::Debug` fields are recorded using the - /// alternate formatter (`{:#?}`). - fn debug_alt(self) -> debug::Alt { - debug::Alt::new(self) - } - - /// Wraps `self` so that any string fields named "message" are recorded - /// using `fmt::Display`. - fn display_messages(self) -> display::Messages { - display::Messages::new(self) - } - - /// Wraps `self` so that when fields are formatted to a writer, they are - /// separated by the provided `delimiter`. - fn delimited(self, delimiter: D) -> delimited::Delimited - where - D: AsRef + Clone, - Self::Visitor: VisitFmt, - { - delimited::Delimited::new(delimiter, self) - } -} - -// === impl RecordFields === - -impl<'a> crate::sealed::Sealed for Event<'a> {} -impl<'a> RecordFields for Event<'a> { - fn record(&self, visitor: &mut dyn Visit) { - Event::record(self, visitor) - } -} - -impl<'a> crate::sealed::Sealed for Attributes<'a> {} -impl<'a> RecordFields for Attributes<'a> { - fn record(&self, visitor: &mut dyn Visit) { - Attributes::record(self, visitor) - } -} - -impl<'a> crate::sealed::Sealed for Record<'a> {} -impl<'a> RecordFields for Record<'a> { - fn record(&self, visitor: &mut dyn Visit) { - Record::record(self, visitor) - } -} - -impl<'a, F> crate::sealed::Sealed for &'a F where F: RecordFields {} -impl<'a, F> RecordFields for &'a F -where - F: RecordFields, -{ - fn record(&self, visitor: &mut dyn Visit) { - F::record(*self, visitor) - } -} - -// === blanket impls === - -impl MakeVisitor for F -where - F: Fn(T) -> V, - V: Visit, -{ - type Visitor = V; - fn make_visitor(&self, target: T) -> Self::Visitor { - (self)(target) - } -} - -impl crate::sealed::Sealed<(T, Out)> for M -where - M: MakeVisitor, - M::Visitor: VisitOutput, -{ -} - -impl MakeOutput for M -where - M: MakeVisitor, - M::Visitor: VisitOutput, -{ -} - -impl crate::sealed::Sealed> for M where M: MakeVisitor + Sized {} - -impl MakeExt for M -where - M: MakeVisitor + Sized, - M: crate::sealed::Sealed>, -{ -} - -#[derive(Debug)] -#[doc(hidden)] -pub struct MakeExtMarker { - _p: PhantomData, -} - -#[derive(Debug)] -#[doc(hidden)] -pub struct RecordFieldsMarker { - _p: (), -} - -#[cfg(all(test, feature = "alloc"))] -#[macro_use] -pub(in crate::field) mod test_util { - use super::*; - pub(in crate::field) use alloc::string::String; - use tracing_core::{ - callsite::Callsite, - field::{Field, Value}, - metadata::{Kind, Level, Metadata}, - }; - - pub(crate) struct TestAttrs1; - pub(crate) struct TestAttrs2; - - impl TestAttrs1 { - pub(crate) fn with(f: impl FnOnce(Attributes<'_>) -> T) -> T { - let fieldset = TEST_META_1.fields(); - let values = &[ - ( - &fieldset.field("question").unwrap(), - Some(&"life, the universe, and everything" as &dyn Value), - ), - (&fieldset.field("question.answer").unwrap(), None), - ( - &fieldset.field("tricky").unwrap(), - Some(&true as &dyn Value), - ), - ( - &fieldset.field("can_you_do_it").unwrap(), - Some(&true as &dyn Value), - ), - ]; - let valueset = fieldset.value_set(values); - let attrs = tracing_core::span::Attributes::new(&TEST_META_1, &valueset); - f(attrs) - } - } - - impl TestAttrs2 { - pub(crate) fn with(f: impl FnOnce(Attributes<'_>) -> T) -> T { - let fieldset = TEST_META_1.fields(); - let none = tracing_core::field::debug(&Option::<&str>::None); - let values = &[ - ( - &fieldset.field("question").unwrap(), - Some(&none as &dyn Value), - ), - ( - &fieldset.field("question.answer").unwrap(), - Some(&42 as &dyn Value), - ), - ( - &fieldset.field("tricky").unwrap(), - Some(&true as &dyn Value), - ), - ( - &fieldset.field("can_you_do_it").unwrap(), - Some(&false as &dyn Value), - ), - ]; - let valueset = fieldset.value_set(values); - let attrs = tracing_core::span::Attributes::new(&TEST_META_1, &valueset); - f(attrs) - } - } - - struct TestCallsite1; - static TEST_CALLSITE_1: &'static dyn Callsite = &TestCallsite1; - static TEST_META_1: Metadata<'static> = tracing_core::metadata! { - name: "field_test1", - target: module_path!(), - level: Level::INFO, - fields: &["question", "question.answer", "tricky", "can_you_do_it"], - callsite: TEST_CALLSITE_1, - kind: Kind::SPAN, - }; - - impl Callsite for TestCallsite1 { - fn set_interest(&self, _: tracing_core::subscriber::Interest) { - unimplemented!() - } - - fn metadata(&self) -> &Metadata<'_> { - &TEST_META_1 - } - } - - pub(crate) struct MakeDebug; - pub(crate) struct DebugVisitor<'a> { - writer: &'a mut dyn fmt::Write, - err: fmt::Result, - } - - impl<'a> DebugVisitor<'a> { - pub(crate) fn new(writer: &'a mut dyn fmt::Write) -> Self { - Self { - writer, - err: Ok(()), - } - } - } - - impl<'a> Visit for DebugVisitor<'a> { - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - write!(self.writer, "{}={:?}", field, value).unwrap(); - } - } - - impl<'a> VisitOutput for DebugVisitor<'a> { - fn finish(self) -> fmt::Result { - self.err - } - } - - impl<'a> VisitFmt for DebugVisitor<'a> { - fn writer(&mut self) -> &mut dyn fmt::Write { - self.writer - } - } - - impl<'a> MakeVisitor<&'a mut dyn fmt::Write> for MakeDebug { - type Visitor = DebugVisitor<'a>; - fn make_visitor(&self, w: &'a mut dyn fmt::Write) -> DebugVisitor<'a> { - DebugVisitor::new(w) - } - } -} diff --git a/vendor/tracing-subscriber/src/filter/directive.rs b/vendor/tracing-subscriber/src/filter/directive.rs deleted file mode 100644 index 2ae3f0f24..000000000 --- a/vendor/tracing-subscriber/src/filter/directive.rs +++ /dev/null @@ -1,456 +0,0 @@ -use crate::filter::level::{self, LevelFilter}; -#[cfg(not(feature = "smallvec"))] -use alloc::vec; -#[cfg(not(feature = "std"))] -use alloc::{string::String, vec::Vec}; - -use core::{cmp::Ordering, fmt, iter::FromIterator, slice, str::FromStr}; -use tracing_core::{Level, Metadata}; -/// Indicates that a string could not be parsed as a filtering directive. -#[derive(Debug)] -pub struct ParseError { - kind: ParseErrorKind, -} - -/// A directive which will statically enable or disable a given callsite. -/// -/// Unlike a dynamic directive, this can be cached by the callsite. -#[derive(Debug, PartialEq, Eq, Clone)] -pub(crate) struct StaticDirective { - pub(in crate::filter) target: Option, - pub(in crate::filter) field_names: Vec, - pub(in crate::filter) level: LevelFilter, -} - -#[cfg(feature = "smallvec")] -pub(crate) type FilterVec = smallvec::SmallVec<[T; 8]>; -#[cfg(not(feature = "smallvec"))] -pub(crate) type FilterVec = Vec; - -#[derive(Debug, PartialEq, Clone)] -pub(in crate::filter) struct DirectiveSet { - directives: FilterVec, - pub(in crate::filter) max_level: LevelFilter, -} - -pub(in crate::filter) trait Match { - fn cares_about(&self, meta: &Metadata<'_>) -> bool; - fn level(&self) -> &LevelFilter; -} - -#[derive(Debug)] -enum ParseErrorKind { - #[cfg(feature = "std")] - Field(Box), - Level(level::ParseError), - Other(Option<&'static str>), -} - -// === impl DirectiveSet === - -impl DirectiveSet { - #[cfg(feature = "env-filter")] - pub(crate) fn is_empty(&self) -> bool { - self.directives.is_empty() - } - - pub(crate) fn iter(&self) -> slice::Iter<'_, T> { - self.directives.iter() - } -} - -impl Default for DirectiveSet { - fn default() -> Self { - Self { - directives: FilterVec::new(), - max_level: LevelFilter::OFF, - } - } -} - -impl DirectiveSet { - pub(crate) fn directives(&self) -> impl Iterator { - self.directives.iter() - } - - pub(crate) fn directives_for<'a>( - &'a self, - metadata: &'a Metadata<'a>, - ) -> impl Iterator + 'a { - self.directives().filter(move |d| d.cares_about(metadata)) - } - - pub(crate) fn add(&mut self, directive: T) { - // does this directive enable a more verbose level than the current - // max? if so, update the max level. - let level = *directive.level(); - if level > self.max_level { - self.max_level = level; - } - // insert the directive into the vec of directives, ordered by - // specificity (length of target + number of field filters). this - // ensures that, when finding a directive to match a span or event, we - // search the directive set in most specific first order. - match self.directives.binary_search(&directive) { - Ok(i) => self.directives[i] = directive, - Err(i) => self.directives.insert(i, directive), - } - } - - #[cfg(test)] - pub(in crate::filter) fn into_vec(self) -> FilterVec { - self.directives - } -} - -impl FromIterator for DirectiveSet { - fn from_iter>(iter: I) -> Self { - let mut this = Self::default(); - this.extend(iter); - this - } -} - -impl Extend for DirectiveSet { - fn extend>(&mut self, iter: I) { - for directive in iter.into_iter() { - self.add(directive); - } - } -} - -impl IntoIterator for DirectiveSet { - type Item = T; - - #[cfg(feature = "smallvec")] - type IntoIter = smallvec::IntoIter<[T; 8]>; - #[cfg(not(feature = "smallvec"))] - type IntoIter = vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.directives.into_iter() - } -} - -// === impl Statics === - -impl DirectiveSet { - pub(crate) fn enabled(&self, meta: &Metadata<'_>) -> bool { - let level = meta.level(); - match self.directives_for(meta).next() { - Some(d) => d.level >= *level, - None => false, - } - } - - /// Same as `enabled` above, but skips `Directive`'s with fields. - pub(crate) fn target_enabled(&self, target: &str, level: &Level) -> bool { - match self.directives_for_target(target).next() { - Some(d) => d.level >= *level, - None => false, - } - } - - pub(crate) fn directives_for_target<'a>( - &'a self, - target: &'a str, - ) -> impl Iterator + 'a { - self.directives() - .filter(move |d| d.cares_about_target(target)) - } -} - -// === impl StaticDirective === - -impl StaticDirective { - pub(in crate::filter) fn new( - target: Option, - field_names: Vec, - level: LevelFilter, - ) -> Self { - Self { - target, - field_names, - level, - } - } - - pub(in crate::filter) fn cares_about_target(&self, to_check: &str) -> bool { - // Does this directive have a target filter, and does it match the - // metadata's target? - if let Some(ref target) = self.target { - if !to_check.starts_with(&target[..]) { - return false; - } - } - - if !self.field_names.is_empty() { - return false; - } - - true - } -} - -impl Ord for StaticDirective { - fn cmp(&self, other: &StaticDirective) -> Ordering { - // We attempt to order directives by how "specific" they are. This - // ensures that we try the most specific directives first when - // attempting to match a piece of metadata. - - // First, we compare based on whether a target is specified, and the - // lengths of those targets if both have targets. - let ordering = self - .target - .as_ref() - .map(String::len) - .cmp(&other.target.as_ref().map(String::len)) - // Then we compare how many field names are matched by each directive. - .then_with(|| self.field_names.len().cmp(&other.field_names.len())) - // Finally, we fall back to lexicographical ordering if the directives are - // equally specific. Although this is no longer semantically important, - // we need to define a total ordering to determine the directive's place - // in the BTreeMap. - .then_with(|| { - self.target - .cmp(&other.target) - .then_with(|| self.field_names[..].cmp(&other.field_names[..])) - }) - .reverse(); - - #[cfg(debug_assertions)] - { - if ordering == Ordering::Equal { - debug_assert_eq!( - self.target, other.target, - "invariant violated: Ordering::Equal must imply a.target == b.target" - ); - debug_assert_eq!( - self.field_names, other.field_names, - "invariant violated: Ordering::Equal must imply a.field_names == b.field_names" - ); - } - } - - ordering - } -} - -impl PartialOrd for StaticDirective { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Match for StaticDirective { - fn cares_about(&self, meta: &Metadata<'_>) -> bool { - // Does this directive have a target filter, and does it match the - // metadata's target? - if let Some(ref target) = self.target { - if !meta.target().starts_with(&target[..]) { - return false; - } - } - - if meta.is_event() && !self.field_names.is_empty() { - let fields = meta.fields(); - for name in &self.field_names { - if fields.field(name).is_none() { - return false; - } - } - } - - true - } - - fn level(&self) -> &LevelFilter { - &self.level - } -} - -impl Default for StaticDirective { - fn default() -> Self { - StaticDirective { - target: None, - field_names: Vec::new(), - level: LevelFilter::ERROR, - } - } -} - -impl fmt::Display for StaticDirective { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut wrote_any = false; - if let Some(ref target) = self.target { - fmt::Display::fmt(target, f)?; - wrote_any = true; - } - - if !self.field_names.is_empty() { - f.write_str("[")?; - - let mut fields = self.field_names.iter(); - if let Some(field) = fields.next() { - write!(f, "{{{}", field)?; - for field in fields { - write!(f, ",{}", field)?; - } - f.write_str("}")?; - } - - f.write_str("]")?; - wrote_any = true; - } - - if wrote_any { - f.write_str("=")?; - } - - fmt::Display::fmt(&self.level, f) - } -} - -impl FromStr for StaticDirective { - type Err = ParseError; - - fn from_str(s: &str) -> Result { - // This method parses a filtering directive in one of the following - // forms: - // - // * `foo=trace` (TARGET=LEVEL) - // * `foo[{bar,baz}]=info` (TARGET[{FIELD,+}]=LEVEL) - // * `trace` (bare LEVEL) - // * `foo` (bare TARGET) - let mut split = s.split('='); - let part0 = split - .next() - .ok_or_else(|| ParseError::msg("string must not be empty"))?; - - // Directive includes an `=`: - // * `foo=trace` - // * `foo[{bar}]=trace` - // * `foo[{bar,baz}]=trace` - if let Some(part1) = split.next() { - if split.next().is_some() { - return Err(ParseError::msg( - "too many '=' in filter directive, expected 0 or 1", - )); - } - - let mut split = part0.split("[{"); - let target = split.next().map(String::from); - let mut field_names = Vec::new(); - // Directive includes fields: - // * `foo[{bar}]=trace` - // * `foo[{bar,baz}]=trace` - if let Some(maybe_fields) = split.next() { - if split.next().is_some() { - return Err(ParseError::msg( - "too many '[{' in filter directive, expected 0 or 1", - )); - } - - if !maybe_fields.ends_with("}]") { - return Err(ParseError::msg("expected fields list to end with '}]'")); - } - - let fields = maybe_fields - .trim_end_matches("}]") - .split(',') - .filter_map(|s| { - if s.is_empty() { - None - } else { - Some(String::from(s)) - } - }); - field_names.extend(fields); - }; - let level = part1.parse()?; - return Ok(Self { - level, - field_names, - target, - }); - } - - // Okay, the part after the `=` was empty, the directive is either a - // bare level or a bare target. - // * `foo` - // * `info` - Ok(match part0.parse::() { - Ok(level) => Self { - level, - target: None, - field_names: Vec::new(), - }, - Err(_) => Self { - target: Some(String::from(part0)), - level: LevelFilter::TRACE, - field_names: Vec::new(), - }, - }) - } -} - -// === impl ParseError === - -impl ParseError { - #[cfg(feature = "env-filter")] - pub(crate) fn new() -> Self { - ParseError { - kind: ParseErrorKind::Other(None), - } - } - - pub(crate) fn msg(s: &'static str) -> Self { - ParseError { - kind: ParseErrorKind::Other(Some(s)), - } - } -} - -impl fmt::Display for ParseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - ParseErrorKind::Other(None) => f.pad("invalid filter directive"), - ParseErrorKind::Other(Some(msg)) => write!(f, "invalid filter directive: {}", msg), - ParseErrorKind::Level(ref l) => l.fmt(f), - #[cfg(feature = "std")] - ParseErrorKind::Field(ref e) => write!(f, "invalid field filter: {}", e), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for ParseError { - fn description(&self) -> &str { - "invalid filter directive" - } - - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self.kind { - ParseErrorKind::Other(_) => None, - ParseErrorKind::Level(ref l) => Some(l), - ParseErrorKind::Field(ref n) => Some(n.as_ref()), - } - } -} - -#[cfg(feature = "std")] -impl From> for ParseError { - fn from(e: Box) -> Self { - Self { - kind: ParseErrorKind::Field(e), - } - } -} - -impl From for ParseError { - fn from(l: level::ParseError) -> Self { - Self { - kind: ParseErrorKind::Level(l), - } - } -} diff --git a/vendor/tracing-subscriber/src/filter/env/builder.rs b/vendor/tracing-subscriber/src/filter/env/builder.rs deleted file mode 100644 index 36b520543..000000000 --- a/vendor/tracing-subscriber/src/filter/env/builder.rs +++ /dev/null @@ -1,324 +0,0 @@ -use super::{ - directive::{self, Directive}, - EnvFilter, FromEnvError, -}; -use crate::sync::RwLock; -use std::env; -use thread_local::ThreadLocal; -use tracing::level_filters::STATIC_MAX_LEVEL; - -/// A [builder] for constructing new [`EnvFilter`]s. -/// -/// [builder]: https://rust-unofficial.github.io/patterns/patterns/creational/builder.html -#[derive(Debug, Clone)] -pub struct Builder { - regex: bool, - env: Option, - default_directive: Option, -} - -impl Builder { - /// Sets whether span field values can be matched with regular expressions. - /// - /// If this is `true`, field filter directives will be interpreted as - /// regular expressions if they are not able to be interpreted as a `bool`, - /// `i64`, `u64`, or `f64` literal. If this is `false,` those field values - /// will be interpreted as literal [`std::fmt::Debug`] output instead. - /// - /// By default, regular expressions are enabled. - /// - /// **Note**: when [`EnvFilter`]s are constructed from untrusted inputs, - /// disabling regular expressions is strongly encouraged. - pub fn with_regex(self, regex: bool) -> Self { - Self { regex, ..self } - } - - /// Sets a default [filtering directive] that will be added to the filter if - /// the parsed string or environment variable contains no filter directives. - /// - /// By default, there is no default directive. - /// - /// # Examples - /// - /// If [`parse`], [`parse_lossy`], [`from_env`], or [`from_env_lossy`] are - /// called with an empty string or environment variable, the default - /// directive is used instead: - /// - /// ```rust - /// # fn main() -> Result<(), Box> { - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// let filter = EnvFilter::builder() - /// .with_default_directive(LevelFilter::INFO.into()) - /// .parse("")?; - /// - /// assert_eq!(format!("{}", filter), "info"); - /// # Ok(()) } - /// ``` - /// - /// Note that the `lossy` variants ([`parse_lossy`] and [`from_env_lossy`]) - /// will ignore any invalid directives. If all directives in a filter - /// string or environment variable are invalid, those methods will also use - /// the default directive: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// let filter = EnvFilter::builder() - /// .with_default_directive(LevelFilter::INFO.into()) - /// .parse_lossy("some_target=fake level,foo::bar=lolwut"); - /// - /// assert_eq!(format!("{}", filter), "info"); - /// ``` - /// - /// - /// If the string or environment variable contains valid filtering - /// directives, the default directive is not used: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// let filter = EnvFilter::builder() - /// .with_default_directive(LevelFilter::INFO.into()) - /// .parse_lossy("foo=trace"); - /// - /// // The default directive is *not* used: - /// assert_eq!(format!("{}", filter), "foo=trace"); - /// ``` - /// - /// Parsing a more complex default directive from a string: - /// - /// ```rust - /// # fn main() -> Result<(), Box> { - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// let default = "myapp=debug".parse() - /// .expect("hard-coded default directive should be valid"); - /// - /// let filter = EnvFilter::builder() - /// .with_default_directive(default) - /// .parse("")?; - /// - /// assert_eq!(format!("{}", filter), "myapp=debug"); - /// # Ok(()) } - /// ``` - /// - /// [`parse_lossy`]: Self::parse_lossy - /// [`from_env_lossy`]: Self::from_env_lossy - /// [`parse`]: Self::parse - /// [`from_env`]: Self::from_env - pub fn with_default_directive(self, default_directive: Directive) -> Self { - Self { - default_directive: Some(default_directive), - ..self - } - } - - /// Sets the name of the environment variable used by the [`from_env`], - /// [`from_env_lossy`], and [`try_from_env`] methods. - /// - /// By default, this is the value of [`EnvFilter::DEFAULT_ENV`] - /// (`RUST_LOG`). - /// - /// [`from_env`]: Self::from_env - /// [`from_env_lossy`]: Self::from_env_lossy - /// [`try_from_env`]: Self::try_from_env - pub fn with_env_var(self, var: impl ToString) -> Self { - Self { - env: Some(var.to_string()), - ..self - } - } - - /// Returns a new [`EnvFilter`] from the directives in the given string, - /// *ignoring* any that are invalid. - pub fn parse_lossy>(&self, dirs: S) -> EnvFilter { - let directives = dirs - .as_ref() - .split(',') - .filter(|s| !s.is_empty()) - .filter_map(|s| match Directive::parse(s, self.regex) { - Ok(d) => Some(d), - Err(err) => { - eprintln!("ignoring `{}`: {}", s, err); - None - } - }); - self.from_directives(directives) - } - - /// Returns a new [`EnvFilter`] from the directives in the given string, - /// or an error if any are invalid. - pub fn parse>(&self, dirs: S) -> Result { - let dirs = dirs.as_ref(); - if dirs.is_empty() { - return Ok(self.from_directives(std::iter::empty())); - } - let directives = dirs - .split(',') - .filter(|s| !s.is_empty()) - .map(|s| Directive::parse(s, self.regex)) - .collect::, _>>()?; - Ok(self.from_directives(directives)) - } - - /// Returns a new [`EnvFilter`] from the directives in the configured - /// environment variable, ignoring any directives that are invalid. - pub fn from_env_lossy(&self) -> EnvFilter { - let var = env::var(self.env_var_name()).unwrap_or_default(); - self.parse_lossy(var) - } - - /// Returns a new [`EnvFilter`] from the directives in the in the configured - /// environment variable, or an error if the environment variable is not set - /// or contains invalid directives. - pub fn from_env(&self) -> Result { - let var = env::var(self.env_var_name()).unwrap_or_default(); - self.parse(var).map_err(Into::into) - } - - /// Returns a new [`EnvFilter`] from the directives in the in the configured - /// environment variable, or an error if the environment variable is not set - /// or contains invalid directives. - pub fn try_from_env(&self) -> Result { - let var = env::var(self.env_var_name())?; - self.parse(var).map_err(Into::into) - } - - // TODO(eliza): consider making this a public API? - // Clippy doesn't love this naming, because it suggests that `from_` methods - // should not take a `Self`...but in this case, it's the `EnvFilter` that is - // being constructed "from" the directives, rather than the builder itself. - #[allow(clippy::wrong_self_convention)] - pub(super) fn from_directives( - &self, - directives: impl IntoIterator, - ) -> EnvFilter { - use tracing::Level; - - let mut directives: Vec<_> = directives.into_iter().collect(); - let mut disabled = Vec::new(); - for directive in &mut directives { - if directive.level > STATIC_MAX_LEVEL { - disabled.push(directive.clone()); - } - if !self.regex { - directive.deregexify(); - } - } - - if !disabled.is_empty() { - #[cfg(feature = "ansi_term")] - use ansi_term::{Color, Style}; - // NOTE: We can't use a configured `MakeWriter` because the EnvFilter - // has no knowledge of any underlying subscriber or collector, which - // may or may not use a `MakeWriter`. - let warn = |msg: &str| { - #[cfg(not(feature = "ansi_term"))] - let msg = format!("warning: {}", msg); - #[cfg(feature = "ansi_term")] - let msg = { - let bold = Style::new().bold(); - let mut warning = Color::Yellow.paint("warning"); - warning.style_ref_mut().is_bold = true; - format!("{}{} {}", warning, bold.paint(":"), bold.paint(msg)) - }; - eprintln!("{}", msg); - }; - let ctx_prefixed = |prefix: &str, msg: &str| { - #[cfg(not(feature = "ansi_term"))] - let msg = format!("{} {}", prefix, msg); - #[cfg(feature = "ansi_term")] - let msg = { - let mut equal = Color::Fixed(21).paint("="); // dark blue - equal.style_ref_mut().is_bold = true; - format!(" {} {} {}", equal, Style::new().bold().paint(prefix), msg) - }; - eprintln!("{}", msg); - }; - let ctx_help = |msg| ctx_prefixed("help:", msg); - let ctx_note = |msg| ctx_prefixed("note:", msg); - let ctx = |msg: &str| { - #[cfg(not(feature = "ansi_term"))] - let msg = format!("note: {}", msg); - #[cfg(feature = "ansi_term")] - let msg = { - let mut pipe = Color::Fixed(21).paint("|"); - pipe.style_ref_mut().is_bold = true; - format!(" {} {}", pipe, msg) - }; - eprintln!("{}", msg); - }; - warn("some trace filter directives would enable traces that are disabled statically"); - for directive in disabled { - let target = if let Some(target) = &directive.target { - format!("the `{}` target", target) - } else { - "all targets".into() - }; - let level = directive - .level - .into_level() - .expect("=off would not have enabled any filters"); - ctx(&format!( - "`{}` would enable the {} level for {}", - directive, level, target - )); - } - ctx_note(&format!("the static max level is `{}`", STATIC_MAX_LEVEL)); - let help_msg = || { - let (feature, filter) = match STATIC_MAX_LEVEL.into_level() { - Some(Level::TRACE) => unreachable!( - "if the max level is trace, no static filtering features are enabled" - ), - Some(Level::DEBUG) => ("max_level_debug", Level::TRACE), - Some(Level::INFO) => ("max_level_info", Level::DEBUG), - Some(Level::WARN) => ("max_level_warn", Level::INFO), - Some(Level::ERROR) => ("max_level_error", Level::WARN), - None => return ("max_level_off", String::new()), - }; - (feature, format!("{} ", filter)) - }; - let (feature, earlier_level) = help_msg(); - ctx_help(&format!( - "to enable {}logging, remove the `{}` feature", - earlier_level, feature - )); - } - - let (dynamics, statics) = Directive::make_tables(directives); - let has_dynamics = !dynamics.is_empty(); - - let mut filter = EnvFilter { - statics, - dynamics, - has_dynamics, - by_id: RwLock::new(Default::default()), - by_cs: RwLock::new(Default::default()), - scope: ThreadLocal::new(), - regex: self.regex, - }; - - if !has_dynamics && filter.statics.is_empty() { - if let Some(ref default) = self.default_directive { - filter = filter.add_directive(default.clone()); - } - } - - filter - } - - fn env_var_name(&self) -> &str { - self.env.as_deref().unwrap_or(EnvFilter::DEFAULT_ENV) - } -} - -impl Default for Builder { - fn default() -> Self { - Self { - regex: true, - env: None, - default_directive: None, - } - } -} diff --git a/vendor/tracing-subscriber/src/filter/env/directive.rs b/vendor/tracing-subscriber/src/filter/env/directive.rs deleted file mode 100644 index f062e6ef9..000000000 --- a/vendor/tracing-subscriber/src/filter/env/directive.rs +++ /dev/null @@ -1,860 +0,0 @@ -pub(crate) use crate::filter::directive::{FilterVec, ParseError, StaticDirective}; -use crate::filter::{ - directive::{DirectiveSet, Match}, - env::{field, FieldMap}, - level::LevelFilter, -}; -use once_cell::sync::Lazy; -use regex::Regex; -use std::{cmp::Ordering, fmt, iter::FromIterator, str::FromStr}; -use tracing_core::{span, Level, Metadata}; - -/// A single filtering directive. -// TODO(eliza): add a builder for programmatically constructing directives? -#[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] -pub struct Directive { - in_span: Option, - fields: Vec, - pub(crate) target: Option, - pub(crate) level: LevelFilter, -} - -/// A set of dynamic filtering directives. -pub(super) type Dynamics = DirectiveSet; - -/// A set of static filtering directives. -pub(super) type Statics = DirectiveSet; - -pub(crate) type CallsiteMatcher = MatchSet; -pub(crate) type SpanMatcher = MatchSet; - -#[derive(Debug, PartialEq, Eq)] -pub(crate) struct MatchSet { - field_matches: FilterVec, - base_level: LevelFilter, -} - -impl Directive { - pub(super) fn has_name(&self) -> bool { - self.in_span.is_some() - } - - pub(super) fn has_fields(&self) -> bool { - !self.fields.is_empty() - } - - pub(super) fn to_static(&self) -> Option { - if !self.is_static() { - return None; - } - - // TODO(eliza): these strings are all immutable; we should consider - // `Arc`ing them to make this more efficient... - let field_names = self.fields.iter().map(field::Match::name).collect(); - - Some(StaticDirective::new( - self.target.clone(), - field_names, - self.level, - )) - } - - fn is_static(&self) -> bool { - !self.has_name() && !self.fields.iter().any(field::Match::has_value) - } - - pub(super) fn is_dynamic(&self) -> bool { - self.has_name() || self.has_fields() - } - - pub(crate) fn field_matcher(&self, meta: &Metadata<'_>) -> Option { - let fieldset = meta.fields(); - let fields = self - .fields - .iter() - .filter_map( - |field::Match { - ref name, - ref value, - }| { - if let Some(field) = fieldset.field(name) { - let value = value.as_ref().cloned()?; - Some(Ok((field, value))) - } else { - Some(Err(())) - } - }, - ) - .collect::, ()>>() - .ok()?; - Some(field::CallsiteMatch { - fields, - level: self.level, - }) - } - - pub(super) fn make_tables( - directives: impl IntoIterator, - ) -> (Dynamics, Statics) { - // TODO(eliza): this could be made more efficient... - let (dyns, stats): (Vec, Vec) = - directives.into_iter().partition(Directive::is_dynamic); - let statics = stats - .into_iter() - .filter_map(|d| d.to_static()) - .chain(dyns.iter().filter_map(Directive::to_static)) - .collect(); - (Dynamics::from_iter(dyns), statics) - } - - pub(super) fn deregexify(&mut self) { - for field in &mut self.fields { - field.value = match field.value.take() { - Some(field::ValueMatch::Pat(pat)) => { - Some(field::ValueMatch::Debug(pat.into_debug_match())) - } - x => x, - } - } - } - - pub(super) fn parse(from: &str, regex: bool) -> Result { - static DIRECTIVE_RE: Lazy = Lazy::new(|| Regex::new( - r"(?x) - ^(?P(?i:trace|debug|info|warn|error|off|[0-5]))$ | - # ^^^. - # `note: we match log level names case-insensitively - ^ - (?: # target name or span name - (?P[\w:-]+)|(?P\[[^\]]*\]) - ){1,2} - (?: # level or nothing - =(?P(?i:trace|debug|info|warn|error|off|[0-5]))? - # ^^^. - # `note: we match log level names case-insensitively - )? - $ - " - ) - .unwrap()); - static SPAN_PART_RE: Lazy = - Lazy::new(|| Regex::new(r#"(?P[^\]\{]+)?(?:\{(?P[^\}]*)\})?"#).unwrap()); - static FIELD_FILTER_RE: Lazy = - // TODO(eliza): this doesn't _currently_ handle value matchers that include comma - // characters. We should fix that. - Lazy::new(|| Regex::new(r#"(?x) - ( - # field name - [[:word:]][[[:word:]]\.]* - # value part (optional) - (?:=[^,]+)? - ) - # trailing comma or EOS - (?:,\s?|$) - "#).unwrap()); - - let caps = DIRECTIVE_RE.captures(from).ok_or_else(ParseError::new)?; - - if let Some(level) = caps - .name("global_level") - .and_then(|s| s.as_str().parse().ok()) - { - return Ok(Directive { - level, - ..Default::default() - }); - } - - let target = caps.name("target").and_then(|c| { - let s = c.as_str(); - if s.parse::().is_ok() { - None - } else { - Some(s.to_owned()) - } - }); - - let (in_span, fields) = caps - .name("span") - .and_then(|cap| { - let cap = cap.as_str().trim_matches(|c| c == '[' || c == ']'); - let caps = SPAN_PART_RE.captures(cap)?; - let span = caps.name("name").map(|c| c.as_str().to_owned()); - let fields = caps - .name("fields") - .map(|c| { - FIELD_FILTER_RE - .find_iter(c.as_str()) - .map(|c| field::Match::parse(c.as_str(), regex)) - .collect::, _>>() - }) - .unwrap_or_else(|| Ok(Vec::new())); - Some((span, fields)) - }) - .unwrap_or_else(|| (None, Ok(Vec::new()))); - - let level = caps - .name("level") - .and_then(|l| l.as_str().parse().ok()) - // Setting the target without the level enables every level for that target - .unwrap_or(LevelFilter::TRACE); - - Ok(Self { - level, - target, - in_span, - fields: fields?, - }) - } -} - -impl Match for Directive { - fn cares_about(&self, meta: &Metadata<'_>) -> bool { - // Does this directive have a target filter, and does it match the - // metadata's target? - if let Some(ref target) = self.target { - if !meta.target().starts_with(&target[..]) { - return false; - } - } - - // Do we have a name filter, and does it match the metadata's name? - // TODO(eliza): put name globbing here? - if let Some(ref name) = self.in_span { - if name != meta.name() { - return false; - } - } - - // Does the metadata define all the fields that this directive cares about? - let actual_fields = meta.fields(); - for expected_field in &self.fields { - // Does the actual field set (from the metadata) contain this field? - if actual_fields.field(&expected_field.name).is_none() { - return false; - } - } - - true - } - - fn level(&self) -> &LevelFilter { - &self.level - } -} - -impl FromStr for Directive { - type Err = ParseError; - fn from_str(from: &str) -> Result { - Directive::parse(from, true) - } -} - -impl Default for Directive { - fn default() -> Self { - Directive { - level: LevelFilter::OFF, - target: None, - in_span: None, - fields: Vec::new(), - } - } -} - -impl PartialOrd for Directive { - fn partial_cmp(&self, other: &Directive) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Directive { - fn cmp(&self, other: &Directive) -> Ordering { - // We attempt to order directives by how "specific" they are. This - // ensures that we try the most specific directives first when - // attempting to match a piece of metadata. - - // First, we compare based on whether a target is specified, and the - // lengths of those targets if both have targets. - let ordering = self - .target - .as_ref() - .map(String::len) - .cmp(&other.target.as_ref().map(String::len)) - // Next compare based on the presence of span names. - .then_with(|| self.in_span.is_some().cmp(&other.in_span.is_some())) - // Then we compare how many fields are defined by each - // directive. - .then_with(|| self.fields.len().cmp(&other.fields.len())) - // Finally, we fall back to lexicographical ordering if the directives are - // equally specific. Although this is no longer semantically important, - // we need to define a total ordering to determine the directive's place - // in the BTreeMap. - .then_with(|| { - self.target - .cmp(&other.target) - .then_with(|| self.in_span.cmp(&other.in_span)) - .then_with(|| self.fields[..].cmp(&other.fields[..])) - }) - .reverse(); - - #[cfg(debug_assertions)] - { - if ordering == Ordering::Equal { - debug_assert_eq!( - self.target, other.target, - "invariant violated: Ordering::Equal must imply a.target == b.target" - ); - debug_assert_eq!( - self.in_span, other.in_span, - "invariant violated: Ordering::Equal must imply a.in_span == b.in_span" - ); - debug_assert_eq!( - self.fields, other.fields, - "invariant violated: Ordering::Equal must imply a.fields == b.fields" - ); - } - } - - ordering - } -} - -impl fmt::Display for Directive { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut wrote_any = false; - if let Some(ref target) = self.target { - fmt::Display::fmt(target, f)?; - wrote_any = true; - } - - if self.in_span.is_some() || !self.fields.is_empty() { - f.write_str("[")?; - - if let Some(ref span) = self.in_span { - fmt::Display::fmt(span, f)?; - } - - let mut fields = self.fields.iter(); - if let Some(field) = fields.next() { - write!(f, "{{{}", field)?; - for field in fields { - write!(f, ",{}", field)?; - } - f.write_str("}")?; - } - - f.write_str("]")?; - wrote_any = true; - } - - if wrote_any { - f.write_str("=")?; - } - - fmt::Display::fmt(&self.level, f) - } -} - -impl From for Directive { - fn from(level: LevelFilter) -> Self { - Self { - level, - ..Self::default() - } - } -} - -impl From for Directive { - fn from(level: Level) -> Self { - LevelFilter::from_level(level).into() - } -} - -// === impl Dynamics === - -impl Dynamics { - pub(crate) fn matcher(&self, metadata: &Metadata<'_>) -> Option { - let mut base_level = None; - let field_matches = self - .directives_for(metadata) - .filter_map(|d| { - if let Some(f) = d.field_matcher(metadata) { - return Some(f); - } - match base_level { - Some(ref b) if d.level > *b => base_level = Some(d.level), - None => base_level = Some(d.level), - _ => {} - } - None - }) - .collect(); - - if let Some(base_level) = base_level { - Some(CallsiteMatcher { - field_matches, - base_level, - }) - } else if !field_matches.is_empty() { - Some(CallsiteMatcher { - field_matches, - base_level: base_level.unwrap_or(LevelFilter::OFF), - }) - } else { - None - } - } - - pub(crate) fn has_value_filters(&self) -> bool { - self.directives() - .any(|d| d.fields.iter().any(|f| f.value.is_some())) - } -} - -// ===== impl DynamicMatch ===== - -impl CallsiteMatcher { - /// Create a new `SpanMatch` for a given instance of the matched callsite. - pub(crate) fn to_span_match(&self, attrs: &span::Attributes<'_>) -> SpanMatcher { - let field_matches = self - .field_matches - .iter() - .map(|m| { - let m = m.to_span_match(); - attrs.record(&mut m.visitor()); - m - }) - .collect(); - SpanMatcher { - field_matches, - base_level: self.base_level, - } - } -} - -impl SpanMatcher { - /// Returns the level currently enabled for this callsite. - pub(crate) fn level(&self) -> LevelFilter { - self.field_matches - .iter() - .filter_map(field::SpanMatch::filter) - .max() - .unwrap_or(self.base_level) - } - - pub(crate) fn record_update(&self, record: &span::Record<'_>) { - for m in &self.field_matches { - record.record(&mut m.visitor()) - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - fn parse_directives(dirs: impl AsRef) -> Vec { - dirs.as_ref() - .split(',') - .filter_map(|s| s.parse().ok()) - .collect() - } - - fn expect_parse(dirs: impl AsRef) -> Vec { - dirs.as_ref() - .split(',') - .map(|s| { - s.parse() - .unwrap_or_else(|err| panic!("directive '{:?}' should parse: {}", s, err)) - }) - .collect() - } - - #[test] - fn directive_ordering_by_target_len() { - // TODO(eliza): it would be nice to have a property-based test for this - // instead. - let mut dirs = expect_parse( - "foo::bar=debug,foo::bar::baz=trace,foo=info,a_really_long_name_with_no_colons=warn", - ); - dirs.sort_unstable(); - - let expected = vec![ - "a_really_long_name_with_no_colons", - "foo::bar::baz", - "foo::bar", - "foo", - ]; - let sorted = dirs - .iter() - .map(|d| d.target.as_ref().unwrap()) - .collect::>(); - - assert_eq!(expected, sorted); - } - #[test] - fn directive_ordering_by_span() { - // TODO(eliza): it would be nice to have a property-based test for this - // instead. - let mut dirs = expect_parse("bar[span]=trace,foo=debug,baz::quux=info,a[span]=warn"); - dirs.sort_unstable(); - - let expected = vec!["baz::quux", "bar", "foo", "a"]; - let sorted = dirs - .iter() - .map(|d| d.target.as_ref().unwrap()) - .collect::>(); - - assert_eq!(expected, sorted); - } - - #[test] - fn directive_ordering_uses_lexicographic_when_equal() { - // TODO(eliza): it would be nice to have a property-based test for this - // instead. - let mut dirs = expect_parse("span[b]=debug,b=debug,a=trace,c=info,span[a]=info"); - dirs.sort_unstable(); - - let expected = vec![ - ("span", Some("b")), - ("span", Some("a")), - ("c", None), - ("b", None), - ("a", None), - ]; - let sorted = dirs - .iter() - .map(|d| { - ( - d.target.as_ref().unwrap().as_ref(), - d.in_span.as_ref().map(String::as_ref), - ) - }) - .collect::>(); - - assert_eq!(expected, sorted); - } - - // TODO: this test requires the parser to support directives with multiple - // fields, which it currently can't handle. We should enable this test when - // that's implemented. - #[test] - #[ignore] - fn directive_ordering_by_field_num() { - // TODO(eliza): it would be nice to have a property-based test for this - // instead. - let mut dirs = expect_parse( - "b[{foo,bar}]=info,c[{baz,quuux,quuux}]=debug,a[{foo}]=warn,bar[{field}]=trace,foo=debug,baz::quux=info" - ); - dirs.sort_unstable(); - - let expected = vec!["baz::quux", "bar", "foo", "c", "b", "a"]; - let sorted = dirs - .iter() - .map(|d| d.target.as_ref().unwrap()) - .collect::>(); - - assert_eq!(expected, sorted); - } - - #[test] - fn parse_directives_ralith() { - let dirs = parse_directives("common=trace,server=trace"); - assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("common".to_string())); - assert_eq!(dirs[0].level, LevelFilter::TRACE); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("server".to_string())); - assert_eq!(dirs[1].level, LevelFilter::TRACE); - assert_eq!(dirs[1].in_span, None); - } - - #[test] - fn parse_directives_ralith_uc() { - let dirs = parse_directives("common=INFO,server=DEBUG"); - assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("common".to_string())); - assert_eq!(dirs[0].level, LevelFilter::INFO); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("server".to_string())); - assert_eq!(dirs[1].level, LevelFilter::DEBUG); - assert_eq!(dirs[1].in_span, None); - } - - #[test] - fn parse_directives_ralith_mixed() { - let dirs = parse_directives("common=iNfo,server=dEbUg"); - assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("common".to_string())); - assert_eq!(dirs[0].level, LevelFilter::INFO); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("server".to_string())); - assert_eq!(dirs[1].level, LevelFilter::DEBUG); - assert_eq!(dirs[1].in_span, None); - } - - #[test] - fn parse_directives_valid() { - let dirs = parse_directives("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off"); - assert_eq!(dirs.len(), 4, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::ERROR); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::TRACE); - assert_eq!(dirs[1].in_span, None); - - assert_eq!(dirs[2].target, Some("crate2".to_string())); - assert_eq!(dirs[2].level, LevelFilter::DEBUG); - assert_eq!(dirs[2].in_span, None); - - assert_eq!(dirs[3].target, Some("crate3".to_string())); - assert_eq!(dirs[3].level, LevelFilter::OFF); - assert_eq!(dirs[3].in_span, None); - } - - #[test] - - fn parse_level_directives() { - let dirs = parse_directives( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off", - ); - assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::ERROR); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::WARN); - assert_eq!(dirs[1].in_span, None); - - assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string())); - assert_eq!(dirs[2].level, LevelFilter::INFO); - assert_eq!(dirs[2].in_span, None); - - assert_eq!(dirs[3].target, Some("crate2".to_string())); - assert_eq!(dirs[3].level, LevelFilter::DEBUG); - assert_eq!(dirs[3].in_span, None); - - assert_eq!(dirs[4].target, Some("crate3".to_string())); - assert_eq!(dirs[4].level, LevelFilter::TRACE); - assert_eq!(dirs[4].in_span, None); - - assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string())); - assert_eq!(dirs[5].level, LevelFilter::OFF); - assert_eq!(dirs[5].in_span, None); - } - - #[test] - fn parse_uppercase_level_directives() { - let dirs = parse_directives( - "crate1::mod1=ERROR,crate1::mod2=WARN,crate1::mod2::mod3=INFO,\ - crate2=DEBUG,crate3=TRACE,crate3::mod2::mod1=OFF", - ); - assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::ERROR); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::WARN); - assert_eq!(dirs[1].in_span, None); - - assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string())); - assert_eq!(dirs[2].level, LevelFilter::INFO); - assert_eq!(dirs[2].in_span, None); - - assert_eq!(dirs[3].target, Some("crate2".to_string())); - assert_eq!(dirs[3].level, LevelFilter::DEBUG); - assert_eq!(dirs[3].in_span, None); - - assert_eq!(dirs[4].target, Some("crate3".to_string())); - assert_eq!(dirs[4].level, LevelFilter::TRACE); - assert_eq!(dirs[4].in_span, None); - - assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string())); - assert_eq!(dirs[5].level, LevelFilter::OFF); - assert_eq!(dirs[5].in_span, None); - } - - #[test] - fn parse_numeric_level_directives() { - let dirs = parse_directives( - "crate1::mod1=1,crate1::mod2=2,crate1::mod2::mod3=3,crate2=4,\ - crate3=5,crate3::mod2::mod1=0", - ); - assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::ERROR); - assert_eq!(dirs[0].in_span, None); - - assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::WARN); - assert_eq!(dirs[1].in_span, None); - - assert_eq!(dirs[2].target, Some("crate1::mod2::mod3".to_string())); - assert_eq!(dirs[2].level, LevelFilter::INFO); - assert_eq!(dirs[2].in_span, None); - - assert_eq!(dirs[3].target, Some("crate2".to_string())); - assert_eq!(dirs[3].level, LevelFilter::DEBUG); - assert_eq!(dirs[3].in_span, None); - - assert_eq!(dirs[4].target, Some("crate3".to_string())); - assert_eq!(dirs[4].level, LevelFilter::TRACE); - assert_eq!(dirs[4].in_span, None); - - assert_eq!(dirs[5].target, Some("crate3::mod2::mod1".to_string())); - assert_eq!(dirs[5].level, LevelFilter::OFF); - assert_eq!(dirs[5].in_span, None); - } - - #[test] - fn parse_directives_invalid_crate() { - // test parse_directives with multiple = in specification - let dirs = parse_directives("crate1::mod1=warn=info,crate2=debug"); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::DEBUG); - assert_eq!(dirs[0].in_span, None); - } - - #[test] - fn parse_directives_invalid_level() { - // test parse_directives with 'noNumber' as log level - let dirs = parse_directives("crate1::mod1=noNumber,crate2=debug"); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::DEBUG); - assert_eq!(dirs[0].in_span, None); - } - - #[test] - fn parse_directives_string_level() { - // test parse_directives with 'warn' as log level - let dirs = parse_directives("crate1::mod1=wrong,crate2=warn"); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::WARN); - assert_eq!(dirs[0].in_span, None); - } - - #[test] - fn parse_directives_empty_level() { - // test parse_directives with '' as log level - let dirs = parse_directives("crate1::mod1=wrong,crate2="); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::TRACE); - assert_eq!(dirs[0].in_span, None); - } - - #[test] - fn parse_directives_global() { - // test parse_directives with no crate - let dirs = parse_directives("warn,crate2=debug"); - assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, None); - assert_eq!(dirs[0].level, LevelFilter::WARN); - assert_eq!(dirs[1].in_span, None); - - assert_eq!(dirs[1].target, Some("crate2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::DEBUG); - assert_eq!(dirs[1].in_span, None); - } - - // helper function for tests below - fn test_parse_bare_level(directive_to_test: &str, level_expected: LevelFilter) { - let dirs = parse_directives(directive_to_test); - assert_eq!( - dirs.len(), - 1, - "\ninput: \"{}\"; parsed: {:#?}", - directive_to_test, - dirs - ); - assert_eq!(dirs[0].target, None); - assert_eq!(dirs[0].level, level_expected); - assert_eq!(dirs[0].in_span, None); - } - - #[test] - fn parse_directives_global_bare_warn_lc() { - // test parse_directives with no crate, in isolation, all lowercase - test_parse_bare_level("warn", LevelFilter::WARN); - } - - #[test] - fn parse_directives_global_bare_warn_uc() { - // test parse_directives with no crate, in isolation, all uppercase - test_parse_bare_level("WARN", LevelFilter::WARN); - } - - #[test] - fn parse_directives_global_bare_warn_mixed() { - // test parse_directives with no crate, in isolation, mixed case - test_parse_bare_level("wArN", LevelFilter::WARN); - } - - #[test] - fn parse_directives_valid_with_spans() { - let dirs = parse_directives("crate1::mod1[foo]=error,crate1::mod2[bar],crate2[baz]=debug"); - assert_eq!(dirs.len(), 3, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::ERROR); - assert_eq!(dirs[0].in_span, Some("foo".to_string())); - - assert_eq!(dirs[1].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::TRACE); - assert_eq!(dirs[1].in_span, Some("bar".to_string())); - - assert_eq!(dirs[2].target, Some("crate2".to_string())); - assert_eq!(dirs[2].level, LevelFilter::DEBUG); - assert_eq!(dirs[2].in_span, Some("baz".to_string())); - } - - #[test] - fn parse_directives_with_dash_in_target_name() { - let dirs = parse_directives("target-name=info"); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("target-name".to_string())); - assert_eq!(dirs[0].level, LevelFilter::INFO); - assert_eq!(dirs[0].in_span, None); - } - - #[test] - fn parse_directives_with_dash_in_span_name() { - // Reproduces https://github.com/tokio-rs/tracing/issues/1367 - - let dirs = parse_directives("target[span-name]=info"); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("target".to_string())); - assert_eq!(dirs[0].level, LevelFilter::INFO); - assert_eq!(dirs[0].in_span, Some("span-name".to_string())); - } - - #[test] - fn parse_directives_with_special_characters_in_span_name() { - let span_name = "!\"#$%&'()*+-./:;<=>?@^_`|~[}"; - - let dirs = parse_directives(format!("target[{}]=info", span_name)); - assert_eq!(dirs.len(), 1, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("target".to_string())); - assert_eq!(dirs[0].level, LevelFilter::INFO); - assert_eq!(dirs[0].in_span, Some(span_name.to_string())); - } - - #[test] - fn parse_directives_with_invalid_span_chars() { - let invalid_span_name = "]{"; - - let dirs = parse_directives(format!("target[{}]=info", invalid_span_name)); - assert_eq!(dirs.len(), 0, "\nparsed: {:#?}", dirs); - } -} diff --git a/vendor/tracing-subscriber/src/filter/env/field.rs b/vendor/tracing-subscriber/src/filter/env/field.rs deleted file mode 100644 index 1394fd04a..000000000 --- a/vendor/tracing-subscriber/src/filter/env/field.rs +++ /dev/null @@ -1,626 +0,0 @@ -use matchers::Pattern; -use std::{ - cmp::Ordering, - error::Error, - fmt::{self, Write}, - str::FromStr, - sync::{ - atomic::{AtomicBool, Ordering::*}, - Arc, - }, -}; - -use super::{FieldMap, LevelFilter}; -use tracing_core::field::{Field, Visit}; - -#[derive(Clone, Debug, Eq, PartialEq)] -pub(crate) struct Match { - pub(crate) name: String, // TODO: allow match patterns for names? - pub(crate) value: Option, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) struct CallsiteMatch { - pub(crate) fields: FieldMap, - pub(crate) level: LevelFilter, -} - -#[derive(Debug)] -pub(crate) struct SpanMatch { - fields: FieldMap<(ValueMatch, AtomicBool)>, - level: LevelFilter, - has_matched: AtomicBool, -} - -pub(crate) struct MatchVisitor<'a> { - inner: &'a SpanMatch, -} - -#[derive(Debug, Clone)] -pub(crate) enum ValueMatch { - /// Matches a specific `bool` value. - Bool(bool), - /// Matches a specific `f64` value. - F64(f64), - /// Matches a specific `u64` value. - U64(u64), - /// Matches a specific `i64` value. - I64(i64), - /// Matches any `NaN` `f64` value. - NaN, - /// Matches any field whose `fmt::Debug` output is equal to a fixed string. - Debug(MatchDebug), - /// Matches any field whose `fmt::Debug` output matches a regular expression - /// pattern. - Pat(Box), -} - -impl Eq for ValueMatch {} - -impl PartialEq for ValueMatch { - fn eq(&self, other: &Self) -> bool { - use ValueMatch::*; - match (self, other) { - (Bool(a), Bool(b)) => a.eq(b), - (F64(a), F64(b)) => { - debug_assert!(!a.is_nan()); - debug_assert!(!b.is_nan()); - - a.eq(b) - } - (U64(a), U64(b)) => a.eq(b), - (I64(a), I64(b)) => a.eq(b), - (NaN, NaN) => true, - (Pat(a), Pat(b)) => a.eq(b), - _ => false, - } - } -} - -impl Ord for ValueMatch { - fn cmp(&self, other: &Self) -> Ordering { - use ValueMatch::*; - match (self, other) { - (Bool(this), Bool(that)) => this.cmp(that), - (Bool(_), _) => Ordering::Less, - - (F64(this), F64(that)) => this - .partial_cmp(that) - .expect("`ValueMatch::F64` may not contain `NaN` values"), - (F64(_), Bool(_)) => Ordering::Greater, - (F64(_), _) => Ordering::Less, - - (NaN, NaN) => Ordering::Equal, - (NaN, Bool(_)) | (NaN, F64(_)) => Ordering::Greater, - (NaN, _) => Ordering::Less, - - (U64(this), U64(that)) => this.cmp(that), - (U64(_), Bool(_)) | (U64(_), F64(_)) | (U64(_), NaN) => Ordering::Greater, - (U64(_), _) => Ordering::Less, - - (I64(this), I64(that)) => this.cmp(that), - (I64(_), Bool(_)) | (I64(_), F64(_)) | (I64(_), NaN) | (I64(_), U64(_)) => { - Ordering::Greater - } - (I64(_), _) => Ordering::Less, - - (Pat(this), Pat(that)) => this.cmp(that), - (Pat(_), _) => Ordering::Greater, - - (Debug(this), Debug(that)) => this.cmp(that), - (Debug(_), _) => Ordering::Greater, - } - } -} - -impl PartialOrd for ValueMatch { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -/// Matches a field's `fmt::Debug` output against a regular expression pattern. -/// -/// This is used for matching all non-literal field value filters when regular -/// expressions are enabled. -#[derive(Debug, Clone)] -pub(crate) struct MatchPattern { - pub(crate) matcher: Pattern, - pattern: Arc, -} - -/// Matches a field's `fmt::Debug` output against a fixed string pattern. -/// -/// This is used for matching all non-literal field value filters when regular -/// expressions are disabled. -#[derive(Debug, Clone)] -pub(crate) struct MatchDebug { - pattern: Arc, -} - -/// Indicates that a field name specified in a filter directive was invalid. -#[derive(Clone, Debug)] -#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] -pub struct BadName { - name: String, -} - -// === impl Match === - -impl Match { - pub(crate) fn has_value(&self) -> bool { - self.value.is_some() - } - - // TODO: reference count these strings? - pub(crate) fn name(&self) -> String { - self.name.clone() - } - - pub(crate) fn parse(s: &str, regex: bool) -> Result> { - let mut parts = s.split('='); - let name = parts - .next() - .ok_or_else(|| BadName { - name: "".to_string(), - })? - // TODO: validate field name - .to_string(); - let value = parts - .next() - .map(|part| match regex { - true => ValueMatch::parse_regex(part), - false => Ok(ValueMatch::parse_non_regex(part)), - }) - .transpose()?; - Ok(Match { name, value }) - } -} - -impl fmt::Display for Match { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.name, f)?; - if let Some(ref value) = self.value { - write!(f, "={}", value)?; - } - Ok(()) - } -} - -impl Ord for Match { - fn cmp(&self, other: &Self) -> Ordering { - // Ordering for `Match` directives is based first on _whether_ a value - // is matched or not. This is semantically meaningful --- we would - // prefer to check directives that match values first as they are more - // specific. - let has_value = match (self.value.as_ref(), other.value.as_ref()) { - (Some(_), None) => Ordering::Greater, - (None, Some(_)) => Ordering::Less, - _ => Ordering::Equal, - }; - // If both directives match a value, we fall back to the field names in - // length + lexicographic ordering, and if these are equal as well, we - // compare the match directives. - // - // This ordering is no longer semantically meaningful but is necessary - // so that the directives can be stored in the `BTreeMap` in a defined - // order. - has_value - .then_with(|| self.name.cmp(&other.name)) - .then_with(|| self.value.cmp(&other.value)) - } -} - -impl PartialOrd for Match { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -// === impl ValueMatch === - -fn value_match_f64(v: f64) -> ValueMatch { - if v.is_nan() { - ValueMatch::NaN - } else { - ValueMatch::F64(v) - } -} - -impl ValueMatch { - /// Parse a `ValueMatch` that will match `fmt::Debug` fields using regular - /// expressions. - /// - /// This returns an error if the string didn't contain a valid `bool`, - /// `u64`, `i64`, or `f64` literal, and couldn't be parsed as a regular - /// expression. - fn parse_regex(s: &str) -> Result { - s.parse::() - .map(ValueMatch::Bool) - .or_else(|_| s.parse::().map(ValueMatch::U64)) - .or_else(|_| s.parse::().map(ValueMatch::I64)) - .or_else(|_| s.parse::().map(value_match_f64)) - .or_else(|_| { - s.parse::() - .map(|p| ValueMatch::Pat(Box::new(p))) - }) - } - - /// Parse a `ValueMatch` that will match `fmt::Debug` against a fixed - /// string. - /// - /// This does *not* return an error, because any string that isn't a valid - /// `bool`, `u64`, `i64`, or `f64` literal is treated as expected - /// `fmt::Debug` output. - fn parse_non_regex(s: &str) -> Self { - s.parse::() - .map(ValueMatch::Bool) - .or_else(|_| s.parse::().map(ValueMatch::U64)) - .or_else(|_| s.parse::().map(ValueMatch::I64)) - .or_else(|_| s.parse::().map(value_match_f64)) - .unwrap_or_else(|_| ValueMatch::Debug(MatchDebug::new(s))) - } -} - -impl fmt::Display for ValueMatch { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ValueMatch::Bool(ref inner) => fmt::Display::fmt(inner, f), - ValueMatch::F64(ref inner) => fmt::Display::fmt(inner, f), - ValueMatch::NaN => fmt::Display::fmt(&std::f64::NAN, f), - ValueMatch::I64(ref inner) => fmt::Display::fmt(inner, f), - ValueMatch::U64(ref inner) => fmt::Display::fmt(inner, f), - ValueMatch::Debug(ref inner) => fmt::Display::fmt(inner, f), - ValueMatch::Pat(ref inner) => fmt::Display::fmt(inner, f), - } - } -} - -// === impl MatchPattern === - -impl FromStr for MatchPattern { - type Err = matchers::Error; - fn from_str(s: &str) -> Result { - let matcher = s.parse::()?; - Ok(Self { - matcher, - pattern: s.to_owned().into(), - }) - } -} - -impl fmt::Display for MatchPattern { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&*self.pattern, f) - } -} - -impl AsRef for MatchPattern { - #[inline] - fn as_ref(&self) -> &str { - self.pattern.as_ref() - } -} - -impl MatchPattern { - #[inline] - fn str_matches(&self, s: &impl AsRef) -> bool { - self.matcher.matches(s) - } - - #[inline] - fn debug_matches(&self, d: &impl fmt::Debug) -> bool { - self.matcher.debug_matches(d) - } - - pub(super) fn into_debug_match(self) -> MatchDebug { - MatchDebug { - pattern: self.pattern, - } - } -} - -impl PartialEq for MatchPattern { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.pattern == other.pattern - } -} - -impl Eq for MatchPattern {} - -impl PartialOrd for MatchPattern { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.pattern.cmp(&other.pattern)) - } -} - -impl Ord for MatchPattern { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - self.pattern.cmp(&other.pattern) - } -} - -// === impl MatchDebug === - -impl MatchDebug { - fn new(s: &str) -> Self { - Self { - pattern: s.to_owned().into(), - } - } - - #[inline] - fn debug_matches(&self, d: &impl fmt::Debug) -> bool { - // Naively, we would probably match a value's `fmt::Debug` output by - // formatting it to a string, and then checking if the string is equal - // to the expected pattern. However, this would require allocating every - // time we want to match a field value against a `Debug` matcher, which - // can be avoided. - // - // Instead, we implement `fmt::Write` for a type that, rather than - // actually _writing_ the strings to something, matches them against the - // expected pattern, and returns an error if the pattern does not match. - struct Matcher<'a> { - pattern: &'a str, - } - - impl fmt::Write for Matcher<'_> { - fn write_str(&mut self, s: &str) -> fmt::Result { - // If the string is longer than the remaining expected string, - // we know it won't match, so bail. - if s.len() > self.pattern.len() { - return Err(fmt::Error); - } - - // If the expected string begins with the string that was - // written, we are still potentially a match. Advance the - // position in the expected pattern to chop off the matched - // output, and continue. - if self.pattern.starts_with(s) { - self.pattern = &self.pattern[s.len()..]; - return Ok(()); - } - - // Otherwise, the expected string doesn't include the string - // that was written at the current position, so the `fmt::Debug` - // output doesn't match! Return an error signalling that this - // doesn't match. - Err(fmt::Error) - } - } - let mut matcher = Matcher { - pattern: &self.pattern, - }; - - // Try to "write" the value's `fmt::Debug` output to a `Matcher`. This - // returns an error if the `fmt::Debug` implementation wrote any - // characters that did not match the expected pattern. - write!(matcher, "{:?}", d).is_ok() - } -} - -impl fmt::Display for MatchDebug { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&*self.pattern, f) - } -} - -impl AsRef for MatchDebug { - #[inline] - fn as_ref(&self) -> &str { - self.pattern.as_ref() - } -} - -impl PartialEq for MatchDebug { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.pattern == other.pattern - } -} - -impl Eq for MatchDebug {} - -impl PartialOrd for MatchDebug { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.pattern.cmp(&other.pattern)) - } -} - -impl Ord for MatchDebug { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - self.pattern.cmp(&other.pattern) - } -} - -// === impl BadName === - -impl Error for BadName {} - -impl fmt::Display for BadName { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "invalid field name `{}`", self.name) - } -} - -impl CallsiteMatch { - pub(crate) fn to_span_match(&self) -> SpanMatch { - let fields = self - .fields - .iter() - .map(|(k, v)| (k.clone(), (v.clone(), AtomicBool::new(false)))) - .collect(); - SpanMatch { - fields, - level: self.level, - has_matched: AtomicBool::new(false), - } - } -} - -impl SpanMatch { - pub(crate) fn visitor(&self) -> MatchVisitor<'_> { - MatchVisitor { inner: self } - } - - #[inline] - pub(crate) fn is_matched(&self) -> bool { - if self.has_matched.load(Acquire) { - return true; - } - self.is_matched_slow() - } - - #[inline(never)] - fn is_matched_slow(&self) -> bool { - let matched = self - .fields - .values() - .all(|(_, matched)| matched.load(Acquire)); - if matched { - self.has_matched.store(true, Release); - } - matched - } - - #[inline] - pub(crate) fn filter(&self) -> Option { - if self.is_matched() { - Some(self.level) - } else { - None - } - } -} - -impl<'a> Visit for MatchVisitor<'a> { - fn record_f64(&mut self, field: &Field, value: f64) { - match self.inner.fields.get(field) { - Some((ValueMatch::NaN, ref matched)) if value.is_nan() => { - matched.store(true, Release); - } - Some((ValueMatch::F64(ref e), ref matched)) - if (value - *e).abs() < std::f64::EPSILON => - { - matched.store(true, Release); - } - _ => {} - } - } - - fn record_i64(&mut self, field: &Field, value: i64) { - use std::convert::TryInto; - - match self.inner.fields.get(field) { - Some((ValueMatch::I64(ref e), ref matched)) if value == *e => { - matched.store(true, Release); - } - Some((ValueMatch::U64(ref e), ref matched)) if Ok(value) == (*e).try_into() => { - matched.store(true, Release); - } - _ => {} - } - } - - fn record_u64(&mut self, field: &Field, value: u64) { - match self.inner.fields.get(field) { - Some((ValueMatch::U64(ref e), ref matched)) if value == *e => { - matched.store(true, Release); - } - _ => {} - } - } - - fn record_bool(&mut self, field: &Field, value: bool) { - match self.inner.fields.get(field) { - Some((ValueMatch::Bool(ref e), ref matched)) if value == *e => { - matched.store(true, Release); - } - _ => {} - } - } - - fn record_str(&mut self, field: &Field, value: &str) { - match self.inner.fields.get(field) { - Some((ValueMatch::Pat(ref e), ref matched)) if e.str_matches(&value) => { - matched.store(true, Release); - } - Some((ValueMatch::Debug(ref e), ref matched)) if e.debug_matches(&value) => { - matched.store(true, Release) - } - _ => {} - } - } - - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - match self.inner.fields.get(field) { - Some((ValueMatch::Pat(ref e), ref matched)) if e.debug_matches(&value) => { - matched.store(true, Release); - } - Some((ValueMatch::Debug(ref e), ref matched)) if e.debug_matches(&value) => { - matched.store(true, Release) - } - _ => {} - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - #[derive(Debug)] - #[allow(dead_code)] - struct MyStruct { - answer: usize, - question: &'static str, - } - - #[test] - fn debug_struct_match() { - let my_struct = MyStruct { - answer: 42, - question: "life, the universe, and everything", - }; - - let pattern = "MyStruct { answer: 42, question: \"life, the universe, and everything\" }"; - - assert_eq!( - format!("{:?}", my_struct), - pattern, - "`MyStruct`'s `Debug` impl doesn't output the expected string" - ); - - let matcher = MatchDebug { - pattern: pattern.into(), - }; - assert!(matcher.debug_matches(&my_struct)) - } - - #[test] - fn debug_struct_not_match() { - let my_struct = MyStruct { - answer: 42, - question: "what shall we have for lunch?", - }; - - let pattern = "MyStruct { answer: 42, question: \"life, the universe, and everything\" }"; - - assert_eq!( - format!("{:?}", my_struct), - "MyStruct { answer: 42, question: \"what shall we have for lunch?\" }", - "`MyStruct`'s `Debug` impl doesn't output the expected string" - ); - - let matcher = MatchDebug { - pattern: pattern.into(), - }; - assert!(!matcher.debug_matches(&my_struct)) - } -} diff --git a/vendor/tracing-subscriber/src/filter/env/mod.rs b/vendor/tracing-subscriber/src/filter/env/mod.rs deleted file mode 100644 index 81a9ae2bd..000000000 --- a/vendor/tracing-subscriber/src/filter/env/mod.rs +++ /dev/null @@ -1,991 +0,0 @@ -//! A `Layer` that enables or disables spans and events based on a set of -//! filtering directives. - -// these are publicly re-exported, but the compiler doesn't realize -// that for some reason. -#[allow(unreachable_pub)] -pub use self::{builder::Builder, directive::Directive, field::BadName as BadFieldName}; -mod builder; -mod directive; -mod field; - -use crate::{ - filter::LevelFilter, - layer::{Context, Layer}, - sync::RwLock, -}; -use directive::ParseError; -use std::{cell::RefCell, collections::HashMap, env, error::Error, fmt, str::FromStr}; -use thread_local::ThreadLocal; -use tracing_core::{ - callsite, - field::Field, - span, - subscriber::{Interest, Subscriber}, - Metadata, -}; - -/// A [`Layer`] which filters spans and events based on a set of filter -/// directives. -/// -/// `EnvFilter` implements both the [`Layer`](#impl-Layer) and [`Filter`] traits, so it may -/// be used for both [global filtering][global] and [per-layer filtering][plf], -/// respectively. See [the documentation on filtering with `Layer`s][filtering] -/// for details. -/// -/// The [`Targets`] type implements a similar form of filtering, but without the -/// ability to dynamically enable events based on the current span context, and -/// without filtering on field values. When these features are not required, -/// [`Targets`] provides a lighter-weight alternative to [`EnvFilter`]. -/// -/// # Directives -/// -/// A filter consists of one or more comma-separated directives which match on [`Span`]s and [`Event`]s. -/// Each directive may have a corresponding maximum verbosity [`level`] which -/// enables (e.g., _selects for_) spans and events that match. Like `log`, -/// `tracing` considers less exclusive levels (like `trace` or `info`) to be more -/// verbose than more exclusive levels (like `error` or `warn`). -/// -/// The directive syntax is similar to that of [`env_logger`]'s. At a high level, the syntax for directives -/// consists of several parts: -/// -/// ```text -/// target[span{field=value}]=level -/// ``` -/// -/// Each component (`target`, `span`, `field`, `value`, and `level`) will be covered in turn. -/// -/// - `target` matches the event or span's target. In general, this is the module path and/or crate name. -/// Examples of targets `h2`, `tokio::net`, or `tide::server`. For more information on targets, -/// please refer to [`Metadata`]'s documentation. -/// - `span` matches on the span's name. If a `span` directive is provided alongside a `target`, -/// the `span` directive will match on spans _within_ the `target`. -/// - `field` matches on [fields] within spans. Field names can also be supplied without a `value` -/// and will match on any [`Span`] or [`Event`] that has a field with that name. -/// For example: `[span{field=\"value\"}]=debug`, `[{field}]=trace`. -/// - `value` matches on the value of a span's field. If a value is a numeric literal or a bool, -/// it will match _only_ on that value. Otherwise, this filter matches the -/// [`std::fmt::Debug`] output from the value. -/// - `level` sets a maximum verbosity level accepted by this directive. -/// -/// When a field value directive (`[{=}]=...`) matches a -/// value's [`std::fmt::Debug`] output (i.e., the field value in the directive -/// is not a `bool`, `i64`, `u64`, or `f64` literal), the matched pattern may be -/// interpreted as either a regular expression or as the precise expected -/// output of the field's [`std::fmt::Debug`] implementation. By default, these -/// filters are interpreted as regular expressions, but this can be disabled -/// using the [`Builder::with_regex`] builder method to use precise matching -/// instead. -/// -/// When field value filters are interpreted as regular expressions, the -/// [`regex-automata` crate's regular expression syntax][re-syntax] is -/// supported. -/// -/// **Note**: When filters are constructed from potentially untrusted inputs, -/// [disabling regular expression matching](Builder::with_regex) is strongly -/// recommended. -/// -/// ## Usage Notes -/// -/// - The portion of the directive which is included within the square brackets is `tracing`-specific. -/// - Any portion of the directive can be omitted. -/// - The sole exception are the `field` and `value` directives. If a `value` is provided, -/// a `field` must _also_ be provided. However, the converse does not hold, as fields can -/// be matched without a value. -/// - If only a level is provided, it will set the maximum level for all `Span`s and `Event`s -/// that are not enabled by other filters. -/// - A directive without a level will enable anything that it matches. This is equivalent to `=trace`. -/// - When a crate has a dash in its name, the default target for events will be the -/// crate's module path as it appears in Rust. This means every dash will be replaced -/// with an underscore. -/// - A dash in a target will only appear when being specified explicitly: -/// `tracing::info!(target: "target-name", ...);` -/// -/// ## Example Syntax -/// -/// - `tokio::net=info` will enable all spans or events that: -/// - have the `tokio::net` target, -/// - at the level `info` or above. -/// - `warn,tokio::net=info` will enable all spans and events that: -/// - are at the level `warn` or above, *or* -/// - have the `tokio::net` target at the level `info` or above. -/// - `my_crate[span_a]=trace` will enable all spans and events that: -/// - are within the `span_a` span or named `span_a` _if_ `span_a` has the target `my_crate`, -/// - at the level `trace` or above. -/// - `[span_b{name=\"bob\"}]` will enable all spans or event that: -/// - have _any_ target, -/// - are inside a span named `span_b`, -/// - which has a field named `name` with value `bob`, -/// - at _any_ level. -/// -/// # Examples -/// -/// Parsing an `EnvFilter` from the [default environment -/// variable](EnvFilter::from_default_env) (`RUST_LOG`): -/// -/// ``` -/// use tracing_subscriber::{EnvFilter, fmt, prelude::*}; -/// -/// tracing_subscriber::registry() -/// .with(fmt::layer()) -/// .with(EnvFilter::from_default_env()) -/// .init(); -/// ``` -/// -/// Parsing an `EnvFilter` [from a user-provided environment -/// variable](EnvFilter::from_env): -/// -/// ``` -/// use tracing_subscriber::{EnvFilter, fmt, prelude::*}; -/// -/// tracing_subscriber::registry() -/// .with(fmt::layer()) -/// .with(EnvFilter::from_env("MYAPP_LOG")) -/// .init(); -/// ``` -/// -/// Using `EnvFilter` as a [per-layer filter][plf] to filter only a single -/// [`Layer`]: -/// -/// ``` -/// use tracing_subscriber::{EnvFilter, fmt, prelude::*}; -/// -/// // Parse an `EnvFilter` configuration from the `RUST_LOG` -/// // environment variable. -/// let filter = EnvFilter::from_default_env(); -/// -/// // Apply the filter to this layer *only*. -/// let filtered_layer = fmt::layer().with_filter(filter); -/// -/// // Some other layer, whose output we don't want to filter. -/// let unfiltered_layer = // ... -/// # fmt::layer(); -/// -/// tracing_subscriber::registry() -/// .with(filtered_layer) -/// .with(unfiltered_layer) -/// .init(); -/// ``` -/// # Constructing `EnvFilter`s -/// -/// An `EnvFilter` is be constructed by parsing a string containing one or more -/// directives. The [`EnvFilter::new`] constructor parses an `EnvFilter` from a -/// string, ignoring any invalid directives, while [`EnvFilter::try_new`] -/// returns an error if invalid directives are encountered. Similarly, the -/// [`EnvFilter::from_env`] and [`EnvFilter::try_from_env`] constructors parse -/// an `EnvFilter` from the value of the provided environment variable, with -/// lossy and strict validation, respectively. -/// -/// A [builder](EnvFilter::builder) interface is available to set additional -/// configuration options prior to parsing an `EnvFilter`. See the [`Builder` -/// type's documentation](Builder) for details on the options that can be -/// configured using the builder. -/// -/// [`Span`]: tracing_core::span -/// [fields]: tracing_core::Field -/// [`Event`]: tracing_core::Event -/// [`level`]: tracing_core::Level -/// [`Metadata`]: tracing_core::Metadata -/// [`Targets`]: crate::filter::Targets -/// [`env_logger`]: https://crates.io/crates/env_logger -/// [`Filter`]: #impl-Filter -/// [global]: crate::layer#global-filtering -/// [plf]: crate::layer#per-layer-filtering -/// [filtering]: crate::layer#filtering-with-layers -#[cfg_attr(docsrs, doc(cfg(all(feature = "env-filter", feature = "std"))))] -#[derive(Debug)] -pub struct EnvFilter { - statics: directive::Statics, - dynamics: directive::Dynamics, - has_dynamics: bool, - by_id: RwLock>, - by_cs: RwLock>, - scope: ThreadLocal>>, - regex: bool, -} - -type FieldMap = HashMap; - -/// Indicates that an error occurred while parsing a `EnvFilter` from an -/// environment variable. -#[cfg_attr(docsrs, doc(cfg(all(feature = "env-filter", feature = "std"))))] -#[derive(Debug)] -pub struct FromEnvError { - kind: ErrorKind, -} - -#[derive(Debug)] -enum ErrorKind { - Parse(ParseError), - Env(env::VarError), -} - -impl EnvFilter { - /// `RUST_LOG` is the default environment variable used by - /// [`EnvFilter::from_default_env`] and [`EnvFilter::try_from_default_env`]. - /// - /// [`EnvFilter::from_default_env`]: EnvFilter::from_default_env() - /// [`EnvFilter::try_from_default_env`]: EnvFilter::try_from_default_env() - pub const DEFAULT_ENV: &'static str = "RUST_LOG"; - - // === constructors, etc === - - /// Returns a [builder] that can be used to configure a new [`EnvFilter`] - /// instance. - /// - /// The [`Builder`] type is used to set additional configurations, such as - /// [whether regular expressions are enabled](Builder::with_regex) or [the - /// default directive](Builder::with_default_directive) before parsing an - /// [`EnvFilter`] from a string or environment variable. - /// - /// [builder]: https://rust-unofficial.github.io/patterns/patterns/creational/builder.html - pub fn builder() -> Builder { - Builder::default() - } - - /// Returns a new `EnvFilter` from the value of the `RUST_LOG` environment - /// variable, ignoring any invalid filter directives. - /// - /// If the environment variable is empty or not set, or if it contains only - /// invalid directives, a default directive enabling the [`ERROR`] level is - /// added. - /// - /// To set additional configuration options prior to parsing the filter, use - /// the [`Builder`] type instead. - /// - /// This function is equivalent to the following: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// # fn docs() -> EnvFilter { - /// EnvFilter::builder() - /// .with_default_directive(LevelFilter::ERROR.into()) - /// .from_env_lossy() - /// # } - /// ``` - /// - /// [`ERROR`]: tracing::Level::ERROR - pub fn from_default_env() -> Self { - Self::builder() - .with_default_directive(LevelFilter::ERROR.into()) - .from_env_lossy() - } - - /// Returns a new `EnvFilter` from the value of the given environment - /// variable, ignoring any invalid filter directives. - /// - /// If the environment variable is empty or not set, or if it contains only - /// invalid directives, a default directive enabling the [`ERROR`] level is - /// added. - /// - /// To set additional configuration options prior to parsing the filter, use - /// the [`Builder`] type instead. - /// - /// This function is equivalent to the following: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// # fn docs() -> EnvFilter { - /// # let env = ""; - /// EnvFilter::builder() - /// .with_default_directive(LevelFilter::ERROR.into()) - /// .with_env_var(env) - /// .from_env_lossy() - /// # } - /// ``` - /// - /// [`ERROR`]: tracing::Level::ERROR - pub fn from_env>(env: A) -> Self { - Self::builder() - .with_default_directive(LevelFilter::ERROR.into()) - .with_env_var(env.as_ref()) - .from_env_lossy() - } - - /// Returns a new `EnvFilter` from the directives in the given string, - /// ignoring any that are invalid. - /// - /// If the string is empty or contains only invalid directives, a default - /// directive enabling the [`ERROR`] level is added. - /// - /// To set additional configuration options prior to parsing the filter, use - /// the [`Builder`] type instead. - /// - /// This function is equivalent to the following: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// # fn docs() -> EnvFilter { - /// # let directives = ""; - /// EnvFilter::builder() - /// .with_default_directive(LevelFilter::ERROR.into()) - /// .parse_lossy(directives) - /// # } - /// ``` - /// - /// [`ERROR`]: tracing::Level::ERROR - pub fn new>(directives: S) -> Self { - Self::builder() - .with_default_directive(LevelFilter::ERROR.into()) - .parse_lossy(directives) - } - - /// Returns a new `EnvFilter` from the directives in the given string, - /// or an error if any are invalid. - /// - /// If the string is empty, a default directive enabling the [`ERROR`] level - /// is added. - /// - /// To set additional configuration options prior to parsing the filter, use - /// the [`Builder`] type instead. - /// - /// This function is equivalent to the following: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// - /// # fn docs() -> Result { - /// # let directives = ""; - /// EnvFilter::builder() - /// .with_default_directive(LevelFilter::ERROR.into()) - /// .parse(directives) - /// # } - /// ``` - /// - /// [`ERROR`]: tracing::Level::ERROR - pub fn try_new>(dirs: S) -> Result { - Self::builder().parse(dirs) - } - - /// Returns a new `EnvFilter` from the value of the `RUST_LOG` environment - /// variable, or an error if the environment variable is unset or contains - /// any invalid filter directives. - /// - /// To set additional configuration options prior to parsing the filter, use - /// the [`Builder`] type instead. - /// - /// This function is equivalent to the following: - /// - /// ```rust - /// use tracing_subscriber::EnvFilter; - /// - /// # fn docs() -> Result { - /// EnvFilter::builder().try_from_env() - /// # } - /// ``` - pub fn try_from_default_env() -> Result { - Self::builder().try_from_env() - } - - /// Returns a new `EnvFilter` from the value of the given environment - /// variable, or an error if the environment variable is unset or contains - /// any invalid filter directives. - /// - /// To set additional configuration options prior to parsing the filter, use - /// the [`Builder`] type instead. - /// - /// This function is equivalent to the following: - /// - /// ```rust - /// use tracing_subscriber::EnvFilter; - /// - /// # fn docs() -> Result { - /// # let env = ""; - /// EnvFilter::builder().with_env_var(env).try_from_env() - /// # } - /// ``` - pub fn try_from_env>(env: A) -> Result { - Self::builder().with_env_var(env.as_ref()).try_from_env() - } - - /// Add a filtering directive to this `EnvFilter`. - /// - /// The added directive will be used in addition to any previously set - /// directives, either added using this method or provided when the filter - /// is constructed. - /// - /// Filters may be created from [`LevelFilter`] or [`Level`], which will - /// enable all traces at or below a certain verbosity level, or - /// parsed from a string specifying a directive. - /// - /// If a filter directive is inserted that matches exactly the same spans - /// and events as a previous filter, but sets a different level for those - /// spans and events, the previous directive is overwritten. - /// - /// [`LevelFilter`]: super::LevelFilter - /// [`Level`]: tracing_core::Level - /// - /// # Examples - /// - /// From [`LevelFilter`]: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// let mut filter = EnvFilter::from_default_env() - /// .add_directive(LevelFilter::INFO.into()); - /// ``` - /// - /// Or from [`Level`]: - /// - /// ```rust - /// # use tracing_subscriber::filter::{EnvFilter, LevelFilter}; - /// # use tracing::Level; - /// let mut filter = EnvFilter::from_default_env() - /// .add_directive(Level::INFO.into()); - /// ``` - /// - /// Parsed from a string: - /// - /// ```rust - /// use tracing_subscriber::filter::{EnvFilter, Directive}; - /// - /// # fn try_mk_filter() -> Result<(), Box> { - /// let mut filter = EnvFilter::try_from_default_env()? - /// .add_directive("my_crate::module=trace".parse()?) - /// .add_directive("my_crate::my_other_module::something=info".parse()?); - /// # Ok(()) - /// # } - /// ``` - /// In the above example, substitute `my_crate`, `module`, etc. with the - /// name your target crate/module is imported with. This might be - /// different from the package name in Cargo.toml (`-` is replaced by `_`). - /// Example, if the package name in your Cargo.toml is `MY-FANCY-LIB`, then - /// the corresponding Rust identifier would be `MY_FANCY_LIB`: - pub fn add_directive(mut self, mut directive: Directive) -> Self { - if !self.regex { - directive.deregexify(); - } - if let Some(stat) = directive.to_static() { - self.statics.add(stat) - } else { - self.has_dynamics = true; - self.dynamics.add(directive); - } - self - } - - // === filtering methods === - - /// Returns `true` if this `EnvFilter` would enable the provided `metadata` - /// in the current context. - /// - /// This is equivalent to calling the [`Layer::enabled`] or - /// [`Filter::enabled`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope. - pub fn enabled(&self, metadata: &Metadata<'_>, _: Context<'_, S>) -> bool { - let level = metadata.level(); - - // is it possible for a dynamic filter directive to enable this event? - // if not, we can avoid the thread loca'l access + iterating over the - // spans in the current scope. - if self.has_dynamics && self.dynamics.max_level >= *level { - if metadata.is_span() { - // If the metadata is a span, see if we care about its callsite. - let enabled_by_cs = self - .by_cs - .read() - .ok() - .map(|by_cs| by_cs.contains_key(&metadata.callsite())) - .unwrap_or(false); - if enabled_by_cs { - return true; - } - } - - let enabled_by_scope = { - let scope = self.scope.get_or_default().borrow(); - for filter in &*scope { - if filter >= level { - return true; - } - } - false - }; - if enabled_by_scope { - return true; - } - } - - // is it possible for a static filter directive to enable this event? - if self.statics.max_level >= *level { - // Otherwise, fall back to checking if the callsite is - // statically enabled. - return self.statics.enabled(metadata); - } - - false - } - - /// Returns an optional hint of the highest [verbosity level][level] that - /// this `EnvFilter` will enable. - /// - /// This is equivalent to calling the [`Layer::max_level_hint`] or - /// [`Filter::max_level_hint`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope. - /// - /// [level]: tracing_core::metadata::Level - pub fn max_level_hint(&self) -> Option { - if self.dynamics.has_value_filters() { - // If we perform any filtering on span field *values*, we will - // enable *all* spans, because their field values are not known - // until recording. - return Some(LevelFilter::TRACE); - } - std::cmp::max( - self.statics.max_level.into(), - self.dynamics.max_level.into(), - ) - } - - /// Informs the filter that a new span was created. - /// - /// This is equivalent to calling the [`Layer::on_new_span`] or - /// [`Filter::on_new_span`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope. - pub fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, _: Context<'_, S>) { - let by_cs = try_lock!(self.by_cs.read()); - if let Some(cs) = by_cs.get(&attrs.metadata().callsite()) { - let span = cs.to_span_match(attrs); - try_lock!(self.by_id.write()).insert(id.clone(), span); - } - } - - /// Informs the filter that the span with the provided `id` was entered. - /// - /// This is equivalent to calling the [`Layer::on_enter`] or - /// [`Filter::on_enter`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope. - pub fn on_enter(&self, id: &span::Id, _: Context<'_, S>) { - // XXX: This is where _we_ could push IDs to the stack instead, and use - // that to allow changing the filter while a span is already entered. - // But that might be much less efficient... - if let Some(span) = try_lock!(self.by_id.read()).get(id) { - self.scope.get_or_default().borrow_mut().push(span.level()); - } - } - - /// Informs the filter that the span with the provided `id` was exited. - /// - /// This is equivalent to calling the [`Layer::on_exit`] or - /// [`Filter::on_exit`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope. - pub fn on_exit(&self, id: &span::Id, _: Context<'_, S>) { - if self.cares_about_span(id) { - self.scope.get_or_default().borrow_mut().pop(); - } - } - - /// Informs the filter that the span with the provided `id` was closed. - /// - /// This is equivalent to calling the [`Layer::on_close`] or - /// [`Filter::on_close`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope. - pub fn on_close(&self, id: span::Id, _: Context<'_, S>) { - // If we don't need to acquire a write lock, avoid doing so. - if !self.cares_about_span(&id) { - return; - } - - let mut spans = try_lock!(self.by_id.write()); - spans.remove(&id); - } - - /// Informs the filter that the span with the provided `id` recorded the - /// provided field `values`. - /// - /// This is equivalent to calling the [`Layer::on_record`] or - /// [`Filter::on_record`] methods on `EnvFilter`'s implementations of those - /// traits, but it does not require the trait to be in scope - pub fn on_record(&self, id: &span::Id, values: &span::Record<'_>, _: Context<'_, S>) { - if let Some(span) = try_lock!(self.by_id.read()).get(id) { - span.record_update(values); - } - } - - fn cares_about_span(&self, span: &span::Id) -> bool { - let spans = try_lock!(self.by_id.read(), else return false); - spans.contains_key(span) - } - - fn base_interest(&self) -> Interest { - if self.has_dynamics { - Interest::sometimes() - } else { - Interest::never() - } - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - if self.has_dynamics && metadata.is_span() { - // If this metadata describes a span, first, check if there is a - // dynamic filter that should be constructed for it. If so, it - // should always be enabled, since it influences filtering. - if let Some(matcher) = self.dynamics.matcher(metadata) { - let mut by_cs = try_lock!(self.by_cs.write(), else return self.base_interest()); - by_cs.insert(metadata.callsite(), matcher); - return Interest::always(); - } - } - - // Otherwise, check if any of our static filters enable this metadata. - if self.statics.enabled(metadata) { - Interest::always() - } else { - self.base_interest() - } - } -} - -impl Layer for EnvFilter { - #[inline] - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - EnvFilter::register_callsite(self, metadata) - } - - #[inline] - fn max_level_hint(&self) -> Option { - EnvFilter::max_level_hint(self) - } - - #[inline] - fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { - self.enabled(metadata, ctx) - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - self.on_new_span(attrs, id, ctx) - } - - #[inline] - fn on_record(&self, id: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - self.on_record(id, values, ctx); - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - self.on_enter(id, ctx); - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - self.on_exit(id, ctx); - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - self.on_close(id, ctx); - } -} - -feature! { - #![all(feature = "registry", feature = "std")] - use crate::layer::Filter; - - impl Filter for EnvFilter { - #[inline] - fn enabled(&self, meta: &Metadata<'_>, ctx: &Context<'_, S>) -> bool { - self.enabled(meta, ctx.clone()) - } - - #[inline] - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - self.register_callsite(meta) - } - - #[inline] - fn max_level_hint(&self) -> Option { - EnvFilter::max_level_hint(self) - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - self.on_new_span(attrs, id, ctx) - } - - #[inline] - fn on_record(&self, id: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - self.on_record(id, values, ctx); - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - self.on_enter(id, ctx); - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - self.on_exit(id, ctx); - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - self.on_close(id, ctx); - } - } -} - -impl FromStr for EnvFilter { - type Err = directive::ParseError; - - fn from_str(spec: &str) -> Result { - Self::try_new(spec) - } -} - -impl From for EnvFilter -where - S: AsRef, -{ - fn from(s: S) -> Self { - Self::new(s) - } -} - -impl Default for EnvFilter { - fn default() -> Self { - Builder::default().from_directives(std::iter::empty()) - } -} - -impl fmt::Display for EnvFilter { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut statics = self.statics.iter(); - let wrote_statics = if let Some(next) = statics.next() { - fmt::Display::fmt(next, f)?; - for directive in statics { - write!(f, ",{}", directive)?; - } - true - } else { - false - }; - - let mut dynamics = self.dynamics.iter(); - if let Some(next) = dynamics.next() { - if wrote_statics { - f.write_str(",")?; - } - fmt::Display::fmt(next, f)?; - for directive in dynamics { - write!(f, ",{}", directive)?; - } - } - Ok(()) - } -} - -// ===== impl FromEnvError ===== - -impl From for FromEnvError { - fn from(p: directive::ParseError) -> Self { - Self { - kind: ErrorKind::Parse(p), - } - } -} - -impl From for FromEnvError { - fn from(v: env::VarError) -> Self { - Self { - kind: ErrorKind::Env(v), - } - } -} - -impl fmt::Display for FromEnvError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - ErrorKind::Parse(ref p) => p.fmt(f), - ErrorKind::Env(ref e) => e.fmt(f), - } - } -} - -impl Error for FromEnvError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - match self.kind { - ErrorKind::Parse(ref p) => Some(p), - ErrorKind::Env(ref e) => Some(e), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use tracing_core::field::FieldSet; - use tracing_core::*; - - struct NoSubscriber; - impl Subscriber for NoSubscriber { - #[inline] - fn register_callsite(&self, _: &'static Metadata<'static>) -> subscriber::Interest { - subscriber::Interest::always() - } - fn new_span(&self, _: &span::Attributes<'_>) -> span::Id { - span::Id::from_u64(0xDEAD) - } - fn event(&self, _event: &Event<'_>) {} - fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {} - fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {} - - #[inline] - fn enabled(&self, _metadata: &Metadata<'_>) -> bool { - true - } - fn enter(&self, _span: &span::Id) {} - fn exit(&self, _span: &span::Id) {} - } - - struct Cs; - impl Callsite for Cs { - fn set_interest(&self, _interest: Interest) {} - fn metadata(&self) -> &Metadata<'_> { - unimplemented!() - } - } - - #[test] - fn callsite_enabled_no_span_directive() { - let filter = EnvFilter::new("app=debug").with_subscriber(NoSubscriber); - static META: &Metadata<'static> = &Metadata::new( - "mySpan", - "app", - Level::TRACE, - None, - None, - None, - FieldSet::new(&[], identify_callsite!(&Cs)), - Kind::SPAN, - ); - - let interest = filter.register_callsite(META); - assert!(interest.is_never()); - } - - #[test] - fn callsite_off() { - let filter = EnvFilter::new("app=off").with_subscriber(NoSubscriber); - static META: &Metadata<'static> = &Metadata::new( - "mySpan", - "app", - Level::ERROR, - None, - None, - None, - FieldSet::new(&[], identify_callsite!(&Cs)), - Kind::SPAN, - ); - - let interest = filter.register_callsite(META); - assert!(interest.is_never()); - } - - #[test] - fn callsite_enabled_includes_span_directive() { - let filter = EnvFilter::new("app[mySpan]=debug").with_subscriber(NoSubscriber); - static META: &Metadata<'static> = &Metadata::new( - "mySpan", - "app", - Level::TRACE, - None, - None, - None, - FieldSet::new(&[], identify_callsite!(&Cs)), - Kind::SPAN, - ); - - let interest = filter.register_callsite(META); - assert!(interest.is_always()); - } - - #[test] - fn callsite_enabled_includes_span_directive_field() { - let filter = - EnvFilter::new("app[mySpan{field=\"value\"}]=debug").with_subscriber(NoSubscriber); - static META: &Metadata<'static> = &Metadata::new( - "mySpan", - "app", - Level::TRACE, - None, - None, - None, - FieldSet::new(&["field"], identify_callsite!(&Cs)), - Kind::SPAN, - ); - - let interest = filter.register_callsite(META); - assert!(interest.is_always()); - } - - #[test] - fn callsite_enabled_includes_span_directive_multiple_fields() { - let filter = EnvFilter::new("app[mySpan{field=\"value\",field2=2}]=debug") - .with_subscriber(NoSubscriber); - static META: &Metadata<'static> = &Metadata::new( - "mySpan", - "app", - Level::TRACE, - None, - None, - None, - FieldSet::new(&["field"], identify_callsite!(&Cs)), - Kind::SPAN, - ); - - let interest = filter.register_callsite(META); - assert!(interest.is_never()); - } - - #[test] - fn roundtrip() { - let f1: EnvFilter = - "[span1{foo=1}]=error,[span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug" - .parse() - .unwrap(); - let f2: EnvFilter = format!("{}", f1).parse().unwrap(); - assert_eq!(f1.statics, f2.statics); - assert_eq!(f1.dynamics, f2.dynamics); - } - - #[test] - fn size_of_filters() { - fn print_sz(s: &str) { - let filter = s.parse::().expect("filter should parse"); - println!( - "size_of_val({:?})\n -> {}B", - s, - std::mem::size_of_val(&filter) - ); - } - - print_sz("info"); - - print_sz("foo=debug"); - - print_sz( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off", - ); - - print_sz("[span1{foo=1}]=error,[span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug"); - - print_sz( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off,[span1{foo=1}]=error,\ - [span2{bar=2 baz=false}],crate2[{quux=\"quuux\"}]=debug", - ); - } - - #[test] - fn parse_empty_string() { - // There is no corresponding test for [`Builder::parse_lossy`] as failed - // parsing does not produce any observable side effects. If this test fails - // check that [`Builder::parse_lossy`] is behaving correctly as well. - assert!(EnvFilter::builder().parse("").is_ok()); - } -} diff --git a/vendor/tracing-subscriber/src/filter/filter_fn.rs b/vendor/tracing-subscriber/src/filter/filter_fn.rs deleted file mode 100644 index 332bf860a..000000000 --- a/vendor/tracing-subscriber/src/filter/filter_fn.rs +++ /dev/null @@ -1,749 +0,0 @@ -use crate::{ - filter::LevelFilter, - layer::{Context, Layer}, -}; -use core::{any::type_name, fmt, marker::PhantomData}; -use tracing_core::{Interest, Metadata, Subscriber}; - -/// A filter implemented by a closure or function pointer that -/// determines whether a given span or event is enabled, based on its -/// [`Metadata`]. -/// -/// This type can be used for both [per-layer filtering][plf] (using its -/// [`Filter`] implementation) and [global filtering][global] (using its -/// [`Layer`] implementation). -/// -/// See the [documentation on filtering with layers][filtering] for details. -/// -/// [`Metadata`]: tracing_core::Metadata -/// [`Filter`]: crate::layer::Filter -/// [`Layer`]: crate::layer::Layer -/// [plf]: crate::layer#per-layer-filtering -/// [global]: crate::layer#global-filtering -/// [filtering]: crate::layer#filtering-with-layers -#[derive(Clone)] -pub struct FilterFn) -> bool> { - enabled: F, - max_level_hint: Option, -} - -/// A filter implemented by a closure or function pointer that -/// determines whether a given span or event is enabled _dynamically_, -/// potentially based on the current [span context]. -/// -/// This type can be used for both [per-layer filtering][plf] (using its -/// [`Filter`] implementation) and [global filtering][global] (using its -/// [`Layer`] implementation). -/// -/// See the [documentation on filtering with layers][filtering] for details. -/// -/// [span context]: crate::layer::Context -/// [`Filter`]: crate::layer::Filter -/// [`Layer`]: crate::layer::Layer -/// [plf]: crate::layer#per-layer-filtering -/// [global]: crate::layer#global-filtering -/// [filtering]: crate::layer#filtering-with-layers -pub struct DynFilterFn< - S, - // TODO(eliza): should these just be boxed functions? - F = fn(&Metadata<'_>, &Context<'_, S>) -> bool, - R = fn(&'static Metadata<'static>) -> Interest, -> { - enabled: F, - register_callsite: Option, - max_level_hint: Option, - _s: PhantomData, -} - -// === impl FilterFn === - -/// Constructs a [`FilterFn`], from a function or closure that returns `true` if -/// a span or event should be enabled, based on its [`Metadata`]. -/// -/// The returned [`FilterFn`] can be used for both [per-layer filtering][plf] -/// (using its [`Filter`] implementation) and [global filtering][global] (using -/// its [`Layer`] implementation). -/// -/// See the [documentation on filtering with layers][filtering] for details. -/// -/// This is equivalent to calling [`FilterFn::new`]. -/// -/// [`Metadata`]: tracing_core::Metadata -/// [`Filter`]: crate::layer::Filter -/// [`Layer`]: crate::layer::Layer -/// [plf]: crate::layer#per-layer-filtering -/// [global]: crate::layer#global-filtering -/// [filtering]: crate::layer#filtering-with-layers -/// -/// # Examples -/// -/// ``` -/// use tracing_subscriber::{ -/// layer::{Layer, SubscriberExt}, -/// filter, -/// util::SubscriberInitExt, -/// }; -/// -/// let my_filter = filter::filter_fn(|metadata| { -/// // Only enable spans or events with the target "interesting_things" -/// metadata.target() == "interesting_things" -/// }); -/// -/// let my_layer = tracing_subscriber::fmt::layer(); -/// -/// tracing_subscriber::registry() -/// .with(my_layer.with_filter(my_filter)) -/// .init(); -/// -/// // This event will not be enabled. -/// tracing::warn!("something important but uninteresting happened!"); -/// -/// // This event will be enabled. -/// tracing::debug!(target: "interesting_things", "an interesting minor detail..."); -/// ``` -pub fn filter_fn(f: F) -> FilterFn -where - F: Fn(&Metadata<'_>) -> bool, -{ - FilterFn::new(f) -} - -/// Constructs a [`DynFilterFn`] from a function or closure that returns `true` -/// if a span or event should be enabled within a particular [span context][`Context`]. -/// -/// This is equivalent to calling [`DynFilterFn::new`]. -/// -/// Unlike [`filter_fn`], this function takes a closure or function pointer -/// taking the [`Metadata`] for a span or event *and* the current [`Context`]. -/// This means that a [`DynFilterFn`] can choose whether to enable spans or -/// events based on information about the _current_ span (or its parents). -/// -/// If this is *not* necessary, use [`filter_fn`] instead. -/// -/// The returned [`DynFilterFn`] can be used for both [per-layer filtering][plf] -/// (using its [`Filter`] implementation) and [global filtering][global] (using -/// its [`Layer`] implementation). -/// -/// See the [documentation on filtering with layers][filtering] for details. -/// -/// # Examples -/// -/// ``` -/// use tracing_subscriber::{ -/// layer::{Layer, SubscriberExt}, -/// filter, -/// util::SubscriberInitExt, -/// }; -/// -/// // Only enable spans or events within a span named "interesting_span". -/// let my_filter = filter::dynamic_filter_fn(|metadata, cx| { -/// // If this *is* "interesting_span", make sure to enable it. -/// if metadata.is_span() && metadata.name() == "interesting_span" { -/// return true; -/// } -/// -/// // Otherwise, are we in an interesting span? -/// if let Some(current_span) = cx.lookup_current() { -/// return current_span.name() == "interesting_span"; -/// } -/// -/// false -/// }); -/// -/// let my_layer = tracing_subscriber::fmt::layer(); -/// -/// tracing_subscriber::registry() -/// .with(my_layer.with_filter(my_filter)) -/// .init(); -/// -/// // This event will not be enabled. -/// tracing::info!("something happened"); -/// -/// tracing::info_span!("interesting_span").in_scope(|| { -/// // This event will be enabled. -/// tracing::debug!("something else happened"); -/// }); -/// ``` -/// -/// [`Filter`]: crate::layer::Filter -/// [`Layer`]: crate::layer::Layer -/// [plf]: crate::layer#per-layer-filtering -/// [global]: crate::layer#global-filtering -/// [filtering]: crate::layer#filtering-with-layers -/// [`Context`]: crate::layer::Context -/// [`Metadata`]: tracing_core::Metadata -pub fn dynamic_filter_fn(f: F) -> DynFilterFn -where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, -{ - DynFilterFn::new(f) -} - -impl FilterFn -where - F: Fn(&Metadata<'_>) -> bool, -{ - /// Constructs a [`FilterFn`] from a function or closure that returns `true` - /// if a span or event should be enabled, based on its [`Metadata`]. - /// - /// If determining whether a span or event should be enabled also requires - /// information about the current span context, use [`DynFilterFn`] instead. - /// - /// See the [documentation on per-layer filtering][plf] for details on using - /// [`Filter`]s. - /// - /// [`Filter`]: crate::layer::Filter - /// [plf]: crate::layer#per-layer-filtering - /// [`Metadata`]: tracing_core::Metadata - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::{ - /// layer::{Layer, SubscriberExt}, - /// filter::FilterFn, - /// util::SubscriberInitExt, - /// }; - /// - /// let my_filter = FilterFn::new(|metadata| { - /// // Only enable spans or events with the target "interesting_things" - /// metadata.target() == "interesting_things" - /// }); - /// - /// let my_layer = tracing_subscriber::fmt::layer(); - /// - /// tracing_subscriber::registry() - /// .with(my_layer.with_filter(my_filter)) - /// .init(); - /// - /// // This event will not be enabled. - /// tracing::warn!("something important but uninteresting happened!"); - /// - /// // This event will be enabled. - /// tracing::debug!(target: "interesting_things", "an interesting minor detail..."); - /// ``` - pub fn new(enabled: F) -> Self { - Self { - enabled, - max_level_hint: None, - } - } - - /// Sets the highest verbosity [`Level`] the filter function will enable. - /// - /// The value passed to this method will be returned by this `FilterFn`'s - /// [`Filter::max_level_hint`] method. - /// - /// If the provided function will not enable all levels, it is recommended - /// to call this method to configure it with the most verbose level it will - /// enable. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::{ - /// layer::{Layer, SubscriberExt}, - /// filter::{filter_fn, LevelFilter}, - /// util::SubscriberInitExt, - /// }; - /// use tracing_core::Level; - /// - /// let my_filter = filter_fn(|metadata| { - /// // Only enable spans or events with targets starting with `my_crate` - /// // and levels at or below `INFO`. - /// metadata.level() <= &Level::INFO && metadata.target().starts_with("my_crate") - /// }) - /// // Since the filter closure will only enable the `INFO` level and - /// // below, set the max level hint - /// .with_max_level_hint(LevelFilter::INFO); - /// - /// let my_layer = tracing_subscriber::fmt::layer(); - /// - /// tracing_subscriber::registry() - /// .with(my_layer.with_filter(my_filter)) - /// .init(); - /// ``` - /// - /// [`Level`]: tracing_core::Level - /// [`Filter::max_level_hint`]: crate::layer::Filter::max_level_hint - pub fn with_max_level_hint(self, max_level_hint: impl Into) -> Self { - Self { - max_level_hint: Some(max_level_hint.into()), - ..self - } - } - - #[inline] - pub(in crate::filter) fn is_enabled(&self, metadata: &Metadata<'_>) -> bool { - let enabled = (self.enabled)(metadata); - debug_assert!( - !enabled || self.is_below_max_level(metadata), - "FilterFn<{}> claimed it would only enable {:?} and below, \ - but it enabled metadata with the {:?} level\nmetadata={:#?}", - type_name::(), - self.max_level_hint.unwrap(), - metadata.level(), - metadata, - ); - - enabled - } - - #[inline] - pub(in crate::filter) fn is_callsite_enabled( - &self, - metadata: &'static Metadata<'static>, - ) -> Interest { - // Because `self.enabled` takes a `Metadata` only (and no `Context` - // parameter), we can reasonably assume its results are cachable, and - // just return `Interest::always`/`Interest::never`. - if (self.enabled)(metadata) { - debug_assert!( - self.is_below_max_level(metadata), - "FilterFn<{}> claimed it was only interested in {:?} and below, \ - but it enabled metadata with the {:?} level\nmetadata={:#?}", - type_name::(), - self.max_level_hint.unwrap(), - metadata.level(), - metadata, - ); - return Interest::always(); - } - - Interest::never() - } - - fn is_below_max_level(&self, metadata: &Metadata<'_>) -> bool { - self.max_level_hint - .as_ref() - .map(|hint| metadata.level() <= hint) - .unwrap_or(true) - } -} - -impl Layer for FilterFn -where - F: Fn(&Metadata<'_>) -> bool + 'static, - S: Subscriber, -{ - fn enabled(&self, metadata: &Metadata<'_>, _: Context<'_, S>) -> bool { - self.is_enabled(metadata) - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.is_callsite_enabled(metadata) - } - - fn max_level_hint(&self) -> Option { - self.max_level_hint - } -} - -impl From for FilterFn -where - F: Fn(&Metadata<'_>) -> bool, -{ - fn from(enabled: F) -> Self { - Self::new(enabled) - } -} - -impl fmt::Debug for FilterFn { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FilterFn") - .field("enabled", &format_args!("{}", type_name::())) - .field("max_level_hint", &self.max_level_hint) - .finish() - } -} - -// === impl DynFilterFn == - -impl DynFilterFn -where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, -{ - /// Constructs a [`Filter`] from a function or closure that returns `true` - /// if a span or event should be enabled in the current [span - /// context][`Context`]. - /// - /// Unlike [`FilterFn`], a `DynFilterFn` is constructed from a closure or - /// function pointer that takes both the [`Metadata`] for a span or event - /// *and* the current [`Context`]. This means that a [`DynFilterFn`] can - /// choose whether to enable spans or events based on information about the - /// _current_ span (or its parents). - /// - /// If this is *not* necessary, use [`FilterFn`] instead. - /// - /// See the [documentation on per-layer filtering][plf] for details on using - /// [`Filter`]s. - /// - /// [`Filter`]: crate::layer::Filter - /// [plf]: crate::layer#per-layer-filtering - /// [`Context`]: crate::layer::Context - /// [`Metadata`]: tracing_core::Metadata - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::{ - /// layer::{Layer, SubscriberExt}, - /// filter::DynFilterFn, - /// util::SubscriberInitExt, - /// }; - /// - /// // Only enable spans or events within a span named "interesting_span". - /// let my_filter = DynFilterFn::new(|metadata, cx| { - /// // If this *is* "interesting_span", make sure to enable it. - /// if metadata.is_span() && metadata.name() == "interesting_span" { - /// return true; - /// } - /// - /// // Otherwise, are we in an interesting span? - /// if let Some(current_span) = cx.lookup_current() { - /// return current_span.name() == "interesting_span"; - /// } - /// - /// false - /// }); - /// - /// let my_layer = tracing_subscriber::fmt::layer(); - /// - /// tracing_subscriber::registry() - /// .with(my_layer.with_filter(my_filter)) - /// .init(); - /// - /// // This event will not be enabled. - /// tracing::info!("something happened"); - /// - /// tracing::info_span!("interesting_span").in_scope(|| { - /// // This event will be enabled. - /// tracing::debug!("something else happened"); - /// }); - /// ``` - pub fn new(enabled: F) -> Self { - Self { - enabled, - register_callsite: None, - max_level_hint: None, - _s: PhantomData, - } - } -} - -impl DynFilterFn -where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, -{ - /// Sets the highest verbosity [`Level`] the filter function will enable. - /// - /// The value passed to this method will be returned by this `DynFilterFn`'s - /// [`Filter::max_level_hint`] method. - /// - /// If the provided function will not enable all levels, it is recommended - /// to call this method to configure it with the most verbose level it will - /// enable. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::{ - /// layer::{Layer, SubscriberExt}, - /// filter::{DynFilterFn, LevelFilter}, - /// util::SubscriberInitExt, - /// }; - /// use tracing_core::Level; - /// - /// // Only enable spans or events with levels at or below `INFO`, if - /// // we are inside a span called "interesting_span". - /// let my_filter = DynFilterFn::new(|metadata, cx| { - /// // If the level is greater than INFO, disable it. - /// if metadata.level() > &Level::INFO { - /// return false; - /// } - /// - /// // If any span in the current scope is named "interesting_span", - /// // enable this span or event. - /// for span in cx.lookup_current().iter().flat_map(|span| span.scope()) { - /// if span.name() == "interesting_span" { - /// return true; - /// } - /// } - /// - /// // Otherwise, disable it. - /// false - /// }) - /// // Since the filter closure will only enable the `INFO` level and - /// // below, set the max level hint - /// .with_max_level_hint(LevelFilter::INFO); - /// - /// let my_layer = tracing_subscriber::fmt::layer(); - /// - /// tracing_subscriber::registry() - /// .with(my_layer.with_filter(my_filter)) - /// .init(); - /// ``` - /// - /// [`Level`]: tracing_core::Level - /// [`Filter::max_level_hint`]: crate::layer::Filter::max_level_hint - pub fn with_max_level_hint(self, max_level_hint: impl Into) -> Self { - Self { - max_level_hint: Some(max_level_hint.into()), - ..self - } - } - - /// Adds a function for filtering callsites to this filter. - /// - /// When this filter's [`Filter::callsite_enabled`][cse] method is called, - /// the provided function will be used rather than the default. - /// - /// By default, `DynFilterFn` assumes that, because the filter _may_ depend - /// dynamically on the current [span context], its result should never be - /// cached. However, some filtering strategies may require dynamic information - /// from the current span context in *some* cases, but are able to make - /// static filtering decisions from [`Metadata`] alone in others. - /// - /// For example, consider the filter given in the example for - /// [`DynFilterFn::new`]. That filter enables all spans named - /// "interesting_span", and any events and spans that occur inside of an - /// interesting span. Since the span's name is part of its static - /// [`Metadata`], the "interesting_span" can be enabled in - /// [`callsite_enabled`][cse]: - /// - /// ``` - /// use tracing_subscriber::{ - /// layer::{Layer, SubscriberExt}, - /// filter::DynFilterFn, - /// util::SubscriberInitExt, - /// }; - /// use tracing_core::subscriber::Interest; - /// - /// // Only enable spans or events within a span named "interesting_span". - /// let my_filter = DynFilterFn::new(|metadata, cx| { - /// // If this *is* "interesting_span", make sure to enable it. - /// if metadata.is_span() && metadata.name() == "interesting_span" { - /// return true; - /// } - /// - /// // Otherwise, are we in an interesting span? - /// if let Some(current_span) = cx.lookup_current() { - /// return current_span.name() == "interesting_span"; - /// } - /// - /// false - /// }).with_callsite_filter(|metadata| { - /// // If this is an "interesting_span", we know we will always - /// // enable it. - /// if metadata.is_span() && metadata.name() == "interesting_span" { - /// return Interest::always(); - /// } - /// - /// // Otherwise, it depends on whether or not we're in an interesting - /// // span. You'll have to ask us again for each span/event! - /// Interest::sometimes() - /// }); - /// - /// let my_layer = tracing_subscriber::fmt::layer(); - /// - /// tracing_subscriber::registry() - /// .with(my_layer.with_filter(my_filter)) - /// .init(); - /// ``` - /// - /// [cse]: crate::layer::Filter::callsite_enabled - /// [`enabled`]: crate::layer::Filter::enabled - /// [`Metadata`]: tracing_core::Metadata - /// [span context]: crate::layer::Context - pub fn with_callsite_filter(self, callsite_enabled: R2) -> DynFilterFn - where - R2: Fn(&'static Metadata<'static>) -> Interest, - { - let register_callsite = Some(callsite_enabled); - let DynFilterFn { - enabled, - max_level_hint, - _s, - .. - } = self; - DynFilterFn { - enabled, - register_callsite, - max_level_hint, - _s, - } - } - - fn default_callsite_enabled(&self, metadata: &Metadata<'_>) -> Interest { - // If it's below the configured max level, assume that `enabled` will - // never enable it... - if !is_below_max_level(&self.max_level_hint, metadata) { - debug_assert!( - !(self.enabled)(metadata, &Context::none()), - "DynFilterFn<{}> claimed it would only enable {:?} and below, \ - but it enabled metadata with the {:?} level\nmetadata={:#?}", - type_name::(), - self.max_level_hint.unwrap(), - metadata.level(), - metadata, - ); - return Interest::never(); - } - - // Otherwise, since this `enabled` function is dynamic and depends on - // the current context, we don't know whether this span or event will be - // enabled or not. Ask again every time it's recorded! - Interest::sometimes() - } -} - -impl DynFilterFn -where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, - R: Fn(&'static Metadata<'static>) -> Interest, -{ - #[inline] - fn is_enabled(&self, metadata: &Metadata<'_>, cx: &Context<'_, S>) -> bool { - let enabled = (self.enabled)(metadata, cx); - debug_assert!( - !enabled || is_below_max_level(&self.max_level_hint, metadata), - "DynFilterFn<{}> claimed it would only enable {:?} and below, \ - but it enabled metadata with the {:?} level\nmetadata={:#?}", - type_name::(), - self.max_level_hint.unwrap(), - metadata.level(), - metadata, - ); - - enabled - } - - #[inline] - fn is_callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - let interest = self - .register_callsite - .as_ref() - .map(|callsite_enabled| callsite_enabled(metadata)) - .unwrap_or_else(|| self.default_callsite_enabled(metadata)); - debug_assert!( - interest.is_never() || is_below_max_level(&self.max_level_hint, metadata), - "DynFilterFn<{}, {}> claimed it was only interested in {:?} and below, \ - but it enabled metadata with the {:?} level\nmetadata={:#?}", - type_name::(), - type_name::(), - self.max_level_hint.unwrap(), - metadata.level(), - metadata, - ); - - interest - } -} - -impl Layer for DynFilterFn -where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool + 'static, - R: Fn(&'static Metadata<'static>) -> Interest + 'static, - S: Subscriber, -{ - fn enabled(&self, metadata: &Metadata<'_>, cx: Context<'_, S>) -> bool { - self.is_enabled(metadata, &cx) - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.is_callsite_enabled(metadata) - } - - fn max_level_hint(&self) -> Option { - self.max_level_hint - } -} - -impl fmt::Debug for DynFilterFn { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("DynFilterFn"); - s.field("enabled", &format_args!("{}", type_name::())); - if self.register_callsite.is_some() { - s.field( - "register_callsite", - &format_args!("Some({})", type_name::()), - ); - } else { - s.field("register_callsite", &format_args!("None")); - } - - s.field("max_level_hint", &self.max_level_hint).finish() - } -} - -impl Clone for DynFilterFn -where - F: Clone, - R: Clone, -{ - fn clone(&self) -> Self { - Self { - enabled: self.enabled.clone(), - register_callsite: self.register_callsite.clone(), - max_level_hint: self.max_level_hint, - _s: PhantomData, - } - } -} - -impl From for DynFilterFn -where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, -{ - fn from(f: F) -> Self { - Self::new(f) - } -} - -// === PLF impls === - -feature! { - #![all(feature = "registry", feature = "std")] - use crate::layer::Filter; - - impl Filter for FilterFn - where - F: Fn(&Metadata<'_>) -> bool, - { - fn enabled(&self, metadata: &Metadata<'_>, _: &Context<'_, S>) -> bool { - self.is_enabled(metadata) - } - - fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - self.is_callsite_enabled(metadata) - } - - fn max_level_hint(&self) -> Option { - self.max_level_hint - } - } - - impl Filter for DynFilterFn - where - F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool, - R: Fn(&'static Metadata<'static>) -> Interest, - { - fn enabled(&self, metadata: &Metadata<'_>, cx: &Context<'_, S>) -> bool { - self.is_enabled(metadata, cx) - } - - fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - self.is_callsite_enabled(metadata) - } - - fn max_level_hint(&self) -> Option { - self.max_level_hint - } - } -} - -fn is_below_max_level(hint: &Option, metadata: &Metadata<'_>) -> bool { - hint.as_ref() - .map(|hint| metadata.level() <= hint) - .unwrap_or(true) -} diff --git a/vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs b/vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs deleted file mode 100644 index e79de2087..000000000 --- a/vendor/tracing-subscriber/src/filter/layer_filters/combinator.rs +++ /dev/null @@ -1,469 +0,0 @@ -//! Filter combinators -use crate::layer::{Context, Filter}; -use std::{cmp, fmt, marker::PhantomData}; -use tracing_core::{ - span::{Attributes, Id, Record}, - subscriber::Interest, - LevelFilter, Metadata, -}; - -/// Combines two [`Filter`]s so that spans and events are enabled if and only if -/// *both* filters return `true`. -/// -/// This type is typically returned by the [`FilterExt::and`] method. See that -/// method's documentation for details. -/// -/// [`Filter`]: crate::layer::Filter -/// [`FilterExt::and`]: crate::filter::FilterExt::and -pub struct And { - a: A, - b: B, - _s: PhantomData, -} - -/// Combines two [`Filter`]s so that spans and events are enabled if *either* filter -/// returns `true`. -/// -/// This type is typically returned by the [`FilterExt::or`] method. See that -/// method's documentation for details. -/// -/// [`Filter`]: crate::layer::Filter -/// [`FilterExt::or`]: crate::filter::FilterExt::or -pub struct Or { - a: A, - b: B, - _s: PhantomData, -} - -/// Inverts the result of a [`Filter`]. -/// -/// If the wrapped filter would enable a span or event, it will be disabled. If -/// it would disable a span or event, that span or event will be enabled. -/// -/// This type is typically returned by the [`FilterExt::or`] method. See that -/// method's documentation for details. -/// -/// [`Filter`]: crate::layer::Filter -/// [`FilterExt::or`]: crate::filter::FilterExt::or -pub struct Not { - a: A, - _s: PhantomData, -} - -// === impl And === - -impl And -where - A: Filter, - B: Filter, -{ - /// Combines two [`Filter`]s so that spans and events are enabled if and only if - /// *both* filters return `true`. - /// - /// # Examples - /// - /// Enabling spans or events if they have both a particular target *and* are - /// above a certain level: - /// - /// ```ignore - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, combinator::And}, - /// prelude::*, - /// }; - /// - /// // Enables spans and events with targets starting with `interesting_target`: - /// let target_filter = filter_fn(|meta| { - /// meta.target().starts_with("interesting_target") - /// }); - /// - /// // Enables spans and events with levels `INFO` and below: - /// let level_filter = LevelFilter::INFO; - /// - /// // Combine the two filters together so that a span or event is only enabled - /// // if *both* filters would enable it: - /// let filter = And::new(level_filter, target_filter); - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// - /// // This event will *not* be enabled: - /// tracing::info!("an event with an uninteresting target"); - /// - /// // This event *will* be enabled: - /// tracing::info!(target: "interesting_target", "a very interesting event"); - /// - /// // This event will *not* be enabled: - /// tracing::debug!(target: "interesting_target", "interesting debug event..."); - /// ``` - /// - /// [`Filter`]: crate::layer::Filter - pub(crate) fn new(a: A, b: B) -> Self { - Self { - a, - b, - _s: PhantomData, - } - } -} - -impl Filter for And -where - A: Filter, - B: Filter, -{ - #[inline] - fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool { - self.a.enabled(meta, cx) && self.b.enabled(meta, cx) - } - - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - let a = self.a.callsite_enabled(meta); - if a.is_never() { - return a; - } - - let b = self.b.callsite_enabled(meta); - - if !b.is_always() { - return b; - } - - a - } - - fn max_level_hint(&self) -> Option { - // If either hint is `None`, return `None`. Otherwise, return the most restrictive. - cmp::min(self.a.max_level_hint(), self.b.max_level_hint()) - } - - #[inline] - fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { - self.a.on_new_span(attrs, id, ctx.clone()); - self.b.on_new_span(attrs, id, ctx) - } - - #[inline] - fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { - self.a.on_record(id, values, ctx.clone()); - self.b.on_record(id, values, ctx); - } - - #[inline] - fn on_enter(&self, id: &Id, ctx: Context<'_, S>) { - self.a.on_enter(id, ctx.clone()); - self.b.on_enter(id, ctx); - } - - #[inline] - fn on_exit(&self, id: &Id, ctx: Context<'_, S>) { - self.a.on_exit(id, ctx.clone()); - self.b.on_exit(id, ctx); - } - - #[inline] - fn on_close(&self, id: Id, ctx: Context<'_, S>) { - self.a.on_close(id.clone(), ctx.clone()); - self.b.on_close(id, ctx); - } -} - -impl Clone for And -where - A: Clone, - B: Clone, -{ - fn clone(&self) -> Self { - Self { - a: self.a.clone(), - b: self.b.clone(), - _s: PhantomData, - } - } -} - -impl fmt::Debug for And -where - A: fmt::Debug, - B: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("And") - .field("a", &self.a) - .field("b", &self.b) - .finish() - } -} - -// === impl Or === - -impl Or -where - A: Filter, - B: Filter, -{ - /// Combines two [`Filter`]s so that spans and events are enabled if *either* filter - /// returns `true`. - /// - /// # Examples - /// - /// Enabling spans and events at the `INFO` level and above, and all spans - /// and events with a particular target: - /// - /// ```ignore - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, combinator::Or}, - /// prelude::*, - /// }; - /// - /// // Enables spans and events with targets starting with `interesting_target`: - /// let target_filter = filter_fn(|meta| { - /// meta.target().starts_with("interesting_target") - /// }); - /// - /// // Enables spans and events with levels `INFO` and below: - /// let level_filter = LevelFilter::INFO; - /// - /// // Combine the two filters together so that a span or event is enabled - /// // if it is at INFO or lower, or if it has a target starting with - /// // `interesting_target`. - /// let filter = Or::new(level_filter, target_filter); - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// - /// // This event will *not* be enabled: - /// tracing::debug!("an uninteresting event"); - /// - /// // This event *will* be enabled: - /// tracing::info!("an uninteresting INFO event"); - /// - /// // This event *will* be enabled: - /// tracing::info!(target: "interesting_target", "a very interesting event"); - /// - /// // This event *will* be enabled: - /// tracing::debug!(target: "interesting_target", "interesting debug event..."); - /// ``` - /// - /// Enabling a higher level for a particular target by using `Or` in - /// conjunction with the [`And`] combinator: - /// - /// ```ignore - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, combinator}, - /// prelude::*, - /// }; - /// - /// // This filter will enable spans and events with targets beginning with - /// // `my_crate`: - /// let my_crate = filter_fn(|meta| { - /// meta.target().starts_with("my_crate") - /// }); - /// - /// // Combine the `my_crate` filter with a `LevelFilter` to produce a filter - /// // that will enable the `INFO` level and lower for spans and events with - /// // `my_crate` targets: - /// let filter = combinator::And::new(my_crate, LevelFilter::INFO); - /// - /// // If a span or event *doesn't* have a target beginning with - /// // `my_crate`, enable it if it has the `WARN` level or lower: - /// // let filter = combinator::Or::new(filter, LevelFilter::WARN); - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// ``` - /// - /// [`Filter`]: crate::layer::Filter - pub(crate) fn new(a: A, b: B) -> Self { - Self { - a, - b, - _s: PhantomData, - } - } -} - -impl Filter for Or -where - A: Filter, - B: Filter, -{ - #[inline] - fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool { - self.a.enabled(meta, cx) || self.b.enabled(meta, cx) - } - - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - let a = self.a.callsite_enabled(meta); - let b = self.b.callsite_enabled(meta); - - // If either filter will always enable the span or event, return `always`. - if a.is_always() || b.is_always() { - return Interest::always(); - } - - // Okay, if either filter will sometimes enable the span or event, - // return `sometimes`. - if a.is_sometimes() || b.is_sometimes() { - return Interest::sometimes(); - } - - debug_assert!( - a.is_never() && b.is_never(), - "if neither filter was `always` or `sometimes`, both must be `never` (a={:?}; b={:?})", - a, - b, - ); - Interest::never() - } - - fn max_level_hint(&self) -> Option { - // If either hint is `None`, return `None`. Otherwise, return the less restrictive. - Some(cmp::max(self.a.max_level_hint()?, self.b.max_level_hint()?)) - } - - #[inline] - fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { - self.a.on_new_span(attrs, id, ctx.clone()); - self.b.on_new_span(attrs, id, ctx) - } - - #[inline] - fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { - self.a.on_record(id, values, ctx.clone()); - self.b.on_record(id, values, ctx); - } - - #[inline] - fn on_enter(&self, id: &Id, ctx: Context<'_, S>) { - self.a.on_enter(id, ctx.clone()); - self.b.on_enter(id, ctx); - } - - #[inline] - fn on_exit(&self, id: &Id, ctx: Context<'_, S>) { - self.a.on_exit(id, ctx.clone()); - self.b.on_exit(id, ctx); - } - - #[inline] - fn on_close(&self, id: Id, ctx: Context<'_, S>) { - self.a.on_close(id.clone(), ctx.clone()); - self.b.on_close(id, ctx); - } -} - -impl Clone for Or -where - A: Clone, - B: Clone, -{ - fn clone(&self) -> Self { - Self { - a: self.a.clone(), - b: self.b.clone(), - _s: PhantomData, - } - } -} - -impl fmt::Debug for Or -where - A: fmt::Debug, - B: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Or") - .field("a", &self.a) - .field("b", &self.b) - .finish() - } -} - -// === impl Not === - -impl Not -where - A: Filter, -{ - /// Inverts the result of a [`Filter`]. - /// - /// If the wrapped filter would enable a span or event, it will be disabled. If - /// it would disable a span or event, that span or event will be enabled. - /// - /// [`Filter`]: crate::layer::Filter - pub(crate) fn new(a: A) -> Self { - Self { a, _s: PhantomData } - } -} - -impl Filter for Not -where - A: Filter, -{ - #[inline] - fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool { - !self.a.enabled(meta, cx) - } - - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - match self.a.callsite_enabled(meta) { - i if i.is_always() => Interest::never(), - i if i.is_never() => Interest::always(), - _ => Interest::sometimes(), - } - } - - fn max_level_hint(&self) -> Option { - // TODO(eliza): figure this out??? - None - } - - #[inline] - fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { - self.a.on_new_span(attrs, id, ctx); - } - - #[inline] - fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { - self.a.on_record(id, values, ctx.clone()); - } - - #[inline] - fn on_enter(&self, id: &Id, ctx: Context<'_, S>) { - self.a.on_enter(id, ctx); - } - - #[inline] - fn on_exit(&self, id: &Id, ctx: Context<'_, S>) { - self.a.on_exit(id, ctx); - } - - #[inline] - fn on_close(&self, id: Id, ctx: Context<'_, S>) { - self.a.on_close(id, ctx); - } -} - -impl Clone for Not -where - A: Clone, -{ - fn clone(&self) -> Self { - Self { - a: self.a.clone(), - _s: PhantomData, - } - } -} - -impl fmt::Debug for Not -where - A: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Not").field(&self.a).finish() - } -} diff --git a/vendor/tracing-subscriber/src/filter/layer_filters/mod.rs b/vendor/tracing-subscriber/src/filter/layer_filters/mod.rs deleted file mode 100644 index 8949cfb5a..000000000 --- a/vendor/tracing-subscriber/src/filter/layer_filters/mod.rs +++ /dev/null @@ -1,1135 +0,0 @@ -//! ## Per-Layer Filtering -//! -//! Per-layer filters permit individual `Layer`s to have their own filter -//! configurations without interfering with other `Layer`s. -//! -//! This module is not public; the public APIs defined in this module are -//! re-exported in the top-level `filter` module. Therefore, this documentation -//! primarily concerns the internal implementation details. For the user-facing -//! public API documentation, see the individual public types in this module, as -//! well as the, see the `Layer` trait documentation's [per-layer filtering -//! section]][1]. -//! -//! ## How does per-layer filtering work? -//! -//! As described in the API documentation, the [`Filter`] trait defines a -//! filtering strategy for a per-layer filter. We expect there will be a variety -//! of implementations of [`Filter`], both in `tracing-subscriber` and in user -//! code. -//! -//! To actually *use* a [`Filter`] implementation, it is combined with a -//! [`Layer`] by the [`Filtered`] struct defined in this module. [`Filtered`] -//! implements [`Layer`] by calling into the wrapped [`Layer`], or not, based on -//! the filtering strategy. While there will be a variety of types that implement -//! [`Filter`], all actual *uses* of per-layer filtering will occur through the -//! [`Filtered`] struct. Therefore, most of the implementation details live -//! there. -//! -//! [1]: crate::layer#per-layer-filtering -//! [`Filter`]: crate::layer::Filter -use crate::{ - filter::LevelFilter, - layer::{self, Context, Layer}, - registry, -}; -use std::{ - any::TypeId, - cell::{Cell, RefCell}, - fmt, - marker::PhantomData, - ops::Deref, - sync::Arc, - thread_local, -}; -use tracing_core::{ - span, - subscriber::{Interest, Subscriber}, - Event, Metadata, -}; -pub mod combinator; - -/// A [`Layer`] that wraps an inner [`Layer`] and adds a [`Filter`] which -/// controls what spans and events are enabled for that layer. -/// -/// This is returned by the [`Layer::with_filter`] method. See the -/// [documentation on per-layer filtering][plf] for details. -/// -/// [`Filter`]: crate::layer::Filter -/// [plf]: crate::layer#per-layer-filtering -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -#[derive(Clone)] -pub struct Filtered { - filter: F, - layer: L, - id: MagicPlfDowncastMarker, - _s: PhantomData, -} - -/// Uniquely identifies an individual [`Filter`] instance in the context of -/// a [`Subscriber`]. -/// -/// When adding a [`Filtered`] [`Layer`] to a [`Subscriber`], the [`Subscriber`] -/// generates a `FilterId` for that [`Filtered`] layer. The [`Filtered`] layer -/// will then use the generated ID to query whether a particular span was -/// previously enabled by that layer's [`Filter`]. -/// -/// **Note**: Currently, the [`Registry`] type provided by this crate is the -/// **only** [`Subscriber`] implementation capable of participating in per-layer -/// filtering. Therefore, the `FilterId` type cannot currently be constructed by -/// code outside of `tracing-subscriber`. In the future, new APIs will be added to `tracing-subscriber` to -/// allow non-Registry [`Subscriber`]s to also participate in per-layer -/// filtering. When those APIs are added, subscribers will be responsible -/// for generating and assigning `FilterId`s. -/// -/// [`Filter`]: crate::layer::Filter -/// [`Subscriber`]: tracing_core::Subscriber -/// [`Layer`]: crate::layer::Layer -/// [`Registry`]: crate::registry::Registry -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -#[derive(Copy, Clone)] -pub struct FilterId(u64); - -/// A bitmap tracking which [`FilterId`]s have enabled a given span or -/// event. -/// -/// This is currently a private type that's used exclusively by the -/// [`Registry`]. However, in the future, this may become a public API, in order -/// to allow user subscribers to host [`Filter`]s. -/// -/// [`Registry`]: crate::Registry -/// [`Filter`]: crate::layer::Filter -#[derive(Default, Copy, Clone, Eq, PartialEq)] -pub(crate) struct FilterMap { - bits: u64, -} - -/// The current state of `enabled` calls to per-layer filters on this -/// thread. -/// -/// When `Filtered::enabled` is called, the filter will set the bit -/// corresponding to its ID if the filter will disable the event/span being -/// filtered. When the event or span is recorded, the per-layer filter will -/// check its bit to determine if it disabled that event or span, and skip -/// forwarding the event or span to the inner layer if the bit is set. Once -/// a span or event has been skipped by a per-layer filter, it unsets its -/// bit, so that the `FilterMap` has been cleared for the next set of -/// `enabled` calls. -/// -/// FilterState is also read by the `Registry`, for two reasons: -/// -/// 1. When filtering a span, the Registry must store the `FilterMap` -/// generated by `Filtered::enabled` calls for that span as part of the -/// span's per-span data. This allows `Filtered` layers to determine -/// whether they had previously disabled a given span, and avoid showing it -/// to the wrapped layer if it was disabled. -/// -/// This allows `Filtered` layers to also filter out the spans they -/// disable from span traversals (such as iterating over parents, etc). -/// 2. If all the bits are set, then every per-layer filter has decided it -/// doesn't want to enable that span or event. In that case, the -/// `Registry`'s `enabled` method will return `false`, so that -/// recording a span or event can be skipped entirely. -#[derive(Debug)] -pub(crate) struct FilterState { - enabled: Cell, - // TODO(eliza): `Interest`s should _probably_ be `Copy`. The only reason - // they're not is our Obsessive Commitment to Forwards-Compatibility. If - // this changes in tracing-core`, we can make this a `Cell` rather than - // `RefCell`... - interest: RefCell>, - - #[cfg(debug_assertions)] - counters: DebugCounters, -} - -/// Extra counters added to `FilterState` used only to make debug assertions. -#[cfg(debug_assertions)] -#[derive(Debug, Default)] -struct DebugCounters { - /// How many per-layer filters have participated in the current `enabled` - /// call? - in_filter_pass: Cell, - - /// How many per-layer filters have participated in the current `register_callsite` - /// call? - in_interest_pass: Cell, -} - -thread_local! { - pub(crate) static FILTERING: FilterState = FilterState::new(); -} - -/// Extension trait adding [combinators] for combining [`Filter`]. -/// -/// [combinators]: crate::filter::combinator -/// [`Filter`]: crate::layer::Filter -pub trait FilterExt: layer::Filter { - /// Combines this [`Filter`] with another [`Filter`] s so that spans and - /// events are enabled if and only if *both* filters return `true`. - /// - /// # Examples - /// - /// Enabling spans or events if they have both a particular target *and* are - /// above a certain level: - /// - /// ``` - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, FilterExt}, - /// prelude::*, - /// }; - /// - /// // Enables spans and events with targets starting with `interesting_target`: - /// let target_filter = filter_fn(|meta| { - /// meta.target().starts_with("interesting_target") - /// }); - /// - /// // Enables spans and events with levels `INFO` and below: - /// let level_filter = LevelFilter::INFO; - /// - /// // Combine the two filters together, returning a filter that only enables - /// // spans and events that *both* filters will enable: - /// let filter = target_filter.and(level_filter); - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// - /// // This event will *not* be enabled: - /// tracing::info!("an event with an uninteresting target"); - /// - /// // This event *will* be enabled: - /// tracing::info!(target: "interesting_target", "a very interesting event"); - /// - /// // This event will *not* be enabled: - /// tracing::debug!(target: "interesting_target", "interesting debug event..."); - /// ``` - /// - /// [`Filter`]: crate::layer::Filter - fn and(self, other: B) -> combinator::And - where - Self: Sized, - B: layer::Filter, - { - combinator::And::new(self, other) - } - - /// Combines two [`Filter`]s so that spans and events are enabled if *either* filter - /// returns `true`. - /// - /// # Examples - /// - /// Enabling spans and events at the `INFO` level and above, and all spans - /// and events with a particular target: - /// ``` - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, FilterExt}, - /// prelude::*, - /// }; - /// - /// // Enables spans and events with targets starting with `interesting_target`: - /// let target_filter = filter_fn(|meta| { - /// meta.target().starts_with("interesting_target") - /// }); - /// - /// // Enables spans and events with levels `INFO` and below: - /// let level_filter = LevelFilter::INFO; - /// - /// // Combine the two filters together so that a span or event is enabled - /// // if it is at INFO or lower, or if it has a target starting with - /// // `interesting_target`. - /// let filter = level_filter.or(target_filter); - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// - /// // This event will *not* be enabled: - /// tracing::debug!("an uninteresting event"); - /// - /// // This event *will* be enabled: - /// tracing::info!("an uninteresting INFO event"); - /// - /// // This event *will* be enabled: - /// tracing::info!(target: "interesting_target", "a very interesting event"); - /// - /// // This event *will* be enabled: - /// tracing::debug!(target: "interesting_target", "interesting debug event..."); - /// ``` - /// - /// Enabling a higher level for a particular target by using `or` in - /// conjunction with the [`and`] combinator: - /// - /// ``` - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, FilterExt}, - /// prelude::*, - /// }; - /// - /// // This filter will enable spans and events with targets beginning with - /// // `my_crate`: - /// let my_crate = filter_fn(|meta| { - /// meta.target().starts_with("my_crate") - /// }); - /// - /// let filter = my_crate - /// // Combine the `my_crate` filter with a `LevelFilter` to produce a - /// // filter that will enable the `INFO` level and lower for spans and - /// // events with `my_crate` targets: - /// .and(LevelFilter::INFO) - /// // If a span or event *doesn't* have a target beginning with - /// // `my_crate`, enable it if it has the `WARN` level or lower: - /// .or(LevelFilter::WARN); - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// ``` - /// - /// [`Filter`]: crate::layer::Filter - /// [`and`]: FilterExt::and - fn or(self, other: B) -> combinator::Or - where - Self: Sized, - B: layer::Filter, - { - combinator::Or::new(self, other) - } - - /// Inverts `self`, returning a filter that enables spans and events only if - /// `self` would *not* enable them. - fn not(self) -> combinator::Not - where - Self: Sized, - { - combinator::Not::new(self) - } - - /// [Boxes] `self`, erasing its concrete type. - /// - /// This is equivalent to calling [`Box::new`], but in method form, so that - /// it can be used when chaining combinator methods. - /// - /// # Examples - /// - /// When different combinations of filters are used conditionally, they may - /// have different types. For example, the following code won't compile, - /// since the `if` and `else` clause produce filters of different types: - /// - /// ```compile_fail - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, FilterExt}, - /// prelude::*, - /// }; - /// - /// let enable_bar_target: bool = // ... - /// # false; - /// - /// let filter = if enable_bar_target { - /// filter_fn(|meta| meta.target().starts_with("foo")) - /// // If `enable_bar_target` is true, add a `filter_fn` enabling - /// // spans and events with the target `bar`: - /// .or(filter_fn(|meta| meta.target().starts_with("bar"))) - /// .and(LevelFilter::INFO) - /// } else { - /// filter_fn(|meta| meta.target().starts_with("foo")) - /// .and(LevelFilter::INFO) - /// }; - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// ``` - /// - /// By using `boxed`, the types of the two different branches can be erased, - /// so the assignment to the `filter` variable is valid (as both branches - /// have the type `Box + Send + Sync + 'static>`). The - /// following code *does* compile: - /// - /// ``` - /// use tracing_subscriber::{ - /// filter::{filter_fn, LevelFilter, FilterExt}, - /// prelude::*, - /// }; - /// - /// let enable_bar_target: bool = // ... - /// # false; - /// - /// let filter = if enable_bar_target { - /// filter_fn(|meta| meta.target().starts_with("foo")) - /// .or(filter_fn(|meta| meta.target().starts_with("bar"))) - /// .and(LevelFilter::INFO) - /// // Boxing the filter erases its type, so both branches now - /// // have the same type. - /// .boxed() - /// } else { - /// filter_fn(|meta| meta.target().starts_with("foo")) - /// .and(LevelFilter::INFO) - /// .boxed() - /// }; - /// - /// tracing_subscriber::registry() - /// .with(tracing_subscriber::fmt::layer().with_filter(filter)) - /// .init(); - /// ``` - /// - /// [Boxes]: std::boxed - /// [`Box::new`]: std::boxed::Box::new - fn boxed(self) -> Box + Send + Sync + 'static> - where - Self: Sized + Send + Sync + 'static, - { - Box::new(self) - } -} - -// === impl Filter === - -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -impl layer::Filter for LevelFilter { - fn enabled(&self, meta: &Metadata<'_>, _: &Context<'_, S>) -> bool { - meta.level() <= self - } - - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - if meta.level() <= self { - Interest::always() - } else { - Interest::never() - } - } - - fn max_level_hint(&self) -> Option { - Some(*self) - } -} - -macro_rules! filter_impl_body { - () => { - #[inline] - fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool { - self.deref().enabled(meta, cx) - } - - #[inline] - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - self.deref().callsite_enabled(meta) - } - - #[inline] - fn max_level_hint(&self) -> Option { - self.deref().max_level_hint() - } - }; -} - -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -impl layer::Filter for Arc + Send + Sync + 'static> { - filter_impl_body!(); -} - -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -impl layer::Filter for Box + Send + Sync + 'static> { - filter_impl_body!(); -} - -// === impl Filtered === - -impl Filtered { - /// Wraps the provided [`Layer`] so that it is filtered by the given - /// [`Filter`]. - /// - /// This is equivalent to calling the [`Layer::with_filter`] method. - /// - /// See the [documentation on per-layer filtering][plf] for details. - /// - /// [`Filter`]: crate::layer::Filter - /// [plf]: crate::layer#per-layer-filtering - pub fn new(layer: L, filter: F) -> Self { - Self { - layer, - filter, - id: MagicPlfDowncastMarker(FilterId::disabled()), - _s: PhantomData, - } - } - - #[inline(always)] - fn id(&self) -> FilterId { - debug_assert!( - !self.id.0.is_disabled(), - "a `Filtered` layer was used, but it had no `FilterId`; \ - was it registered with the subscriber?" - ); - self.id.0 - } - - fn did_enable(&self, f: impl FnOnce()) { - FILTERING.with(|filtering| filtering.did_enable(self.id(), f)) - } - - /// Borrows the [`Filter`](crate::layer::Filter) used by this layer. - pub fn filter(&self) -> &F { - &self.filter - } - - /// Mutably borrows the [`Filter`](crate::layer::Filter) used by this layer. - /// - /// When this layer can be mutably borrowed, this may be used to mutate the filter. - /// Generally, this will primarily be used with the - /// [`reload::Handle::modify`](crate::reload::Handle::modify) method. - /// - /// # Examples - /// - /// ``` - /// # use tracing::info; - /// # use tracing_subscriber::{filter,fmt,reload,Registry,prelude::*}; - /// # fn main() { - /// let filtered_layer = fmt::Layer::default().with_filter(filter::LevelFilter::WARN); - /// let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer); - /// # - /// # // specifying the Registry type is required - /// # let _: &reload::Handle, - /// # filter::LevelFilter, Registry>,Registry> - /// # = &reload_handle; - /// # - /// info!("This will be ignored"); - /// reload_handle.modify(|layer| *layer.filter_mut() = filter::LevelFilter::INFO); - /// info!("This will be logged"); - /// # } - /// ``` - pub fn filter_mut(&mut self) -> &mut F { - &mut self.filter - } - - /// Borrows the inner [`Layer`] wrapped by this `Filtered` layer. - pub fn inner(&self) -> &L { - &self.layer - } - - /// Mutably borrows the inner [`Layer`] wrapped by this `Filtered` layer. - /// - /// This method is primarily expected to be used with the - /// [`reload::Handle::modify`](crate::reload::Handle::modify) method. - /// - /// # Examples - /// - /// ``` - /// # use tracing::info; - /// # use tracing_subscriber::{filter,fmt,reload,Registry,prelude::*}; - /// # fn non_blocking(writer: T) -> (fn() -> std::io::Stdout) { - /// # std::io::stdout - /// # } - /// # fn main() { - /// let filtered_layer = fmt::layer().with_writer(non_blocking(std::io::stderr())).with_filter(filter::LevelFilter::INFO); - /// let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer); - /// # - /// # // specifying the Registry type is required - /// # let _: &reload::Handle std::io::Stdout>, - /// # filter::LevelFilter, Registry>, Registry> - /// # = &reload_handle; - /// # - /// info!("This will be logged to stderr"); - /// reload_handle.modify(|layer| *layer.inner_mut().writer_mut() = non_blocking(std::io::stdout())); - /// info!("This will be logged to stdout"); - /// # } - /// ``` - /// - /// [subscriber]: Subscribe - pub fn inner_mut(&mut self) -> &mut L { - &mut self.layer - } -} - -impl Layer for Filtered -where - S: Subscriber + for<'span> registry::LookupSpan<'span> + 'static, - F: layer::Filter + 'static, - L: Layer, -{ - fn on_layer(&mut self, subscriber: &mut S) { - self.id = MagicPlfDowncastMarker(subscriber.register_filter()); - self.layer.on_layer(subscriber); - } - - // TODO(eliza): can we figure out a nice way to make the `Filtered` layer - // not call `is_enabled_for` in hooks that the inner layer doesn't actually - // have real implementations of? probably not... - // - // it would be cool if there was some wild rust reflection way of checking - // if a trait impl has the default impl of a trait method or not, but that's - // almsot certainly impossible...right? - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - let interest = self.filter.callsite_enabled(metadata); - - // If the filter didn't disable the callsite, allow the inner layer to - // register it — since `register_callsite` is also used for purposes - // such as reserving/caching per-callsite data, we want the inner layer - // to be able to perform any other registration steps. However, we'll - // ignore its `Interest`. - if !interest.is_never() { - self.layer.register_callsite(metadata); - } - - // Add our `Interest` to the current sum of per-layer filter `Interest`s - // for this callsite. - FILTERING.with(|filtering| filtering.add_interest(interest)); - - // don't short circuit! if the stack consists entirely of `Layer`s with - // per-layer filters, the `Registry` will return the actual `Interest` - // value that's the sum of all the `register_callsite` calls to those - // per-layer filters. if we returned an actual `never` interest here, a - // `Layered` layer would short-circuit and not allow any `Filtered` - // layers below us if _they_ are interested in the callsite. - Interest::always() - } - - fn enabled(&self, metadata: &Metadata<'_>, cx: Context<'_, S>) -> bool { - let cx = cx.with_filter(self.id()); - let enabled = self.filter.enabled(metadata, &cx); - FILTERING.with(|filtering| filtering.set(self.id(), enabled)); - - if enabled { - // If the filter enabled this metadata, ask the wrapped layer if - // _it_ wants it --- it might have a global filter. - self.layer.enabled(metadata, cx) - } else { - // Otherwise, return `true`. The _per-layer_ filter disabled this - // metadata, but returning `false` in `Layer::enabled` will - // short-circuit and globally disable the span or event. This is - // *not* what we want for per-layer filters, as other layers may - // still want this event. Returning `true` here means we'll continue - // asking the next layer in the stack. - // - // Once all per-layer filters have been evaluated, the `Registry` - // at the root of the stack will return `false` from its `enabled` - // method if *every* per-layer filter disabled this metadata. - // Otherwise, the individual per-layer filters will skip the next - // `new_span` or `on_event` call for their layer if *they* disabled - // the span or event, but it was not globally disabled. - true - } - } - - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, cx: Context<'_, S>) { - self.did_enable(|| { - let cx = cx.with_filter(self.id()); - self.filter.on_new_span(attrs, id, cx.clone()); - self.layer.on_new_span(attrs, id, cx); - }) - } - - #[doc(hidden)] - fn max_level_hint(&self) -> Option { - self.filter.max_level_hint() - } - - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, cx: Context<'_, S>) { - if let Some(cx) = cx.if_enabled_for(span, self.id()) { - self.filter.on_record(span, values, cx.clone()); - self.layer.on_record(span, values, cx) - } - } - - fn on_follows_from(&self, span: &span::Id, follows: &span::Id, cx: Context<'_, S>) { - // only call `on_follows_from` if both spans are enabled by us - if cx.is_enabled_for(span, self.id()) && cx.is_enabled_for(follows, self.id()) { - self.layer - .on_follows_from(span, follows, cx.with_filter(self.id())) - } - } - - fn on_event(&self, event: &Event<'_>, cx: Context<'_, S>) { - self.did_enable(|| { - self.layer.on_event(event, cx.with_filter(self.id())); - }) - } - - fn on_enter(&self, id: &span::Id, cx: Context<'_, S>) { - if let Some(cx) = cx.if_enabled_for(id, self.id()) { - self.filter.on_enter(id, cx.clone()); - self.layer.on_enter(id, cx); - } - } - - fn on_exit(&self, id: &span::Id, cx: Context<'_, S>) { - if let Some(cx) = cx.if_enabled_for(id, self.id()) { - self.filter.on_exit(id, cx.clone()); - self.layer.on_exit(id, cx); - } - } - - fn on_close(&self, id: span::Id, cx: Context<'_, S>) { - if let Some(cx) = cx.if_enabled_for(&id, self.id()) { - self.filter.on_close(id.clone(), cx.clone()); - self.layer.on_close(id, cx); - } - } - - // XXX(eliza): the existence of this method still makes me sad... - fn on_id_change(&self, old: &span::Id, new: &span::Id, cx: Context<'_, S>) { - if let Some(cx) = cx.if_enabled_for(old, self.id()) { - self.layer.on_id_change(old, new, cx) - } - } - - #[doc(hidden)] - #[inline] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - match id { - id if id == TypeId::of::() => Some(self as *const _ as *const ()), - id if id == TypeId::of::() => Some(&self.layer as *const _ as *const ()), - id if id == TypeId::of::() => Some(&self.filter as *const _ as *const ()), - id if id == TypeId::of::() => { - Some(&self.id as *const _ as *const ()) - } - _ => self.layer.downcast_raw(id), - } - } -} - -impl fmt::Debug for Filtered -where - F: fmt::Debug, - L: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Filtered") - .field("filter", &self.filter) - .field("layer", &self.layer) - .field("id", &self.id) - .finish() - } -} - -// === impl FilterId === - -impl FilterId { - const fn disabled() -> Self { - Self(std::u64::MAX) - } - - /// Returns a `FilterId` that will consider _all_ spans enabled. - pub(crate) const fn none() -> Self { - Self(0) - } - - pub(crate) fn new(id: u8) -> Self { - assert!(id < 64, "filter IDs may not be greater than 64"); - Self(1 << id as usize) - } - - /// Combines two `FilterId`s, returning a new `FilterId` that will match a - /// [`FilterMap`] where the span was disabled by _either_ this `FilterId` - /// *or* the combined `FilterId`. - /// - /// This method is called by [`Context`]s when adding the `FilterId` of a - /// [`Filtered`] layer to the context. - /// - /// This is necessary for cases where we have a tree of nested [`Filtered`] - /// layers, like this: - /// - /// ```text - /// Filtered { - /// filter1, - /// Layered { - /// layer1, - /// Filtered { - /// filter2, - /// layer2, - /// }, - /// } - /// ``` - /// - /// We want `layer2` to be affected by both `filter1` _and_ `filter2`. - /// Without combining `FilterId`s, this works fine when filtering - /// `on_event`/`new_span`, because the outer `Filtered` layer (`filter1`) - /// won't call the inner layer's `on_event` or `new_span` callbacks if it - /// disabled the event/span. - /// - /// However, it _doesn't_ work when filtering span lookups and traversals - /// (e.g. `scope`). This is because the [`Context`] passed to `layer2` - /// would set its filter ID to the filter ID of `filter2`, and would skip - /// spans that were disabled by `filter2`. However, what if a span was - /// disabled by `filter1`? We wouldn't see it in `new_span`, but we _would_ - /// see it in lookups and traversals...which we don't want. - /// - /// When a [`Filtered`] layer adds its ID to a [`Context`], it _combines_ it - /// with any previous filter ID that the context had, rather than replacing - /// it. That way, `layer2`'s context will check if a span was disabled by - /// `filter1` _or_ `filter2`. The way we do this, instead of representing - /// `FilterId`s as a number number that we shift a 1 over by to get a mask, - /// we just store the actual mask,so we can combine them with a bitwise-OR. - /// - /// For example, if we consider the following case (pretending that the - /// masks are 8 bits instead of 64 just so i don't have to write out a bunch - /// of extra zeroes): - /// - /// - `filter1` has the filter id 1 (`0b0000_0001`) - /// - `filter2` has the filter id 2 (`0b0000_0010`) - /// - /// A span that gets disabled by filter 1 would have the [`FilterMap`] with - /// bits `0b0000_0001`. - /// - /// If the `FilterId` was internally represented as `(bits to shift + 1), - /// when `layer2`'s [`Context`] checked if it enabled the span, it would - /// make the mask `0b0000_0010` (`1 << 1`). That bit would not be set in the - /// [`FilterMap`], so it would see that it _didn't_ disable the span. Which - /// is *true*, it just doesn't reflect the tree-like shape of the actual - /// subscriber. - /// - /// By having the IDs be masks instead of shifts, though, when the - /// [`Filtered`] with `filter2` gets the [`Context`] with `filter1`'s filter ID, - /// instead of replacing it, it ors them together: - /// - /// ```ignore - /// 0b0000_0001 | 0b0000_0010 == 0b0000_0011; - /// ``` - /// - /// We then test if the span was disabled by seeing if _any_ bits in the - /// mask are `1`: - /// - /// ```ignore - /// filtermap & mask != 0; - /// 0b0000_0001 & 0b0000_0011 != 0; - /// 0b0000_0001 != 0; - /// true; - /// ``` - /// - /// [`Context`]: crate::layer::Context - pub(crate) fn and(self, FilterId(other): Self) -> Self { - // If this mask is disabled, just return the other --- otherwise, we - // would always see that every span is disabled. - if self.0 == Self::disabled().0 { - return Self(other); - } - - Self(self.0 | other) - } - - fn is_disabled(self) -> bool { - self.0 == Self::disabled().0 - } -} - -impl fmt::Debug for FilterId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // don't print a giant set of the numbers 0..63 if the filter ID is disabled. - if self.0 == Self::disabled().0 { - return f - .debug_tuple("FilterId") - .field(&format_args!("DISABLED")) - .finish(); - } - - if f.alternate() { - f.debug_struct("FilterId") - .field("ids", &format_args!("{:?}", FmtBitset(self.0))) - .field("bits", &format_args!("{:b}", self.0)) - .finish() - } else { - f.debug_tuple("FilterId").field(&FmtBitset(self.0)).finish() - } - } -} - -impl fmt::Binary for FilterId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("FilterId") - .field(&format_args!("{:b}", self.0)) - .finish() - } -} - -// === impl FilterExt === - -impl FilterExt for F where F: layer::Filter {} - -// === impl FilterMap === - -impl FilterMap { - pub(crate) fn set(self, FilterId(mask): FilterId, enabled: bool) -> Self { - if mask == std::u64::MAX { - return self; - } - - if enabled { - Self { - bits: self.bits & (!mask), - } - } else { - Self { - bits: self.bits | mask, - } - } - } - - #[inline] - pub(crate) fn is_enabled(self, FilterId(mask): FilterId) -> bool { - self.bits & mask == 0 - } - - #[inline] - pub(crate) fn any_enabled(self) -> bool { - self.bits != std::u64::MAX - } -} - -impl fmt::Debug for FilterMap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let alt = f.alternate(); - let mut s = f.debug_struct("FilterMap"); - s.field("disabled_by", &format_args!("{:?}", &FmtBitset(self.bits))); - - if alt { - s.field("bits", &format_args!("{:b}", self.bits)); - } - - s.finish() - } -} - -impl fmt::Binary for FilterMap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FilterMap") - .field("bits", &format_args!("{:b}", self.bits)) - .finish() - } -} - -// === impl FilterState === - -impl FilterState { - fn new() -> Self { - Self { - enabled: Cell::new(FilterMap::default()), - interest: RefCell::new(None), - - #[cfg(debug_assertions)] - counters: DebugCounters::default(), - } - } - - fn set(&self, filter: FilterId, enabled: bool) { - #[cfg(debug_assertions)] - { - let in_current_pass = self.counters.in_filter_pass.get(); - if in_current_pass == 0 { - debug_assert_eq!(self.enabled.get(), FilterMap::default()); - } - self.counters.in_filter_pass.set(in_current_pass + 1); - debug_assert_eq!( - self.counters.in_interest_pass.get(), - 0, - "if we are in or starting a filter pass, we must not be in an interest pass." - ) - } - - self.enabled.set(self.enabled.get().set(filter, enabled)) - } - - fn add_interest(&self, interest: Interest) { - let mut curr_interest = self.interest.borrow_mut(); - - #[cfg(debug_assertions)] - { - let in_current_pass = self.counters.in_interest_pass.get(); - if in_current_pass == 0 { - debug_assert!(curr_interest.is_none()); - } - self.counters.in_interest_pass.set(in_current_pass + 1); - } - - if let Some(curr_interest) = curr_interest.as_mut() { - if (curr_interest.is_always() && !interest.is_always()) - || (curr_interest.is_never() && !interest.is_never()) - { - *curr_interest = Interest::sometimes(); - } - // If the two interests are the same, do nothing. If the current - // interest is `sometimes`, stay sometimes. - } else { - *curr_interest = Some(interest); - } - } - - pub(crate) fn event_enabled() -> bool { - FILTERING - .try_with(|this| { - let enabled = this.enabled.get().any_enabled(); - #[cfg(debug_assertions)] - { - if this.counters.in_filter_pass.get() == 0 { - debug_assert_eq!(this.enabled.get(), FilterMap::default()); - } - - // Nothing enabled this event, we won't tick back down the - // counter in `did_enable`. Reset it. - if !enabled { - this.counters.in_filter_pass.set(0); - } - } - enabled - }) - .unwrap_or(true) - } - - /// Executes a closure if the filter with the provided ID did not disable - /// the current span/event. - /// - /// This is used to implement the `on_event` and `new_span` methods for - /// `Filtered`. - fn did_enable(&self, filter: FilterId, f: impl FnOnce()) { - let map = self.enabled.get(); - if map.is_enabled(filter) { - // If the filter didn't disable the current span/event, run the - // callback. - f(); - } else { - // Otherwise, if this filter _did_ disable the span or event - // currently being processed, clear its bit from this thread's - // `FilterState`. The bit has already been "consumed" by skipping - // this callback, and we need to ensure that the `FilterMap` for - // this thread is reset when the *next* `enabled` call occurs. - self.enabled.set(map.set(filter, true)); - } - #[cfg(debug_assertions)] - { - let in_current_pass = self.counters.in_filter_pass.get(); - if in_current_pass <= 1 { - debug_assert_eq!(self.enabled.get(), FilterMap::default()); - } - self.counters - .in_filter_pass - .set(in_current_pass.saturating_sub(1)); - debug_assert_eq!( - self.counters.in_interest_pass.get(), - 0, - "if we are in a filter pass, we must not be in an interest pass." - ) - } - } - - /// Clears the current in-progress filter state. - /// - /// This resets the [`FilterMap`] and current [`Interest`] as well as - /// clearing the debug counters. - pub(crate) fn clear_enabled() { - // Drop the `Result` returned by `try_with` --- if we are in the middle - // a panic and the thread-local has been torn down, that's fine, just - // ignore it ratehr than panicking. - let _ = FILTERING.try_with(|filtering| { - filtering.enabled.set(FilterMap::default()); - - #[cfg(debug_assertions)] - filtering.counters.in_filter_pass.set(0); - }); - } - - pub(crate) fn take_interest() -> Option { - FILTERING - .try_with(|filtering| { - #[cfg(debug_assertions)] - { - if filtering.counters.in_interest_pass.get() == 0 { - debug_assert!(filtering.interest.try_borrow().ok()?.is_none()); - } - filtering.counters.in_interest_pass.set(0); - } - filtering.interest.try_borrow_mut().ok()?.take() - }) - .ok()? - } - - pub(crate) fn filter_map(&self) -> FilterMap { - let map = self.enabled.get(); - #[cfg(debug_assertions)] - { - if self.counters.in_filter_pass.get() == 0 { - debug_assert_eq!(map, FilterMap::default()); - } - } - - map - } -} -/// This is a horrible and bad abuse of the downcasting system to expose -/// *internally* whether a layer has per-layer filtering, within -/// `tracing-subscriber`, without exposing a public API for it. -/// -/// If a `Layer` has per-layer filtering, it will downcast to a -/// `MagicPlfDowncastMarker`. Since layers which contain other layers permit -/// downcasting to recurse to their children, this will do the Right Thing with -/// layers like Reload, Option, etc. -/// -/// Why is this a wrapper around the `FilterId`, you may ask? Because -/// downcasting works by returning a pointer, and we don't want to risk -/// introducing UB by constructing pointers that _don't_ point to a valid -/// instance of the type they claim to be. In this case, we don't _intend_ for -/// this pointer to be dereferenced, so it would actually be fine to return one -/// that isn't a valid pointer...but we can't guarantee that the caller won't -/// (accidentally) dereference it, so it's better to be safe than sorry. We -/// could, alternatively, add an additional field to the type that's used only -/// for returning pointers to as as part of the evil downcasting hack, but I -/// thought it was nicer to just add a `repr(transparent)` wrapper to the -/// existing `FilterId` field, since it won't make the struct any bigger. -/// -/// Don't worry, this isn't on the test. :) -#[derive(Clone, Copy)] -#[repr(transparent)] -struct MagicPlfDowncastMarker(FilterId); -impl fmt::Debug for MagicPlfDowncastMarker { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Just pretend that `MagicPlfDowncastMarker` doesn't exist for - // `fmt::Debug` purposes...if no one *sees* it in their `Debug` output, - // they don't have to know I thought this code would be a good idea. - fmt::Debug::fmt(&self.0, f) - } -} - -pub(crate) fn is_plf_downcast_marker(type_id: TypeId) -> bool { - type_id == TypeId::of::() -} - -/// Does a type implementing `Subscriber` contain any per-layer filters? -pub(crate) fn subscriber_has_plf(subscriber: &S) -> bool -where - S: Subscriber, -{ - (subscriber as &dyn Subscriber).is::() -} - -/// Does a type implementing `Layer` contain any per-layer filters? -pub(crate) fn layer_has_plf(layer: &L) -> bool -where - L: Layer, - S: Subscriber, -{ - unsafe { - // Safety: we're not actually *doing* anything with this pointer --- we - // only care about the `Option`, which we're turning into a `bool`. So - // even if the layer decides to be evil and give us some kind of invalid - // pointer, we don't ever dereference it, so this is always safe. - layer.downcast_raw(TypeId::of::()) - } - .is_some() -} - -struct FmtBitset(u64); - -impl fmt::Debug for FmtBitset { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut set = f.debug_set(); - for bit in 0..64 { - // if the `bit`-th bit is set, add it to the debug set - if self.0 & (1 << bit) != 0 { - set.entry(&bit); - } - } - set.finish() - } -} diff --git a/vendor/tracing-subscriber/src/filter/level.rs b/vendor/tracing-subscriber/src/filter/level.rs deleted file mode 100644 index 0fa601260..000000000 --- a/vendor/tracing-subscriber/src/filter/level.rs +++ /dev/null @@ -1,27 +0,0 @@ -use tracing_core::{ - subscriber::{Interest, Subscriber}, - Metadata, -}; - -#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 -pub use tracing_core::metadata::{LevelFilter, ParseLevelFilterError as ParseError}; - -// === impl LevelFilter === - -impl crate::Layer for LevelFilter { - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - if self >= metadata.level() { - Interest::always() - } else { - Interest::never() - } - } - - fn enabled(&self, metadata: &Metadata<'_>, _: crate::layer::Context<'_, S>) -> bool { - self >= metadata.level() - } - - fn max_level_hint(&self) -> Option { - Some(*self) - } -} diff --git a/vendor/tracing-subscriber/src/filter/mod.rs b/vendor/tracing-subscriber/src/filter/mod.rs deleted file mode 100644 index 000a27195..000000000 --- a/vendor/tracing-subscriber/src/filter/mod.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! [`Layer`]s that control which spans and events are enabled by the wrapped -//! subscriber. -//! -//! This module contains a number of types that provide implementations of -//! various strategies for filtering which spans and events are enabled. For -//! details on filtering spans and events using [`Layer`]s, see the -//! [`layer` module's documentation]. -//! -//! [`layer` module's documentation]: crate::layer#filtering-with-layers -//! [`Layer`]: crate::layer -mod filter_fn; - -feature! { - #![all(feature = "env-filter", feature = "std")] - mod env; - pub use self::env::*; -} - -feature! { - #![all(feature = "registry", feature = "std")] - mod layer_filters; - pub use self::layer_filters::*; -} - -mod level; - -pub use self::filter_fn::*; -pub use self::level::{LevelFilter, ParseError as LevelParseError}; - -#[cfg(not(all(feature = "registry", feature = "std")))] -pub(crate) use self::has_plf_stubs::*; - -feature! { - #![any(feature = "std", feature = "alloc")] - pub mod targets; - pub use self::targets::Targets; - - mod directive; - pub use self::directive::ParseError; -} - -/// Stub implementations of the per-layer-fitler detection functions for when the -/// `registry` feature is disabled. -#[cfg(not(all(feature = "registry", feature = "std")))] -mod has_plf_stubs { - pub(crate) fn is_plf_downcast_marker(_: core::any::TypeId) -> bool { - false - } - - /// Does a type implementing `Subscriber` contain any per-layer filters? - pub(crate) fn subscriber_has_plf(_: &S) -> bool - where - S: tracing_core::Subscriber, - { - false - } - - /// Does a type implementing `Layer` contain any per-layer filters? - pub(crate) fn layer_has_plf(_: &L) -> bool - where - L: crate::Layer, - S: tracing_core::Subscriber, - { - false - } -} diff --git a/vendor/tracing-subscriber/src/filter/targets.rs b/vendor/tracing-subscriber/src/filter/targets.rs deleted file mode 100644 index 2a30d2db6..000000000 --- a/vendor/tracing-subscriber/src/filter/targets.rs +++ /dev/null @@ -1,710 +0,0 @@ -//! A [filter] that enables or disables spans and events based on their [target] and [level]. -//! -//! See [`Targets`] for details. -//! -//! [target]: tracing_core::Metadata::target -//! [level]: tracing_core::Level -//! [filter]: crate::layer#filtering-with-layers - -use crate::{ - filter::{ - directive::{DirectiveSet, ParseError, StaticDirective}, - LevelFilter, - }, - layer, -}; -#[cfg(not(feature = "std"))] -use alloc::string::String; -use core::{ - iter::{Extend, FilterMap, FromIterator}, - slice, - str::FromStr, -}; -use tracing_core::{Interest, Level, Metadata, Subscriber}; - -/// A filter that enables or disables spans and events based on their [target] -/// and [level]. -/// -/// Targets are typically equal to the Rust module path of the code where the -/// span or event was recorded, although they may be overridden. -/// -/// This type can be used for both [per-layer filtering][plf] (using its -/// [`Filter`] implementation) and [global filtering][global] (using its -/// [`Layer`] implementation). -/// -/// See the [documentation on filtering with layers][filtering] for details. -/// -/// # Filtering With `Targets` -/// -/// A `Targets` filter consists of one or more [target] prefixes, paired with -/// [`LevelFilter`]s. If a span or event's [target] begins with one of those -/// prefixes, and its [level] is at or below the [`LevelFilter`] enabled for -/// that prefix, then the span or event will be enabled. -/// -/// This is similar to the behavior implemented by the [`env_logger` crate] in -/// the `log` ecosystem. -/// -/// The [`EnvFilter`] type also provided by this crate is very similar to `Targets`, -/// but is capable of a more sophisticated form of filtering where events may -/// also be enabled or disabled based on the span they are recorded in. -/// `Targets` can be thought of as a lighter-weight form of [`EnvFilter`] that -/// can be used instead when this dynamic filtering is not required. -/// -/// # Examples -/// -/// A `Targets` filter can be constructed by programmatically adding targets and -/// levels to enable: -/// -/// ``` -/// use tracing_subscriber::{filter, prelude::*}; -/// use tracing_core::Level; -/// -/// let filter = filter::Targets::new() -/// // Enable the `INFO` level for anything in `my_crate` -/// .with_target("my_crate", Level::INFO) -/// // Enable the `DEBUG` level for a specific module. -/// .with_target("my_crate::interesting_module", Level::DEBUG); -/// -/// // Build a new subscriber with the `fmt` layer using the `Targets` -/// // filter we constructed above. -/// tracing_subscriber::registry() -/// .with(tracing_subscriber::fmt::layer()) -/// .with(filter) -/// .init(); -/// ``` -/// -/// [`LevelFilter::OFF`] can be used to disable a particular target: -/// ``` -/// use tracing_subscriber::filter::{Targets, LevelFilter}; -/// use tracing_core::Level; -/// -/// let filter = Targets::new() -/// .with_target("my_crate", Level::INFO) -/// // Disable all traces from `annoying_module`. -/// .with_target("my_crate::annoying_module", LevelFilter::OFF); -/// # drop(filter); -/// ``` -/// -/// Alternatively, `Targets` implements [`std::str::FromStr`], allowing it to be -/// parsed from a comma-delimited list of `target=level` pairs. For example: -/// -/// ```rust -/// # fn main() -> Result<(), Box> { -/// use tracing_subscriber::filter; -/// use tracing_core::Level; -/// -/// let filter = "my_crate=info,my_crate::interesting_module=trace,other_crate=debug" -/// .parse::()?; -/// -/// // The parsed filter is identical to a filter constructed using `with_target`: -/// assert_eq!( -/// filter, -/// filter::Targets::new() -/// .with_target("my_crate", Level::INFO) -/// .with_target("my_crate::interesting_module", Level::TRACE) -/// .with_target("other_crate", Level::DEBUG) -/// ); -/// # Ok(()) } -/// ``` -/// -/// This is particularly useful when the list of enabled targets is configurable -/// by the user at runtime. -/// -/// The `Targets` filter can be used as a [per-layer filter][plf] *and* as a -/// [global filter][global]: -/// -/// ```rust -/// use tracing_subscriber::{ -/// fmt, -/// filter::{Targets, LevelFilter}, -/// prelude::*, -/// }; -/// use tracing_core::Level; -/// use std::{sync::Arc, fs::File}; -/// # fn docs() -> Result<(), Box> { -/// -/// // A layer that logs events to stdout using the human-readable "pretty" -/// // format. -/// let stdout_log = fmt::layer().pretty(); -/// -/// // A layer that logs events to a file, using the JSON format. -/// let file = File::create("debug_log.json")?; -/// let debug_log = fmt::layer() -/// .with_writer(Arc::new(file)) -/// .json(); -/// -/// tracing_subscriber::registry() -/// // Only log INFO and above to stdout, unless the span or event -/// // has the `my_crate::cool_module` target prefix. -/// .with(stdout_log -/// .with_filter( -/// Targets::default() -/// .with_target("my_crate::cool_module", Level::DEBUG) -/// .with_default(Level::INFO) -/// ) -/// ) -/// // Log everything enabled by the global filter to `debug_log.json`. -/// .with(debug_log) -/// // Configure a global filter for the whole subscriber stack. This will -/// // control what spans and events are recorded by both the `debug_log` -/// // and the `stdout_log` layers, and `stdout_log` will *additionally* be -/// // filtered by its per-layer filter. -/// .with( -/// Targets::default() -/// .with_target("my_crate", Level::TRACE) -/// .with_target("other_crate", Level::INFO) -/// .with_target("other_crate::annoying_module", LevelFilter::OFF) -/// .with_target("third_crate", Level::DEBUG) -/// ).init(); -/// # Ok(()) } -///``` -/// -/// [target]: tracing_core::Metadata::target -/// [level]: tracing_core::Level -/// [`Filter`]: crate::layer::Filter -/// [`Layer`]: crate::layer::Layer -/// [plf]: crate::layer#per-layer-filtering -/// [global]: crate::layer#global-filtering -/// [filtering]: crate::layer#filtering-with-layers -/// [`env_logger` crate]: https://docs.rs/env_logger/0.9.0/env_logger/index.html#enabling-logging -/// [`EnvFilter`]: crate::filter::EnvFilter -#[derive(Debug, Default, Clone, PartialEq)] -pub struct Targets(DirectiveSet); - -impl Targets { - /// Returns a new `Targets` filter. - /// - /// This filter will enable no targets. Call [`with_target`] or [`with_targets`] - /// to add enabled targets, and [`with_default`] to change the default level - /// enabled for spans and events that didn't match any of the provided targets. - /// - /// [`with_target`]: Targets::with_target - /// [`with_targets`]: Targets::with_targets - /// [`with_default`]: Targets::with_default - pub fn new() -> Self { - Self::default() - } - - /// Enables spans and events with [target]s starting with the provided target - /// prefix if they are at or below the provided [`LevelFilter`]. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter; - /// use tracing_core::Level; - /// - /// let filter = filter::Targets::new() - /// // Enable the `INFO` level for anything in `my_crate` - /// .with_target("my_crate", Level::INFO) - /// // Enable the `DEBUG` level for a specific module. - /// .with_target("my_crate::interesting_module", Level::DEBUG); - /// # drop(filter); - /// ``` - /// - /// [`LevelFilter::OFF`] can be used to disable a particular target: - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// // Disable all traces from `annoying_module`. - /// .with_target("my_crate::interesting_module", LevelFilter::OFF); - /// # drop(filter); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - pub fn with_target(mut self, target: impl Into, level: impl Into) -> Self { - self.0.add(StaticDirective::new( - Some(target.into()), - Default::default(), - level.into(), - )); - self - } - /// Adds [target]s from an iterator of [target]-[`LevelFilter`] pairs to this filter. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter; - /// use tracing_core::Level; - /// - /// let filter = filter::Targets::new() - /// .with_targets(vec![ - /// ("my_crate", Level::INFO), - /// ("my_crate::some_module", Level::DEBUG), - /// ("my_crate::other_module::cool_stuff", Level::TRACE), - /// ("other_crate", Level::WARN) - /// ]); - /// # drop(filter); - /// ``` - /// - /// [`LevelFilter::OFF`] can be used to disable a particular target: - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// // Disable all traces from `annoying_module`. - /// .with_target("my_crate::interesting_module", LevelFilter::OFF); - /// # drop(filter); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - pub fn with_targets(mut self, targets: impl IntoIterator) -> Self - where - String: From, - LevelFilter: From, - { - self.extend(targets); - self - } - - /// Sets the default level to enable for spans and events whose targets did - /// not match any of the configured prefixes. - /// - /// By default, this is [`LevelFilter::OFF`]. This means that spans and - /// events will only be enabled if they match one of the configured target - /// prefixes. If this is changed to a different [`LevelFilter`], spans and - /// events with targets that did not match any of the configured prefixes - /// will be enabled if their level is at or below the provided level. - pub fn with_default(mut self, level: impl Into) -> Self { - self.0 - .add(StaticDirective::new(None, Default::default(), level.into())); - self - } - - /// Returns an iterator over the [target]-[`LevelFilter`] pairs in this filter. - /// - /// The order of iteration is undefined. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// .with_target("my_crate::interesting_module", Level::DEBUG); - /// - /// let mut targets: Vec<_> = filter.iter().collect(); - /// targets.sort(); - /// - /// assert_eq!(targets, vec![ - /// ("my_crate", LevelFilter::INFO), - /// ("my_crate::interesting_module", LevelFilter::DEBUG), - /// ]); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - pub fn iter(&self) -> Iter<'_> { - self.into_iter() - } - - #[inline] - fn interested(&self, metadata: &'static Metadata<'static>) -> Interest { - if self.0.enabled(metadata) { - Interest::always() - } else { - Interest::never() - } - } - - /// Returns whether a [target]-[`Level`] pair would be enabled - /// by this `Targets`. - /// - /// This method can be used with [`module_path!`] from `std` as the target - /// in order to emulate the behavior of the [`tracing::event!`] and [`tracing::span!`] - /// macros. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::filter::{Targets, LevelFilter}; - /// use tracing_core::Level; - /// - /// let filter = Targets::new() - /// .with_target("my_crate", Level::INFO) - /// .with_target("my_crate::interesting_module", Level::DEBUG); - /// - /// assert!(filter.would_enable("my_crate", &Level::INFO)); - /// assert!(!filter.would_enable("my_crate::interesting_module", &Level::TRACE)); - /// ``` - /// - /// [target]: tracing_core::Metadata::target - /// [`module_path!`]: std::module_path! - pub fn would_enable(&self, target: &str, level: &Level) -> bool { - // "Correct" to call because `Targets` only produces `StaticDirective`'s with NO - // fields - self.0.target_enabled(target, level) - } -} - -impl Extend<(T, L)> for Targets -where - T: Into, - L: Into, -{ - fn extend>(&mut self, iter: I) { - let iter = iter.into_iter().map(|(target, level)| { - StaticDirective::new(Some(target.into()), Default::default(), level.into()) - }); - self.0.extend(iter); - } -} - -impl FromIterator<(T, L)> for Targets -where - T: Into, - L: Into, -{ - fn from_iter>(iter: I) -> Self { - let mut this = Self::default(); - this.extend(iter); - this - } -} - -impl FromStr for Targets { - type Err = ParseError; - fn from_str(s: &str) -> Result { - s.split(',') - .map(StaticDirective::from_str) - .collect::>() - .map(Self) - } -} - -impl layer::Layer for Targets -where - S: Subscriber, -{ - fn enabled(&self, metadata: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { - self.0.enabled(metadata) - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.interested(metadata) - } - - fn max_level_hint(&self) -> Option { - Some(self.0.max_level) - } -} - -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(feature = "registry")))] -impl layer::Filter for Targets { - fn enabled(&self, metadata: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool { - self.0.enabled(metadata) - } - - fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - self.interested(metadata) - } - - fn max_level_hint(&self) -> Option { - Some(self.0.max_level) - } -} - -impl IntoIterator for Targets { - type Item = (String, LevelFilter); - - type IntoIter = IntoIter; - - fn into_iter(self) -> Self::IntoIter { - IntoIter::new(self) - } -} - -impl<'a> IntoIterator for &'a Targets { - type Item = (&'a str, LevelFilter); - - type IntoIter = Iter<'a>; - - fn into_iter(self) -> Self::IntoIter { - Iter::new(self) - } -} - -/// An owning iterator over the [target]-[level] pairs of a `Targets` filter. -/// -/// This struct is created by the `IntoIterator` trait implementation of [`Targets`]. -/// -/// # Examples -/// -/// Merge the targets from one `Targets` with another: -/// -/// ``` -/// use tracing_subscriber::filter::Targets; -/// use tracing_core::Level; -/// -/// let mut filter = Targets::new().with_target("my_crate", Level::INFO); -/// let overrides = Targets::new().with_target("my_crate::interesting_module", Level::DEBUG); -/// -/// filter.extend(overrides); -/// # drop(filter); -/// ``` -/// -/// [target]: tracing_core::Metadata::target -/// [level]: tracing_core::Level -#[derive(Debug)] -pub struct IntoIter( - #[allow(clippy::type_complexity)] // alias indirection would probably make this more confusing - FilterMap< - as IntoIterator>::IntoIter, - fn(StaticDirective) -> Option<(String, LevelFilter)>, - >, -); - -impl IntoIter { - fn new(targets: Targets) -> Self { - Self(targets.0.into_iter().filter_map(|directive| { - let level = directive.level; - directive.target.map(|target| (target, level)) - })) - } -} - -impl Iterator for IntoIter { - type Item = (String, LevelFilter); - - fn next(&mut self) -> Option { - self.0.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} - -/// A borrowing iterator over the [target]-[level] pairs of a `Targets` filter. -/// -/// This struct is created by [`iter`] method of [`Targets`], or from the `IntoIterator` -/// implementation for `&Targets`. -/// -/// [target]: tracing_core::Metadata::target -/// [level]: tracing_core::Level -/// [`iter`]: Targets::iter -#[derive(Debug)] -pub struct Iter<'a>( - FilterMap< - slice::Iter<'a, StaticDirective>, - fn(&'a StaticDirective) -> Option<(&'a str, LevelFilter)>, - >, -); - -impl<'a> Iter<'a> { - fn new(targets: &'a Targets) -> Self { - Self(targets.0.iter().filter_map(|directive| { - directive - .target - .as_deref() - .map(|target| (target, directive.level)) - })) - } -} - -impl<'a> Iterator for Iter<'a> { - type Item = (&'a str, LevelFilter); - - fn next(&mut self) -> Option { - self.0.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - feature! { - #![not(feature = "std")] - use alloc::{vec, vec::Vec, string::ToString}; - - // `dbg!` is only available with `libstd`; just nop it out when testing - // with alloc only. - macro_rules! dbg { - ($x:expr) => { $x } - } - } - - fn expect_parse(s: &str) -> Targets { - match dbg!(s).parse::() { - Err(e) => panic!("string {:?} did not parse successfully: {}", s, e), - Ok(e) => e, - } - } - - fn expect_parse_ralith(s: &str) { - let dirs = expect_parse(s).0.into_vec(); - assert_eq!(dirs.len(), 2, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("server".to_string())); - assert_eq!(dirs[0].level, LevelFilter::DEBUG); - assert_eq!(dirs[0].field_names, Vec::::new()); - - assert_eq!(dirs[1].target, Some("common".to_string())); - assert_eq!(dirs[1].level, LevelFilter::INFO); - assert_eq!(dirs[1].field_names, Vec::::new()); - } - - fn expect_parse_level_directives(s: &str) { - let dirs = expect_parse(s).0.into_vec(); - assert_eq!(dirs.len(), 6, "\nparsed: {:#?}", dirs); - - assert_eq!(dirs[0].target, Some("crate3::mod2::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::OFF); - assert_eq!(dirs[0].field_names, Vec::::new()); - - assert_eq!(dirs[1].target, Some("crate1::mod2::mod3".to_string())); - assert_eq!(dirs[1].level, LevelFilter::INFO); - assert_eq!(dirs[1].field_names, Vec::::new()); - - assert_eq!(dirs[2].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[2].level, LevelFilter::WARN); - assert_eq!(dirs[2].field_names, Vec::::new()); - - assert_eq!(dirs[3].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[3].level, LevelFilter::ERROR); - assert_eq!(dirs[3].field_names, Vec::::new()); - - assert_eq!(dirs[4].target, Some("crate3".to_string())); - assert_eq!(dirs[4].level, LevelFilter::TRACE); - assert_eq!(dirs[4].field_names, Vec::::new()); - - assert_eq!(dirs[5].target, Some("crate2".to_string())); - assert_eq!(dirs[5].level, LevelFilter::DEBUG); - assert_eq!(dirs[5].field_names, Vec::::new()); - } - - #[test] - fn parse_ralith() { - expect_parse_ralith("common=info,server=debug"); - } - - #[test] - fn parse_ralith_uc() { - expect_parse_ralith("common=INFO,server=DEBUG"); - } - - #[test] - fn parse_ralith_mixed() { - expect_parse("common=iNfo,server=dEbUg"); - } - - #[test] - fn expect_parse_valid() { - let dirs = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") - .0 - .into_vec(); - assert_eq!(dirs.len(), 4, "\nparsed: {:#?}", dirs); - assert_eq!(dirs[0].target, Some("crate1::mod2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::TRACE); - assert_eq!(dirs[0].field_names, Vec::::new()); - - assert_eq!(dirs[1].target, Some("crate1::mod1".to_string())); - assert_eq!(dirs[1].level, LevelFilter::ERROR); - assert_eq!(dirs[1].field_names, Vec::::new()); - - assert_eq!(dirs[2].target, Some("crate3".to_string())); - assert_eq!(dirs[2].level, LevelFilter::OFF); - assert_eq!(dirs[2].field_names, Vec::::new()); - - assert_eq!(dirs[3].target, Some("crate2".to_string())); - assert_eq!(dirs[3].level, LevelFilter::DEBUG); - assert_eq!(dirs[3].field_names, Vec::::new()); - } - - #[test] - fn parse_level_directives() { - expect_parse_level_directives( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off", - ) - } - - #[test] - fn parse_uppercase_level_directives() { - expect_parse_level_directives( - "crate1::mod1=ERROR,crate1::mod2=WARN,crate1::mod2::mod3=INFO,\ - crate2=DEBUG,crate3=TRACE,crate3::mod2::mod1=OFF", - ) - } - - #[test] - fn parse_numeric_level_directives() { - expect_parse_level_directives( - "crate1::mod1=1,crate1::mod2=2,crate1::mod2::mod3=3,crate2=4,\ - crate3=5,crate3::mod2::mod1=0", - ) - } - - #[test] - fn targets_iter() { - let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") - .with_default(LevelFilter::WARN); - - let mut targets: Vec<_> = filter.iter().collect(); - targets.sort(); - - assert_eq!( - targets, - vec![ - ("crate1::mod1", LevelFilter::ERROR), - ("crate1::mod2", LevelFilter::TRACE), - ("crate2", LevelFilter::DEBUG), - ("crate3", LevelFilter::OFF), - ] - ); - } - - #[test] - fn targets_into_iter() { - let filter = expect_parse("crate1::mod1=error,crate1::mod2,crate2=debug,crate3=off") - .with_default(LevelFilter::WARN); - - let mut targets: Vec<_> = filter.into_iter().collect(); - targets.sort(); - - assert_eq!( - targets, - vec![ - ("crate1::mod1".to_string(), LevelFilter::ERROR), - ("crate1::mod2".to_string(), LevelFilter::TRACE), - ("crate2".to_string(), LevelFilter::DEBUG), - ("crate3".to_string(), LevelFilter::OFF), - ] - ); - } - - #[test] - // `println!` is only available with `libstd`. - #[cfg(feature = "std")] - fn size_of_filters() { - fn print_sz(s: &str) { - let filter = s.parse::().expect("filter should parse"); - println!( - "size_of_val({:?})\n -> {}B", - s, - std::mem::size_of_val(&filter) - ); - } - - print_sz("info"); - - print_sz("foo=debug"); - - print_sz( - "crate1::mod1=error,crate1::mod2=warn,crate1::mod2::mod3=info,\ - crate2=debug,crate3=trace,crate3::mod2::mod1=off", - ); - } -} diff --git a/vendor/tracing-subscriber/src/fmt/fmt_layer.rs b/vendor/tracing-subscriber/src/fmt/fmt_layer.rs deleted file mode 100644 index 21992e780..000000000 --- a/vendor/tracing-subscriber/src/fmt/fmt_layer.rs +++ /dev/null @@ -1,1368 +0,0 @@ -use crate::{ - field::RecordFields, - fmt::{format, FormatEvent, FormatFields, MakeWriter, TestWriter}, - layer::{self, Context}, - registry::{self, LookupSpan, SpanRef}, -}; -use format::{FmtSpan, TimingDisplay}; -use std::{any::TypeId, cell::RefCell, fmt, io, marker::PhantomData, ops::Deref, time::Instant}; -use tracing_core::{ - field, - span::{Attributes, Current, Id, Record}, - Event, Metadata, Subscriber, -}; - -/// A [`Layer`] that logs formatted representations of `tracing` events. -/// -/// ## Examples -/// -/// Constructing a layer with the default configuration: -/// -/// ```rust -/// use tracing_subscriber::{fmt, Registry}; -/// use tracing_subscriber::prelude::*; -/// -/// let subscriber = Registry::default() -/// .with(fmt::Layer::default()); -/// -/// tracing::subscriber::set_global_default(subscriber).unwrap(); -/// ``` -/// -/// Overriding the layer's behavior: -/// -/// ```rust -/// use tracing_subscriber::{fmt, Registry}; -/// use tracing_subscriber::prelude::*; -/// -/// let fmt_layer = fmt::layer() -/// .with_target(false) // don't include event targets when logging -/// .with_level(false); // don't include event levels when logging -/// -/// let subscriber = Registry::default().with(fmt_layer); -/// # tracing::subscriber::set_global_default(subscriber).unwrap(); -/// ``` -/// -/// Setting a custom event formatter: -/// -/// ```rust -/// use tracing_subscriber::fmt::{self, format, time}; -/// use tracing_subscriber::prelude::*; -/// -/// let fmt = format().with_timer(time::Uptime::default()); -/// let fmt_layer = fmt::layer() -/// .event_format(fmt) -/// .with_target(false); -/// # let subscriber = fmt_layer.with_subscriber(tracing_subscriber::registry::Registry::default()); -/// # tracing::subscriber::set_global_default(subscriber).unwrap(); -/// ``` -/// -/// [`Layer`]: super::layer::Layer -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -#[derive(Debug)] -pub struct Layer< - S, - N = format::DefaultFields, - E = format::Format, - W = fn() -> io::Stdout, -> { - make_writer: W, - fmt_fields: N, - fmt_event: E, - fmt_span: format::FmtSpanConfig, - is_ansi: bool, - _inner: PhantomData, -} - -impl Layer { - /// Returns a new [`Layer`][self::Layer] with the default configuration. - pub fn new() -> Self { - Self::default() - } -} - -// This needs to be a seperate impl block because they place different bounds on the type parameters. -impl Layer -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'writer> FormatFields<'writer> + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, -{ - /// Sets the [event formatter][`FormatEvent`] that the layer being built will - /// use to format events. - /// - /// The event formatter may be any type implementing the [`FormatEvent`] - /// trait, which is implemented for all functions taking a [`FmtContext`], a - /// [`Writer`], and an [`Event`]. - /// - /// # Examples - /// - /// Setting a type implementing [`FormatEvent`] as the formatter: - /// ```rust - /// use tracing_subscriber::fmt::{self, format}; - /// - /// let layer = fmt::layer() - /// .event_format(format().compact()); - /// # // this is necessary for type inference. - /// # use tracing_subscriber::Layer as _; - /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); - /// ``` - /// [`FormatEvent`]: format::FormatEvent - /// [`Event`]: tracing::Event - /// [`Writer`]: format::Writer - pub fn event_format(self, e: E2) -> Layer - where - E2: FormatEvent + 'static, - { - Layer { - fmt_fields: self.fmt_fields, - fmt_event: e, - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } - - /// Updates the event formatter by applying a function to the existing event formatter. - /// - /// This sets the event formatter that the layer being built will use to record fields. - /// - /// # Examples - /// - /// Updating an event formatter: - /// - /// ```rust - /// let layer = tracing_subscriber::fmt::layer() - /// .map_event_format(|e| e.compact()); - /// # // this is necessary for type inference. - /// # use tracing_subscriber::Layer as _; - /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); - /// ``` - pub fn map_event_format(self, f: impl FnOnce(E) -> E2) -> Layer - where - E2: FormatEvent + 'static, - { - Layer { - fmt_fields: self.fmt_fields, - fmt_event: f(self.fmt_event), - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } -} - -// This needs to be a seperate impl block because they place different bounds on the type parameters. -impl Layer { - /// Sets the [`MakeWriter`] that the layer being built will use to write events. - /// - /// # Examples - /// - /// Using `stderr` rather than `stdout`: - /// - /// ```rust - /// use std::io; - /// use tracing_subscriber::fmt; - /// - /// let layer = fmt::layer() - /// .with_writer(io::stderr); - /// # // this is necessary for type inference. - /// # use tracing_subscriber::Layer as _; - /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); - /// ``` - pub fn with_writer(self, make_writer: W2) -> Layer - where - W2: for<'writer> MakeWriter<'writer> + 'static, - { - Layer { - fmt_fields: self.fmt_fields, - fmt_event: self.fmt_event, - fmt_span: self.fmt_span, - is_ansi: self.is_ansi, - make_writer, - _inner: self._inner, - } - } - - /// Borrows the [writer] for this [`Layer`]. - /// - /// [writer]: MakeWriter - pub fn writer(&self) -> &W { - &self.make_writer - } - - /// Mutably borrows the [writer] for this [`Layer`]. - /// - /// This method is primarily expected to be used with the - /// [`reload::Handle::modify`](crate::reload::Handle::modify) method. - /// - /// # Examples - /// - /// ``` - /// # use tracing::info; - /// # use tracing_subscriber::{fmt,reload,Registry,prelude::*}; - /// # fn non_blocking(writer: T) -> (fn() -> std::io::Stdout) { - /// # std::io::stdout - /// # } - /// # fn main() { - /// let layer = fmt::layer().with_writer(non_blocking(std::io::stderr())); - /// let (layer, reload_handle) = reload::Layer::new(layer); - /// # - /// # // specifying the Registry type is required - /// # let _: &reload::Handle, Registry> = &reload_handle; - /// # - /// info!("This will be logged to stderr"); - /// reload_handle.modify(|layer| *layer.writer_mut() = non_blocking(std::io::stdout())); - /// info!("This will be logged to stdout"); - /// # } - /// ``` - /// - /// [writer]: MakeWriter - pub fn writer_mut(&mut self) -> &mut W { - &mut self.make_writer - } - - /// Sets whether this layer should use ANSI terminal formatting - /// escape codes (such as colors). - /// - /// This method is primarily expected to be used with the - /// [`reload::Handle::modify`](crate::reload::Handle::modify) method when changing - /// the writer. - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] - pub fn set_ansi(&mut self, ansi: bool) { - self.is_ansi = ansi; - } - - /// Configures the layer to support [`libtest`'s output capturing][capturing] when used in - /// unit tests. - /// - /// See [`TestWriter`] for additional details. - /// - /// # Examples - /// - /// Using [`TestWriter`] to let `cargo test` capture test output: - /// - /// ```rust - /// use std::io; - /// use tracing_subscriber::fmt; - /// - /// let layer = fmt::layer() - /// .with_test_writer(); - /// # // this is necessary for type inference. - /// # use tracing_subscriber::Layer as _; - /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); - /// ``` - /// [capturing]: - /// https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output - /// [`TestWriter`]: super::writer::TestWriter - pub fn with_test_writer(self) -> Layer { - Layer { - fmt_fields: self.fmt_fields, - fmt_event: self.fmt_event, - fmt_span: self.fmt_span, - is_ansi: self.is_ansi, - make_writer: TestWriter::default(), - _inner: self._inner, - } - } - - /// Enable ANSI terminal colors for formatted output. - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] - pub fn with_ansi(self, ansi: bool) -> Self { - Self { - is_ansi: ansi, - ..self - } - } - - /// Updates the [`MakeWriter`] by applying a function to the existing [`MakeWriter`]. - /// - /// This sets the [`MakeWriter`] that the layer being built will use to write events. - /// - /// # Examples - /// - /// Redirect output to stderr if level is <= WARN: - /// - /// ```rust - /// use tracing::Level; - /// use tracing_subscriber::fmt::{self, writer::MakeWriterExt}; - /// - /// let stderr = std::io::stderr.with_max_level(Level::WARN); - /// let layer = fmt::layer() - /// .map_writer(move |w| stderr.or_else(w)); - /// # // this is necessary for type inference. - /// # use tracing_subscriber::Layer as _; - /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); - /// ``` - pub fn map_writer(self, f: impl FnOnce(W) -> W2) -> Layer - where - W2: for<'writer> MakeWriter<'writer> + 'static, - { - Layer { - fmt_fields: self.fmt_fields, - fmt_event: self.fmt_event, - fmt_span: self.fmt_span, - is_ansi: self.is_ansi, - make_writer: f(self.make_writer), - _inner: self._inner, - } - } -} - -impl Layer, W> -where - N: for<'writer> FormatFields<'writer> + 'static, -{ - /// Use the given [`timer`] for span and event timestamps. - /// - /// See the [`time` module] for the provided timer implementations. - /// - /// Note that using the `"time`"" feature flag enables the - /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the - /// [`time` crate] to provide more sophisticated timestamp formatting - /// options. - /// - /// [`timer`]: super::time::FormatTime - /// [`time` module]: mod@super::time - /// [`UtcTime`]: super::time::UtcTime - /// [`LocalTime`]: super::time::LocalTime - /// [`time` crate]: https://docs.rs/time/0.3 - pub fn with_timer(self, timer: T2) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_timer(timer), - fmt_fields: self.fmt_fields, - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } - - /// Do not emit timestamps with spans and event. - pub fn without_time(self) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.without_time(), - fmt_fields: self.fmt_fields, - fmt_span: self.fmt_span.without_time(), - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } - - /// Configures how synthesized events are emitted at points in the [span - /// lifecycle][lifecycle]. - /// - /// The following options are available: - /// - /// - `FmtSpan::NONE`: No events will be synthesized when spans are - /// created, entered, exited, or closed. Data from spans will still be - /// included as the context for formatted events. This is the default. - /// - `FmtSpan::NEW`: An event will be synthesized when spans are created. - /// - `FmtSpan::ENTER`: An event will be synthesized when spans are entered. - /// - `FmtSpan::EXIT`: An event will be synthesized when spans are exited. - /// - `FmtSpan::CLOSE`: An event will be synthesized when a span closes. If - /// [timestamps are enabled][time] for this formatter, the generated - /// event will contain fields with the span's _busy time_ (the total - /// time for which it was entered) and _idle time_ (the total time that - /// the span existed but was not entered). - /// - `FmtSpan::ACTIVE`: Events will be synthesized when spans are entered - /// or exited. - /// - `FmtSpan::FULL`: Events will be synthesized whenever a span is - /// created, entered, exited, or closed. If timestamps are enabled, the - /// close event will contain the span's busy and idle time, as - /// described above. - /// - /// The options can be enabled in any combination. For instance, the following - /// will synthesize events whenever spans are created and closed: - /// - /// ```rust - /// use tracing_subscriber::fmt; - /// use tracing_subscriber::fmt::format::FmtSpan; - /// - /// let subscriber = fmt() - /// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) - /// .finish(); - /// ``` - /// - /// Note that the generated events will only be part of the log output by - /// this formatter; they will not be recorded by other `Subscriber`s or by - /// `Layer`s added to this subscriber. - /// - /// [lifecycle]: https://docs.rs/tracing/latest/tracing/span/index.html#the-span-lifecycle - /// [time]: Layer::without_time() - pub fn with_span_events(self, kind: FmtSpan) -> Self { - Layer { - fmt_span: self.fmt_span.with_kind(kind), - ..self - } - } - - /// Sets whether or not an event's target is displayed. - pub fn with_target(self, display_target: bool) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_target(display_target), - ..self - } - } - /// Sets whether or not an event's [source code file path][file] is - /// displayed. - /// - /// [file]: tracing_core::Metadata::file - pub fn with_file(self, display_filename: bool) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_file(display_filename), - ..self - } - } - - /// Sets whether or not an event's [source code line number][line] is - /// displayed. - /// - /// [line]: tracing_core::Metadata::line - pub fn with_line_number( - self, - display_line_number: bool, - ) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_line_number(display_line_number), - ..self - } - } - - /// Sets whether or not an event's level is displayed. - pub fn with_level(self, display_level: bool) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_level(display_level), - ..self - } - } - - /// Sets whether or not the [thread ID] of the current thread is displayed - /// when formatting events. - /// - /// [thread ID]: std::thread::ThreadId - pub fn with_thread_ids(self, display_thread_ids: bool) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_thread_ids(display_thread_ids), - ..self - } - } - - /// Sets whether or not the [name] of the current thread is displayed - /// when formatting events. - /// - /// [name]: std::thread#naming-threads - pub fn with_thread_names( - self, - display_thread_names: bool, - ) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_thread_names(display_thread_names), - ..self - } - } - - /// Sets the layer being built to use a [less verbose formatter][super::format::Compact]. - pub fn compact(self) -> Layer, W> - where - N: for<'writer> FormatFields<'writer> + 'static, - { - Layer { - fmt_event: self.fmt_event.compact(), - fmt_fields: self.fmt_fields, - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } - - /// Sets the layer being built to use an [excessively pretty, human-readable formatter](crate::fmt::format::Pretty). - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] - pub fn pretty(self) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.pretty(), - fmt_fields: format::Pretty::default(), - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } - - /// Sets the layer being built to use a [JSON formatter][super::format::Json]. - /// - /// The full format includes fields from all entered spans. - /// - /// # Example Output - /// - /// ```ignore,json - /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate","fields":{"message":"some message", "key": "value"}} - /// ``` - /// - /// # Options - /// - /// - [`Layer::flatten_event`] can be used to enable flattening event fields into the root - /// object. - /// - /// [`Layer::flatten_event`]: Layer::flatten_event() - #[cfg(feature = "json")] - #[cfg_attr(docsrs, doc(cfg(feature = "json")))] - pub fn json(self) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.json(), - fmt_fields: format::JsonFields::new(), - fmt_span: self.fmt_span, - make_writer: self.make_writer, - // always disable ANSI escapes in JSON mode! - is_ansi: false, - _inner: self._inner, - } - } -} - -#[cfg(feature = "json")] -#[cfg_attr(docsrs, doc(cfg(feature = "json")))] -impl Layer, W> { - /// Sets the JSON layer being built to flatten event metadata. - /// - /// See [`format::Json`][super::format::Json] - pub fn flatten_event( - self, - flatten_event: bool, - ) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.flatten_event(flatten_event), - fmt_fields: format::JsonFields::new(), - ..self - } - } - - /// Sets whether or not the formatter will include the current span in - /// formatted events. - /// - /// See [`format::Json`][super::format::Json] - pub fn with_current_span( - self, - display_current_span: bool, - ) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_current_span(display_current_span), - fmt_fields: format::JsonFields::new(), - ..self - } - } - - /// Sets whether or not the formatter will include a list (from root to leaf) - /// of all currently entered spans in formatted events. - /// - /// See [`format::Json`][super::format::Json] - pub fn with_span_list( - self, - display_span_list: bool, - ) -> Layer, W> { - Layer { - fmt_event: self.fmt_event.with_span_list(display_span_list), - fmt_fields: format::JsonFields::new(), - ..self - } - } -} - -impl Layer { - /// Sets the field formatter that the layer being built will use to record - /// fields. - pub fn fmt_fields(self, fmt_fields: N2) -> Layer - where - N2: for<'writer> FormatFields<'writer> + 'static, - { - Layer { - fmt_event: self.fmt_event, - fmt_fields, - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } - - /// Updates the field formatter by applying a function to the existing field formatter. - /// - /// This sets the field formatter that the layer being built will use to record fields. - /// - /// # Examples - /// - /// Updating a field formatter: - /// - /// ```rust - /// use tracing_subscriber::field::MakeExt; - /// let layer = tracing_subscriber::fmt::layer() - /// .map_fmt_fields(|f| f.debug_alt()); - /// # // this is necessary for type inference. - /// # use tracing_subscriber::Layer as _; - /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); - /// ``` - pub fn map_fmt_fields(self, f: impl FnOnce(N) -> N2) -> Layer - where - N2: for<'writer> FormatFields<'writer> + 'static, - { - Layer { - fmt_event: self.fmt_event, - fmt_fields: f(self.fmt_fields), - fmt_span: self.fmt_span, - make_writer: self.make_writer, - is_ansi: self.is_ansi, - _inner: self._inner, - } - } -} - -impl Default for Layer { - fn default() -> Self { - Layer { - fmt_fields: format::DefaultFields::default(), - fmt_event: format::Format::default(), - fmt_span: format::FmtSpanConfig::default(), - make_writer: io::stdout, - is_ansi: cfg!(feature = "ansi"), - _inner: PhantomData, - } - } -} - -impl Layer -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'writer> FormatFields<'writer> + 'static, - E: FormatEvent + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, -{ - #[inline] - fn make_ctx<'a>(&'a self, ctx: Context<'a, S>, event: &'a Event<'a>) -> FmtContext<'a, S, N> { - FmtContext { - ctx, - fmt_fields: &self.fmt_fields, - event, - } - } -} - -/// A formatted representation of a span's fields stored in its [extensions]. -/// -/// Because `FormattedFields` is generic over the type of the formatter that -/// produced it, multiple versions of a span's formatted fields can be stored in -/// the [`Extensions`][extensions] type-map. This means that when multiple -/// formatters are in use, each can store its own formatted representation -/// without conflicting. -/// -/// [extensions]: crate::registry::Extensions -#[derive(Default)] -pub struct FormattedFields { - _format_fields: PhantomData, - was_ansi: bool, - /// The formatted fields of a span. - pub fields: String, -} - -impl FormattedFields { - /// Returns a new `FormattedFields`. - pub fn new(fields: String) -> Self { - Self { - fields, - was_ansi: false, - _format_fields: PhantomData, - } - } - - /// Returns a new [`format::Writer`] for writing to this `FormattedFields`. - /// - /// The returned [`format::Writer`] can be used with the - /// [`FormatFields::format_fields`] method. - pub fn as_writer(&mut self) -> format::Writer<'_> { - format::Writer::new(&mut self.fields).with_ansi(self.was_ansi) - } -} - -impl fmt::Debug for FormattedFields { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FormattedFields") - .field("fields", &self.fields) - .field("formatter", &format_args!("{}", std::any::type_name::())) - .field("was_ansi", &self.was_ansi) - .finish() - } -} - -impl fmt::Display for FormattedFields { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.fields, f) - } -} - -impl Deref for FormattedFields { - type Target = String; - fn deref(&self) -> &Self::Target { - &self.fields - } -} - -// === impl FmtLayer === - -macro_rules! with_event_from_span { - ($id:ident, $span:ident, $($field:literal = $value:expr),*, |$event:ident| $code:block) => { - let meta = $span.metadata(); - let cs = meta.callsite(); - let fs = field::FieldSet::new(&[$($field),*], cs); - #[allow(unused)] - let mut iter = fs.iter(); - let v = [$( - (&iter.next().unwrap(), Some(&$value as &dyn field::Value)), - )*]; - let vs = fs.value_set(&v); - let $event = Event::new_child_of($id, meta, &vs); - $code - }; -} - -impl layer::Layer for Layer -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'writer> FormatFields<'writer> + 'static, - E: FormatEvent + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, -{ - fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { - let span = ctx.span(id).expect("Span not found, this is a bug"); - let mut extensions = span.extensions_mut(); - - if extensions.get_mut::>().is_none() { - let mut fields = FormattedFields::::new(String::new()); - if self - .fmt_fields - .format_fields(fields.as_writer().with_ansi(self.is_ansi), attrs) - .is_ok() - { - fields.was_ansi = self.is_ansi; - extensions.insert(fields); - } - } - - if self.fmt_span.fmt_timing - && self.fmt_span.trace_close() - && extensions.get_mut::().is_none() - { - extensions.insert(Timings::new()); - } - - if self.fmt_span.trace_new() { - with_event_from_span!(id, span, "message" = "new", |event| { - drop(extensions); - drop(span); - self.on_event(&event, ctx); - }); - } - } - - fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { - let span = ctx.span(id).expect("Span not found, this is a bug"); - let mut extensions = span.extensions_mut(); - if let Some(fields) = extensions.get_mut::>() { - let _ = self.fmt_fields.add_fields(fields, values); - return; - } - - let mut fields = FormattedFields::::new(String::new()); - if self - .fmt_fields - .format_fields(fields.as_writer().with_ansi(self.is_ansi), values) - .is_ok() - { - fields.was_ansi = self.is_ansi; - extensions.insert(fields); - } - } - - fn on_enter(&self, id: &Id, ctx: Context<'_, S>) { - if self.fmt_span.trace_enter() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing { - let span = ctx.span(id).expect("Span not found, this is a bug"); - let mut extensions = span.extensions_mut(); - if let Some(timings) = extensions.get_mut::() { - let now = Instant::now(); - timings.idle += (now - timings.last).as_nanos() as u64; - timings.last = now; - } - - if self.fmt_span.trace_enter() { - with_event_from_span!(id, span, "message" = "enter", |event| { - drop(extensions); - drop(span); - self.on_event(&event, ctx); - }); - } - } - } - - fn on_exit(&self, id: &Id, ctx: Context<'_, S>) { - if self.fmt_span.trace_exit() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing { - let span = ctx.span(id).expect("Span not found, this is a bug"); - let mut extensions = span.extensions_mut(); - if let Some(timings) = extensions.get_mut::() { - let now = Instant::now(); - timings.busy += (now - timings.last).as_nanos() as u64; - timings.last = now; - } - - if self.fmt_span.trace_exit() { - with_event_from_span!(id, span, "message" = "exit", |event| { - drop(extensions); - drop(span); - self.on_event(&event, ctx); - }); - } - } - } - - fn on_close(&self, id: Id, ctx: Context<'_, S>) { - if self.fmt_span.trace_close() { - let span = ctx.span(&id).expect("Span not found, this is a bug"); - let extensions = span.extensions(); - if let Some(timing) = extensions.get::() { - let Timings { - busy, - mut idle, - last, - } = *timing; - idle += (Instant::now() - last).as_nanos() as u64; - - let t_idle = field::display(TimingDisplay(idle)); - let t_busy = field::display(TimingDisplay(busy)); - - with_event_from_span!( - id, - span, - "message" = "close", - "time.busy" = t_busy, - "time.idle" = t_idle, - |event| { - drop(extensions); - drop(span); - self.on_event(&event, ctx); - } - ); - } else { - with_event_from_span!(id, span, "message" = "close", |event| { - drop(extensions); - drop(span); - self.on_event(&event, ctx); - }); - } - } - } - - fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { - thread_local! { - static BUF: RefCell = RefCell::new(String::new()); - } - - BUF.with(|buf| { - let borrow = buf.try_borrow_mut(); - let mut a; - let mut b; - let mut buf = match borrow { - Ok(buf) => { - a = buf; - &mut *a - } - _ => { - b = String::new(); - &mut b - } - }; - - let ctx = self.make_ctx(ctx, event); - if self - .fmt_event - .format_event( - &ctx, - format::Writer::new(&mut buf).with_ansi(self.is_ansi), - event, - ) - .is_ok() - { - let mut writer = self.make_writer.make_writer_for(event.metadata()); - let _ = io::Write::write_all(&mut writer, buf.as_bytes()); - } - - buf.clear(); - }); - } - - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - // This `downcast_raw` impl allows downcasting a `fmt` layer to any of - // its components (event formatter, field formatter, and `MakeWriter`) - // as well as to the layer's type itself. The potential use-cases for - // this *may* be somewhat niche, though... - match () { - _ if id == TypeId::of::() => Some(self as *const Self as *const ()), - _ if id == TypeId::of::() => Some(&self.fmt_event as *const E as *const ()), - _ if id == TypeId::of::() => Some(&self.fmt_fields as *const N as *const ()), - _ if id == TypeId::of::() => Some(&self.make_writer as *const W as *const ()), - _ => None, - } - } -} - -/// Provides the current span context to a formatter. -pub struct FmtContext<'a, S, N> { - pub(crate) ctx: Context<'a, S>, - pub(crate) fmt_fields: &'a N, - pub(crate) event: &'a Event<'a>, -} - -impl<'a, S, N> fmt::Debug for FmtContext<'a, S, N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FmtContext").finish() - } -} - -impl<'cx, 'writer, S, N> FormatFields<'writer> for FmtContext<'cx, S, N> -where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - N: FormatFields<'writer> + 'static, -{ - fn format_fields( - &self, - writer: format::Writer<'writer>, - fields: R, - ) -> fmt::Result { - self.fmt_fields.format_fields(writer, fields) - } -} - -impl<'a, S, N> FmtContext<'a, S, N> -where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static, -{ - /// Visits every span in the current context with a closure. - /// - /// The provided closure will be called first with the current span, - /// and then with that span's parent, and then that span's parent, - /// and so on until a root span is reached. - pub fn visit_spans(&self, mut f: F) -> Result<(), E> - where - F: FnMut(&SpanRef<'_, S>) -> Result<(), E>, - { - // visit all the current spans - if let Some(scope) = self.event_scope() { - for span in scope.from_root() { - f(&span)?; - } - } - Ok(()) - } - - /// Returns metadata for the span with the given `id`, if it exists. - /// - /// If this returns `None`, then no span exists for that ID (either it has - /// closed or the ID is invalid). - #[inline] - pub fn metadata(&self, id: &Id) -> Option<&'static Metadata<'static>> - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.ctx.metadata(id) - } - - /// Returns [stored data] for the span with the given `id`, if it exists. - /// - /// If this returns `None`, then no span exists for that ID (either it has - /// closed or the ID is invalid). - /// - /// [stored data]: crate::registry::SpanRef - #[inline] - pub fn span(&self, id: &Id) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.ctx.span(id) - } - - /// Returns `true` if an active span exists for the given `Id`. - #[inline] - pub fn exists(&self, id: &Id) -> bool - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.ctx.exists(id) - } - - /// Returns [stored data] for the span that the wrapped subscriber considers - /// to be the current. - /// - /// If this returns `None`, then we are not currently within a span. - /// - /// [stored data]: crate::registry::SpanRef - #[inline] - pub fn lookup_current(&self) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.ctx.lookup_current() - } - - /// Returns the current span for this formatter. - pub fn current_span(&self) -> Current { - self.ctx.current_span() - } - - /// Returns [stored data] for the parent span of the event currently being - /// formatted. - /// - /// If the event has a contextual parent, this will return the current span. If - /// the event has an explicit parent span, this will return that span. If - /// the event does not have a parent span, this will return `None`. - /// - /// [stored data]: SpanRef - pub fn parent_span(&self) -> Option> { - self.ctx.event_span(self.event) - } - - /// Returns an iterator over the [stored data] for all the spans in the - /// current context, starting with the specified span and ending with the - /// root of the trace tree and ending with the current span. - /// - /// This is equivalent to the [`Context::span_scope`] method. - /// - ///
- ///
Note
- ///
- ///
- ///
-    /// Note: Compared to scope this
-    /// returns the spans in reverse order (from leaf to root). Use
-    /// Scope::from_root
-    /// in case root-to-leaf ordering is desired.
-    /// 
- /// - ///
- ///
-    /// Note: This requires the wrapped subscriber to implement the
-    /// LookupSpan trait.
-    /// See the documentation on Context's
-    /// declaration for details.
-    /// 
- /// - /// [stored data]: crate::registry::SpanRef - pub fn span_scope(&self, id: &Id) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.ctx.span_scope(id) - } - - /// Returns an iterator over the [stored data] for all the spans in the - /// event's span context, starting with its parent span and ending with the - /// root of the trace tree. - /// - /// This is equivalent to calling the [`Context::event_scope`] method and - /// passing the event currently being formatted. - /// - ///
- ///
-    /// Note: Compared to scope this
-    /// returns the spans in reverse order (from leaf to root). Use
-    /// Scope::from_root
-    /// in case root-to-leaf ordering is desired.
-    /// 
- /// - ///
- ///
-    /// Note: This requires the wrapped subscriber to implement the
-    /// LookupSpan trait.
-    /// See the documentation on Context's
-    /// declaration for details.
-    /// 
- /// - /// [stored data]: crate::registry::SpanRef - pub fn event_scope(&self) -> Option> - where - S: for<'lookup> registry::LookupSpan<'lookup>, - { - self.ctx.event_scope(self.event) - } - - /// Returns the [field formatter] configured by the subscriber invoking - /// `format_event`. - /// - /// The event formatter may use the returned field formatter to format the - /// fields of any events it records. - /// - /// [field formatter]: FormatFields - pub fn field_format(&self) -> &N { - self.fmt_fields - } -} - -struct Timings { - idle: u64, - busy: u64, - last: Instant, -} - -impl Timings { - fn new() -> Self { - Self { - idle: 0, - busy: 0, - last: Instant::now(), - } - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::fmt::{ - self, - format::{self, test::MockTime, Format}, - layer::Layer as _, - test::{MockMakeWriter, MockWriter}, - time, - }; - use crate::Registry; - use format::FmtSpan; - use regex::Regex; - use tracing::subscriber::with_default; - use tracing_core::dispatcher::Dispatch; - - #[test] - fn impls() { - let f = Format::default().with_timer(time::Uptime::default()); - let fmt = fmt::Layer::default().event_format(f); - let subscriber = fmt.with_subscriber(Registry::default()); - let _dispatch = Dispatch::new(subscriber); - - let f = format::Format::default(); - let fmt = fmt::Layer::default().event_format(f); - let subscriber = fmt.with_subscriber(Registry::default()); - let _dispatch = Dispatch::new(subscriber); - - let f = format::Format::default().compact(); - let fmt = fmt::Layer::default().event_format(f); - let subscriber = fmt.with_subscriber(Registry::default()); - let _dispatch = Dispatch::new(subscriber); - } - - #[test] - fn fmt_layer_downcasts() { - let f = format::Format::default(); - let fmt = fmt::Layer::default().event_format(f); - let subscriber = fmt.with_subscriber(Registry::default()); - - let dispatch = Dispatch::new(subscriber); - assert!(dispatch.downcast_ref::>().is_some()); - } - - #[test] - fn fmt_layer_downcasts_to_parts() { - let f = format::Format::default(); - let fmt = fmt::Layer::default().event_format(f); - let subscriber = fmt.with_subscriber(Registry::default()); - let dispatch = Dispatch::new(subscriber); - assert!(dispatch.downcast_ref::().is_some()); - assert!(dispatch.downcast_ref::().is_some()) - } - - #[test] - fn is_lookup_span() { - fn assert_lookup_span crate::registry::LookupSpan<'a>>(_: T) {} - let fmt = fmt::Layer::default(); - let subscriber = fmt.with_subscriber(Registry::default()); - assert_lookup_span(subscriber) - } - - fn sanitize_timings(s: String) -> String { - let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap(); - re.replace_all(s.as_str(), "timing").to_string() - } - - #[test] - fn synthesize_span_none() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - // check that FmtSpan::NONE is the default - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", x = 42); - let _e = span1.enter(); - }); - let actual = sanitize_timings(make_writer.get_string()); - assert_eq!("", actual.as_str()); - } - - #[test] - fn synthesize_span_active() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - .with_span_events(FmtSpan::ACTIVE) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", x = 42); - let _e = span1.enter(); - }); - let actual = sanitize_timings(make_writer.get_string()); - assert_eq!( - "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\ - fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n", - actual.as_str() - ); - } - - #[test] - fn synthesize_span_close() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - .with_span_events(FmtSpan::CLOSE) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", x = 42); - let _e = span1.enter(); - }); - let actual = sanitize_timings(make_writer.get_string()); - assert_eq!( - "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n", - actual.as_str() - ); - } - - #[test] - fn synthesize_span_close_no_timing() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - .without_time() - .with_span_events(FmtSpan::CLOSE) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", x = 42); - let _e = span1.enter(); - }); - let actual = sanitize_timings(make_writer.get_string()); - assert_eq!( - "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n", - actual.as_str() - ); - } - - #[test] - fn synthesize_span_full() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - .with_span_events(FmtSpan::FULL) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", x = 42); - let _e = span1.enter(); - }); - let actual = sanitize_timings(make_writer.get_string()); - assert_eq!( - "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\ - fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\ - fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\ - fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n", - actual.as_str() - ); - } - - #[test] - fn make_writer_based_on_meta() { - struct MakeByTarget { - make_writer1: MockMakeWriter, - make_writer2: MockMakeWriter, - } - - impl<'a> MakeWriter<'a> for MakeByTarget { - type Writer = MockWriter; - - fn make_writer(&'a self) -> Self::Writer { - self.make_writer1.make_writer() - } - - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - if meta.target() == "writer2" { - return self.make_writer2.make_writer(); - } - self.make_writer() - } - } - - let make_writer1 = MockMakeWriter::default(); - let make_writer2 = MockMakeWriter::default(); - - let make_writer = MakeByTarget { - make_writer1: make_writer1.clone(), - make_writer2: make_writer2.clone(), - }; - - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer) - .with_level(false) - .with_target(false) - .with_ansi(false) - .with_timer(MockTime) - .with_span_events(FmtSpan::CLOSE) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("writer1_span", x = 42); - let _e = span1.enter(); - tracing::info!(target: "writer2", "hello writer2!"); - let span2 = tracing::info_span!(target: "writer2", "writer2_span"); - let _e = span2.enter(); - tracing::warn!(target: "writer1", "hello writer1!"); - }); - - let actual = sanitize_timings(make_writer1.get_string()); - assert_eq!( - "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\ - fake time writer1_span{x=42}: close timing timing\n", - actual.as_str() - ); - let actual = sanitize_timings(make_writer2.get_string()); - assert_eq!( - "fake time writer1_span{x=42}: hello writer2!\n\ - fake time writer1_span{x=42}:writer2_span: close timing timing\n", - actual.as_str() - ); - } -} diff --git a/vendor/tracing-subscriber/src/fmt/format/json.rs b/vendor/tracing-subscriber/src/fmt/format/json.rs deleted file mode 100644 index c2f4d3755..000000000 --- a/vendor/tracing-subscriber/src/fmt/format/json.rs +++ /dev/null @@ -1,885 +0,0 @@ -use super::{Format, FormatEvent, FormatFields, FormatTime, Writer}; -use crate::{ - field::{RecordFields, VisitOutput}, - fmt::{ - fmt_layer::{FmtContext, FormattedFields}, - writer::WriteAdaptor, - }, - registry::LookupSpan, -}; -use serde::ser::{SerializeMap, Serializer as _}; -use serde_json::Serializer; -use std::{ - collections::BTreeMap, - fmt::{self, Write}, -}; -use tracing_core::{ - field::{self, Field}, - span::Record, - Event, Subscriber, -}; -use tracing_serde::AsSerde; - -#[cfg(feature = "tracing-log")] -use tracing_log::NormalizeEvent; - -/// Marker for [`Format`] that indicates that the newline-delimited JSON log -/// format should be used. -/// -/// This formatter is intended for production use with systems where structured -/// logs are consumed as JSON by analysis and viewing tools. The JSON output is -/// not optimized for human readability; instead, it should be pretty-printed -/// using external JSON tools such as `jq`, or using a JSON log viewer. -/// -/// # Example Output -/// -///
:; cargo run --example fmt-json
-///     Finished dev [unoptimized + debuginfo] target(s) in 0.08s
-///      Running `target/debug/examples/fmt-json`
-/// {"timestamp":"2022-02-15T18:47:10.821315Z","level":"INFO","fields":{"message":"preparing to shave yaks","number_of_yaks":3},"target":"fmt_json"}
-/// {"timestamp":"2022-02-15T18:47:10.821422Z","level":"INFO","fields":{"message":"shaving yaks"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821495Z","level":"TRACE","fields":{"message":"hello! I'm gonna shave a yak","excitement":"yay!"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":1,"name":"shave"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821546Z","level":"TRACE","fields":{"message":"yak shaved successfully"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":1,"name":"shave"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821598Z","level":"DEBUG","fields":{"yak":1,"shaved":true},"target":"yak_events","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821637Z","level":"TRACE","fields":{"yaks_shaved":1},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821684Z","level":"TRACE","fields":{"message":"hello! I'm gonna shave a yak","excitement":"yay!"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":2,"name":"shave"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821727Z","level":"TRACE","fields":{"message":"yak shaved successfully"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":2,"name":"shave"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821773Z","level":"DEBUG","fields":{"yak":2,"shaved":true},"target":"yak_events","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821806Z","level":"TRACE","fields":{"yaks_shaved":2},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821909Z","level":"TRACE","fields":{"message":"hello! I'm gonna shave a yak","excitement":"yay!"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":3,"name":"shave"}]}
-/// {"timestamp":"2022-02-15T18:47:10.821956Z","level":"WARN","fields":{"message":"could not locate yak"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"},{"yak":3,"name":"shave"}]}
-/// {"timestamp":"2022-02-15T18:47:10.822006Z","level":"DEBUG","fields":{"yak":3,"shaved":false},"target":"yak_events","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.822041Z","level":"ERROR","fields":{"message":"failed to shave yak","yak":3,"error":"missing yak"},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.822079Z","level":"TRACE","fields":{"yaks_shaved":2},"target":"fmt_json::yak_shave","spans":[{"yaks":3,"name":"shaving_yaks"}]}
-/// {"timestamp":"2022-02-15T18:47:10.822117Z","level":"INFO","fields":{"message":"yak shaving completed","all_yaks_shaved":false},"target":"fmt_json"}
-/// 
-/// -/// # Options -/// -/// This formatter exposes additional options to configure the structure of the -/// output JSON objects: -/// -/// - [`Json::flatten_event`] can be used to enable flattening event fields into -/// the root -/// - [`Json::with_current_span`] can be used to control logging of the current -/// span -/// - [`Json::with_span_list`] can be used to control logging of the span list -/// object. -/// -/// By default, event fields are not flattened, and both current span and span -/// list are logged. -/// -/// # Valuable Support -/// -/// Experimental support is available for using the [`valuable`] crate to record -/// user-defined values as structured JSON. When the ["valuable" unstable -/// feature][unstable] is enabled, types implementing [`valuable::Valuable`] will -/// be recorded as structured JSON, rather than -/// using their [`std::fmt::Debug`] implementations. -/// -/// **Note**: This is an experimental feature. [Unstable features][unstable] -/// must be enabled in order to use `valuable` support. -/// -/// [`Json::flatten_event`]: Json::flatten_event() -/// [`Json::with_current_span`]: Json::with_current_span() -/// [`Json::with_span_list`]: Json::with_span_list() -/// [`valuable`]: https://crates.io/crates/valuable -/// [unstable]: crate#unstable-features -/// [`valuable::Valuable`]: https://docs.rs/valuable/latest/valuable/trait.Valuable.html -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct Json { - pub(crate) flatten_event: bool, - pub(crate) display_current_span: bool, - pub(crate) display_span_list: bool, -} - -impl Json { - /// If set to `true` event metadata will be flattened into the root object. - pub fn flatten_event(&mut self, flatten_event: bool) { - self.flatten_event = flatten_event; - } - - /// If set to `false`, formatted events won't contain a field for the current span. - pub fn with_current_span(&mut self, display_current_span: bool) { - self.display_current_span = display_current_span; - } - - /// If set to `false`, formatted events won't contain a list of all currently - /// entered spans. Spans are logged in a list from root to leaf. - pub fn with_span_list(&mut self, display_span_list: bool) { - self.display_span_list = display_span_list; - } -} - -struct SerializableContext<'a, 'b, Span, N>( - &'b crate::layer::Context<'a, Span>, - std::marker::PhantomData, -) -where - Span: Subscriber + for<'lookup> crate::registry::LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static; - -impl<'a, 'b, Span, N> serde::ser::Serialize for SerializableContext<'a, 'b, Span, N> -where - Span: Subscriber + for<'lookup> crate::registry::LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static, -{ - fn serialize(&self, serializer_o: Ser) -> Result - where - Ser: serde::ser::Serializer, - { - use serde::ser::SerializeSeq; - let mut serializer = serializer_o.serialize_seq(None)?; - - if let Some(leaf_span) = self.0.lookup_current() { - for span in leaf_span.scope().from_root() { - serializer.serialize_element(&SerializableSpan(&span, self.1))?; - } - } - - serializer.end() - } -} - -struct SerializableSpan<'a, 'b, Span, N>( - &'b crate::registry::SpanRef<'a, Span>, - std::marker::PhantomData, -) -where - Span: for<'lookup> crate::registry::LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static; - -impl<'a, 'b, Span, N> serde::ser::Serialize for SerializableSpan<'a, 'b, Span, N> -where - Span: for<'lookup> crate::registry::LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static, -{ - fn serialize(&self, serializer: Ser) -> Result - where - Ser: serde::ser::Serializer, - { - let mut serializer = serializer.serialize_map(None)?; - - let ext = self.0.extensions(); - let data = ext - .get::>() - .expect("Unable to find FormattedFields in extensions; this is a bug"); - - // TODO: let's _not_ do this, but this resolves - // https://github.com/tokio-rs/tracing/issues/391. - // We should probably rework this to use a `serde_json::Value` or something - // similar in a JSON-specific layer, but I'd (david) - // rather have a uglier fix now rather than shipping broken JSON. - match serde_json::from_str::(data) { - Ok(serde_json::Value::Object(fields)) => { - for field in fields { - serializer.serialize_entry(&field.0, &field.1)?; - } - } - // We have fields for this span which are valid JSON but not an object. - // This is probably a bug, so panic if we're in debug mode - Ok(_) if cfg!(debug_assertions) => panic!( - "span '{}' had malformed fields! this is a bug.\n error: invalid JSON object\n fields: {:?}", - self.0.metadata().name(), - data - ), - // If we *aren't* in debug mode, it's probably best not to - // crash the program, let's log the field found but also an - // message saying it's type is invalid - Ok(value) => { - serializer.serialize_entry("field", &value)?; - serializer.serialize_entry("field_error", "field was no a valid object")? - } - // We have previously recorded fields for this span - // should be valid JSON. However, they appear to *not* - // be valid JSON. This is almost certainly a bug, so - // panic if we're in debug mode - Err(e) if cfg!(debug_assertions) => panic!( - "span '{}' had malformed fields! this is a bug.\n error: {}\n fields: {:?}", - self.0.metadata().name(), - e, - data - ), - // If we *aren't* in debug mode, it's probably best not - // crash the program, but let's at least make sure it's clear - // that the fields are not supposed to be missing. - Err(e) => serializer.serialize_entry("field_error", &format!("{}", e))?, - }; - serializer.serialize_entry("name", self.0.metadata().name())?; - serializer.end() - } -} - -impl FormatEvent for Format -where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static, - T: FormatTime, -{ - fn format_event( - &self, - ctx: &FmtContext<'_, S, N>, - mut writer: Writer<'_>, - event: &Event<'_>, - ) -> fmt::Result - where - S: Subscriber + for<'a> LookupSpan<'a>, - { - let mut timestamp = String::new(); - self.timer.format_time(&mut Writer::new(&mut timestamp))?; - - #[cfg(feature = "tracing-log")] - let normalized_meta = event.normalized_metadata(); - #[cfg(feature = "tracing-log")] - let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - #[cfg(not(feature = "tracing-log"))] - let meta = event.metadata(); - - let mut visit = || { - let mut serializer = Serializer::new(WriteAdaptor::new(&mut writer)); - - let mut serializer = serializer.serialize_map(None)?; - - if self.display_timestamp { - serializer.serialize_entry("timestamp", ×tamp)?; - } - - if self.display_level { - serializer.serialize_entry("level", &meta.level().as_serde())?; - } - - let format_field_marker: std::marker::PhantomData = std::marker::PhantomData; - - let current_span = if self.format.display_current_span || self.format.display_span_list - { - event - .parent() - .and_then(|id| ctx.span(id)) - .or_else(|| ctx.lookup_current()) - } else { - None - }; - - if self.format.flatten_event { - let mut visitor = tracing_serde::SerdeMapVisitor::new(serializer); - event.record(&mut visitor); - - serializer = visitor.take_serializer()?; - } else { - use tracing_serde::fields::AsMap; - serializer.serialize_entry("fields", &event.field_map())?; - }; - - if self.display_target { - serializer.serialize_entry("target", meta.target())?; - } - - if self.display_filename { - if let Some(filename) = meta.file() { - serializer.serialize_entry("filename", filename)?; - } - } - - if self.display_line_number { - if let Some(line_number) = meta.line() { - serializer.serialize_entry("line_number", &line_number)?; - } - } - - if self.format.display_current_span { - if let Some(ref span) = current_span { - serializer - .serialize_entry("span", &SerializableSpan(span, format_field_marker)) - .unwrap_or(()); - } - } - - if self.format.display_span_list && current_span.is_some() { - serializer.serialize_entry( - "spans", - &SerializableContext(&ctx.ctx, format_field_marker), - )?; - } - - if self.display_thread_name { - let current_thread = std::thread::current(); - match current_thread.name() { - Some(name) => { - serializer.serialize_entry("threadName", name)?; - } - // fall-back to thread id when name is absent and ids are not enabled - None if !self.display_thread_id => { - serializer - .serialize_entry("threadName", &format!("{:?}", current_thread.id()))?; - } - _ => {} - } - } - - if self.display_thread_id { - serializer - .serialize_entry("threadId", &format!("{:?}", std::thread::current().id()))?; - } - - serializer.end() - }; - - visit().map_err(|_| fmt::Error)?; - writeln!(writer) - } -} - -impl Default for Json { - fn default() -> Json { - Json { - flatten_event: false, - display_current_span: true, - display_span_list: true, - } - } -} - -/// The JSON [`FormatFields`] implementation. -/// -#[derive(Debug)] -pub struct JsonFields { - // reserve the ability to add fields to this without causing a breaking - // change in the future. - _private: (), -} - -impl JsonFields { - /// Returns a new JSON [`FormatFields`] implementation. - /// - pub fn new() -> Self { - Self { _private: () } - } -} - -impl Default for JsonFields { - fn default() -> Self { - Self::new() - } -} - -impl<'a> FormatFields<'a> for JsonFields { - /// Format the provided `fields` to the provided `writer`, returning a result. - fn format_fields(&self, mut writer: Writer<'_>, fields: R) -> fmt::Result { - let mut v = JsonVisitor::new(&mut writer); - fields.record(&mut v); - v.finish() - } - - /// Record additional field(s) on an existing span. - /// - /// By default, this appends a space to the current set of fields if it is - /// non-empty, and then calls `self.format_fields`. If different behavior is - /// required, the default implementation of this method can be overridden. - fn add_fields( - &self, - current: &'a mut FormattedFields, - fields: &Record<'_>, - ) -> fmt::Result { - if current.is_empty() { - // If there are no previously recorded fields, we can just reuse the - // existing string. - let mut writer = current.as_writer(); - let mut v = JsonVisitor::new(&mut writer); - fields.record(&mut v); - v.finish()?; - return Ok(()); - } - - // If fields were previously recorded on this span, we need to parse - // the current set of fields as JSON, add the new fields, and - // re-serialize them. Otherwise, if we just appended the new fields - // to a previously serialized JSON object, we would end up with - // malformed JSON. - // - // XXX(eliza): this is far from efficient, but unfortunately, it is - // necessary as long as the JSON formatter is implemented on top of - // an interface that stores all formatted fields as strings. - // - // We should consider reimplementing the JSON formatter as a - // separate layer, rather than a formatter for the `fmt` layer — - // then, we could store fields as JSON values, and add to them - // without having to parse and re-serialize. - let mut new = String::new(); - let map: BTreeMap<&'_ str, serde_json::Value> = - serde_json::from_str(current).map_err(|_| fmt::Error)?; - let mut v = JsonVisitor::new(&mut new); - v.values = map; - fields.record(&mut v); - v.finish()?; - current.fields = new; - - Ok(()) - } -} - -/// The [visitor] produced by [`JsonFields`]'s [`MakeVisitor`] implementation. -/// -/// [visitor]: crate::field::Visit -/// [`MakeVisitor`]: crate::field::MakeVisitor -pub struct JsonVisitor<'a> { - values: BTreeMap<&'a str, serde_json::Value>, - writer: &'a mut dyn Write, -} - -impl<'a> fmt::Debug for JsonVisitor<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_fmt(format_args!("JsonVisitor {{ values: {:?} }}", self.values)) - } -} - -impl<'a> JsonVisitor<'a> { - /// Returns a new default visitor that formats to the provided `writer`. - /// - /// # Arguments - /// - `writer`: the writer to format to. - /// - `is_empty`: whether or not any fields have been previously written to - /// that writer. - pub fn new(writer: &'a mut dyn Write) -> Self { - Self { - values: BTreeMap::new(), - writer, - } - } -} - -impl<'a> crate::field::VisitFmt for JsonVisitor<'a> { - fn writer(&mut self) -> &mut dyn fmt::Write { - self.writer - } -} - -impl<'a> crate::field::VisitOutput for JsonVisitor<'a> { - fn finish(self) -> fmt::Result { - let inner = || { - let mut serializer = Serializer::new(WriteAdaptor::new(self.writer)); - let mut ser_map = serializer.serialize_map(None)?; - - for (k, v) in self.values { - ser_map.serialize_entry(k, &v)?; - } - - ser_map.end() - }; - - if inner().is_err() { - Err(fmt::Error) - } else { - Ok(()) - } - } -} - -impl<'a> field::Visit for JsonVisitor<'a> { - #[cfg(all(tracing_unstable, feature = "valuable"))] - fn record_value(&mut self, field: &Field, value: valuable_crate::Value<'_>) { - let value = match serde_json::to_value(valuable_serde::Serializable::new(value)) { - Ok(value) => value, - Err(_e) => { - #[cfg(debug_assertions)] - unreachable!( - "`valuable::Valuable` implementations should always serialize \ - successfully, but an error occurred: {}", - _e, - ); - - #[cfg(not(debug_assertions))] - return; - } - }; - - self.values.insert(field.name(), value); - } - - /// Visit a double precision floating point value. - fn record_f64(&mut self, field: &Field, value: f64) { - self.values - .insert(field.name(), serde_json::Value::from(value)); - } - - /// Visit a signed 64-bit integer value. - fn record_i64(&mut self, field: &Field, value: i64) { - self.values - .insert(field.name(), serde_json::Value::from(value)); - } - - /// Visit an unsigned 64-bit integer value. - fn record_u64(&mut self, field: &Field, value: u64) { - self.values - .insert(field.name(), serde_json::Value::from(value)); - } - - /// Visit a boolean value. - fn record_bool(&mut self, field: &Field, value: bool) { - self.values - .insert(field.name(), serde_json::Value::from(value)); - } - - /// Visit a string value. - fn record_str(&mut self, field: &Field, value: &str) { - self.values - .insert(field.name(), serde_json::Value::from(value)); - } - - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - match field.name() { - // Skip fields that are actually log metadata that have already been handled - #[cfg(feature = "tracing-log")] - name if name.starts_with("log.") => (), - name if name.starts_with("r#") => { - self.values - .insert(&name[2..], serde_json::Value::from(format!("{:?}", value))); - } - name => { - self.values - .insert(name, serde_json::Value::from(format!("{:?}", value))); - } - }; - } -} -#[cfg(test)] -mod test { - use super::*; - use crate::fmt::{format::FmtSpan, test::MockMakeWriter, time::FormatTime, SubscriberBuilder}; - use tracing::{self, subscriber::with_default}; - - use std::fmt; - use std::path::Path; - - struct MockTime; - impl FormatTime for MockTime { - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - write!(w, "fake time") - } - } - - fn subscriber() -> SubscriberBuilder> { - SubscriberBuilder::default().json() - } - - #[test] - fn json() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(true) - .with_span_list(true); - test_json(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_filename() { - let current_path = Path::new("tracing-subscriber") - .join("src") - .join("fmt") - .join("format") - .join("json.rs") - .to_str() - .expect("path must be valid unicode") - // escape windows backslashes - .replace('\\', "\\\\"); - let expected = - &format!("{}{}{}", - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"filename\":\"", - current_path, - "\",\"fields\":{\"message\":\"some json test\"}}\n"); - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(true) - .with_file(true) - .with_span_list(true); - test_json(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_line_number() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"line_number\":42,\"fields\":{\"message\":\"some json test\"}}\n"; - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(true) - .with_line_number(true) - .with_span_list(true); - test_json_with_line_number(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_flattened_event() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"message\":\"some json test\"}\n"; - - let subscriber = subscriber() - .flatten_event(true) - .with_current_span(true) - .with_span_list(true); - test_json(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_disabled_current_span_event() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(false) - .with_span_list(true); - test_json(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_disabled_span_list_event() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":42,\"name\":\"json_span\",\"number\":3},\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(true) - .with_span_list(false); - test_json(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_nested_span() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"span\":{\"answer\":43,\"name\":\"nested_json_span\",\"number\":4},\"spans\":[{\"answer\":42,\"name\":\"json_span\",\"number\":3},{\"answer\":43,\"name\":\"nested_json_span\",\"number\":4}],\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(true) - .with_span_list(true); - test_json(expected, subscriber, || { - let span = tracing::span!(tracing::Level::INFO, "json_span", answer = 42, number = 3); - let _guard = span.enter(); - let span = tracing::span!( - tracing::Level::INFO, - "nested_json_span", - answer = 43, - number = 4 - ); - let _guard = span.enter(); - tracing::info!("some json test"); - }); - } - - #[test] - fn json_no_span() { - let expected = - "{\"timestamp\":\"fake time\",\"level\":\"INFO\",\"target\":\"tracing_subscriber::fmt::format::json::test\",\"fields\":{\"message\":\"some json test\"}}\n"; - let subscriber = subscriber() - .flatten_event(false) - .with_current_span(true) - .with_span_list(true); - test_json(expected, subscriber, || { - tracing::info!("some json test"); - }); - } - - #[test] - fn record_works() { - // This test reproduces issue #707, where using `Span::record` causes - // any events inside the span to be ignored. - - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt() - .json() - .with_writer(make_writer.clone()) - .finish(); - - with_default(subscriber, || { - tracing::info!("an event outside the root span"); - assert_eq!( - parse_as_json(&make_writer)["fields"]["message"], - "an event outside the root span" - ); - - let span = tracing::info_span!("the span", na = tracing::field::Empty); - span.record("na", &"value"); - let _enter = span.enter(); - - tracing::info!("an event inside the root span"); - assert_eq!( - parse_as_json(&make_writer)["fields"]["message"], - "an event inside the root span" - ); - }); - } - - #[test] - fn json_span_event_show_correct_context() { - let buffer = MockMakeWriter::default(); - let subscriber = subscriber() - .with_writer(buffer.clone()) - .flatten_event(false) - .with_current_span(true) - .with_span_list(false) - .with_span_events(FmtSpan::FULL) - .finish(); - - with_default(subscriber, || { - let context = "parent"; - let parent_span = tracing::info_span!("parent_span", context); - - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "new"); - assert_eq!(event["span"]["context"], "parent"); - - let _parent_enter = parent_span.enter(); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "enter"); - assert_eq!(event["span"]["context"], "parent"); - - let context = "child"; - let child_span = tracing::info_span!("child_span", context); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "new"); - assert_eq!(event["span"]["context"], "child"); - - let _child_enter = child_span.enter(); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "enter"); - assert_eq!(event["span"]["context"], "child"); - - drop(_child_enter); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "exit"); - assert_eq!(event["span"]["context"], "child"); - - drop(child_span); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "close"); - assert_eq!(event["span"]["context"], "child"); - - drop(_parent_enter); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "exit"); - assert_eq!(event["span"]["context"], "parent"); - - drop(parent_span); - let event = parse_as_json(&buffer); - assert_eq!(event["fields"]["message"], "close"); - assert_eq!(event["span"]["context"], "parent"); - }); - } - - #[test] - fn json_span_event_with_no_fields() { - // Check span events serialize correctly. - // Discussion: https://github.com/tokio-rs/tracing/issues/829#issuecomment-661984255 - let buffer = MockMakeWriter::default(); - let subscriber = subscriber() - .with_writer(buffer.clone()) - .flatten_event(false) - .with_current_span(false) - .with_span_list(false) - .with_span_events(FmtSpan::FULL) - .finish(); - - with_default(subscriber, || { - let span = tracing::info_span!("valid_json"); - assert_eq!(parse_as_json(&buffer)["fields"]["message"], "new"); - - let _enter = span.enter(); - assert_eq!(parse_as_json(&buffer)["fields"]["message"], "enter"); - - drop(_enter); - assert_eq!(parse_as_json(&buffer)["fields"]["message"], "exit"); - - drop(span); - assert_eq!(parse_as_json(&buffer)["fields"]["message"], "close"); - }); - } - - fn parse_as_json(buffer: &MockMakeWriter) -> serde_json::Value { - let buf = String::from_utf8(buffer.buf().to_vec()).unwrap(); - let json = buf - .lines() - .last() - .expect("expected at least one line to be written!"); - match serde_json::from_str(json) { - Ok(v) => v, - Err(e) => panic!( - "assertion failed: JSON shouldn't be malformed\n error: {}\n json: {}", - e, json - ), - } - } - - fn test_json( - expected: &str, - builder: crate::fmt::SubscriberBuilder>, - producer: impl FnOnce() -> T, - ) { - let make_writer = MockMakeWriter::default(); - let subscriber = builder - .with_writer(make_writer.clone()) - .with_timer(MockTime) - .finish(); - - with_default(subscriber, producer); - - let buf = make_writer.buf(); - let actual = std::str::from_utf8(&buf[..]).unwrap(); - assert_eq!( - serde_json::from_str::>(expected) - .unwrap(), - serde_json::from_str(actual).unwrap() - ); - } - - fn test_json_with_line_number( - expected: &str, - builder: crate::fmt::SubscriberBuilder>, - producer: impl FnOnce() -> T, - ) { - let make_writer = MockMakeWriter::default(); - let subscriber = builder - .with_writer(make_writer.clone()) - .with_timer(MockTime) - .finish(); - - with_default(subscriber, producer); - - let buf = make_writer.buf(); - let actual = std::str::from_utf8(&buf[..]).unwrap(); - let mut expected = - serde_json::from_str::>(expected) - .unwrap(); - let expect_line_number = expected.remove("line_number").is_some(); - let mut actual: std::collections::HashMap<&str, serde_json::Value> = - serde_json::from_str(actual).unwrap(); - let line_number = actual.remove("line_number"); - if expect_line_number { - assert_eq!(line_number.map(|x| x.is_number()), Some(true)); - } else { - assert!(line_number.is_none()); - } - assert_eq!(actual, expected); - } -} diff --git a/vendor/tracing-subscriber/src/fmt/format/mod.rs b/vendor/tracing-subscriber/src/fmt/format/mod.rs deleted file mode 100644 index ec79ac140..000000000 --- a/vendor/tracing-subscriber/src/fmt/format/mod.rs +++ /dev/null @@ -1,2161 +0,0 @@ -//! Formatters for logging `tracing` events. -//! -//! This module provides several formatter implementations, as well as utilities -//! for implementing custom formatters. -//! -//! # Formatters -//! This module provides a number of formatter implementations: -//! -//! * [`Full`]: The default formatter. This emits human-readable, -//! single-line logs for each event that occurs, with the current span context -//! displayed before the formatted representation of the event. See -//! [here](Full#example-output) for sample output. -//! -//! * [`Compact`]: A variant of the default formatter, optimized for -//! short line lengths. Fields from the current span context are appended to -//! the fields of the formatted event, and span names are not shown; the -//! verbosity level is abbreviated to a single character. See -//! [here](Compact#example-output) for sample output. -//! -//! * [`Pretty`]: Emits excessively pretty, multi-line logs, optimized -//! for human readability. This is primarily intended to be used in local -//! development and debugging, or for command-line applications, where -//! automated analysis and compact storage of logs is less of a priority than -//! readability and visual appeal. See [here](Pretty#example-output) -//! for sample output. -//! -//! * [`Json`]: Outputs newline-delimited JSON logs. This is intended -//! for production use with systems where structured logs are consumed as JSON -//! by analysis and viewing tools. The JSON output is not optimized for human -//! readability. See [here](Json#example-output) for sample output. -use super::time::{FormatTime, SystemTime}; -use crate::{ - field::{MakeOutput, MakeVisitor, RecordFields, VisitFmt, VisitOutput}, - fmt::fmt_layer::FmtContext, - fmt::fmt_layer::FormattedFields, - registry::LookupSpan, -}; - -use std::fmt::{self, Debug, Display, Write}; -use tracing_core::{ - field::{self, Field, Visit}, - span, Event, Level, Subscriber, -}; - -#[cfg(feature = "tracing-log")] -use tracing_log::NormalizeEvent; - -#[cfg(feature = "ansi")] -use ansi_term::{Colour, Style}; - -#[cfg(feature = "json")] -mod json; -#[cfg(feature = "json")] -#[cfg_attr(docsrs, doc(cfg(feature = "json")))] -pub use json::*; - -#[cfg(feature = "ansi")] -mod pretty; -#[cfg(feature = "ansi")] -#[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] -pub use pretty::*; - -/// A type that can format a tracing [`Event`] to a [`Writer`]. -/// -/// `FormatEvent` is primarily used in the context of [`fmt::Subscriber`] or -/// [`fmt::Layer`]. Each time an event is dispatched to [`fmt::Subscriber`] or -/// [`fmt::Layer`], the subscriber or layer -/// forwards it to its associated `FormatEvent` to emit a log message. -/// -/// This trait is already implemented for function pointers with the same -/// signature as `format_event`. -/// -/// # Arguments -/// -/// The following arguments are passed to `FormatEvent::format_event`: -/// -/// * A [`FmtContext`]. This is an extension of the [`layer::Context`] type, -/// which can be used for accessing stored information such as the current -/// span context an event occurred in. -/// -/// In addition, [`FmtContext`] exposes access to the [`FormatFields`] -/// implementation that the subscriber was configured to use via the -/// [`FmtContext::field_format`] method. This can be used when the -/// [`FormatEvent`] implementation needs to format the event's fields. -/// -/// For convenience, [`FmtContext`] also [implements `FormatFields`], -/// forwarding to the configured [`FormatFields`] type. -/// -/// * A [`Writer`] to which the formatted representation of the event is -/// written. This type implements the [`std::fmt::Write`] trait, and therefore -/// can be used with the [`std::write!`] and [`std::writeln!`] macros, as well -/// as calling [`std::fmt::Write`] methods directly. -/// -/// The [`Writer`] type also implements additional methods that provide -/// information about how the event should be formatted. The -/// [`Writer::has_ansi_escapes`] method indicates whether [ANSI terminal -/// escape codes] are supported by the underlying I/O writer that the event -/// will be written to. If this returns `true`, the formatter is permitted to -/// use ANSI escape codes to add colors and other text formatting to its -/// output. If it returns `false`, the event will be written to an output that -/// does not support ANSI escape codes (such as a log file), and they should -/// not be emitted. -/// -/// Crates like [`ansi_term`] and [`owo-colors`] can be used to add ANSI -/// escape codes to formatted output. -/// -/// * The actual [`Event`] to be formatted. -/// -/// # Examples -/// -/// This example re-implements a simiplified version of this crate's [default -/// formatter]: -/// -/// ```rust -/// use std::fmt; -/// use tracing_core::{Subscriber, Event}; -/// use tracing_subscriber::fmt::{ -/// format::{self, FormatEvent, FormatFields}, -/// FmtContext, -/// FormattedFields, -/// }; -/// use tracing_subscriber::registry::LookupSpan; -/// -/// struct MyFormatter; -/// -/// impl FormatEvent for MyFormatter -/// where -/// S: Subscriber + for<'a> LookupSpan<'a>, -/// N: for<'a> FormatFields<'a> + 'static, -/// { -/// fn format_event( -/// &self, -/// ctx: &FmtContext<'_, S, N>, -/// mut writer: format::Writer<'_>, -/// event: &Event<'_>, -/// ) -> fmt::Result { -/// // Format values from the event's's metadata: -/// let metadata = event.metadata(); -/// write!(&mut writer, "{} {}: ", metadata.level(), metadata.target())?; -/// -/// // Format all the spans in the event's span context. -/// if let Some(scope) = ctx.event_scope() { -/// for span in scope.from_root() { -/// write!(writer, "{}", span.name())?; -/// -/// // `FormattedFields` is a formatted representation of the span's -/// // fields, which is stored in its extensions by the `fmt` layer's -/// // `new_span` method. The fields will have been formatted -/// // by the same field formatter that's provided to the event -/// // formatter in the `FmtContext`. -/// let ext = span.extensions(); -/// let fields = &ext -/// .get::>() -/// .expect("will never be `None`"); -/// -/// // Skip formatting the fields if the span had no fields. -/// if !fields.is_empty() { -/// write!(writer, "{{{}}}", fields)?; -/// } -/// write!(writer, ": ")?; -/// } -/// } -/// -/// // Write fields on the event -/// ctx.field_format().format_fields(writer.by_ref(), event)?; -/// -/// writeln!(writer) -/// } -/// } -/// -/// let _subscriber = tracing_subscriber::fmt() -/// .event_format(MyFormatter) -/// .init(); -/// -/// let _span = tracing::info_span!("my_span", answer = 42).entered(); -/// tracing::info!(question = "life, the universe, and everything", "hello world"); -/// ``` -/// -/// This formatter will print events like this: -/// -/// ```text -/// DEBUG yak_shaving::shaver: some-span{field-on-span=foo}: started shaving yak -/// ``` -/// -/// [`layer::Context`]: crate::layer::Context -/// [`fmt::Layer`]: super::Layer -/// [`fmt::Subscriber`]: super::Subscriber -/// [`Event`]: tracing::Event -/// [implements `FormatFields`]: super::FmtContext#impl-FormatFields<'writer> -/// [ANSI terminal escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code -/// [`Writer::has_ansi_escapes`]: Writer::has_ansi_escapes -/// [`ansi_term`]: https://crates.io/crates/ansi_term -/// [`owo-colors`]: https://crates.io/crates/owo-colors -/// [default formatter]: Full -pub trait FormatEvent -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'a> FormatFields<'a> + 'static, -{ - /// Write a log message for `Event` in `Context` to the given [`Writer`]. - fn format_event( - &self, - ctx: &FmtContext<'_, S, N>, - writer: Writer<'_>, - event: &Event<'_>, - ) -> fmt::Result; -} - -impl FormatEvent - for fn(ctx: &FmtContext<'_, S, N>, Writer<'_>, &Event<'_>) -> fmt::Result -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'a> FormatFields<'a> + 'static, -{ - fn format_event( - &self, - ctx: &FmtContext<'_, S, N>, - writer: Writer<'_>, - event: &Event<'_>, - ) -> fmt::Result { - (*self)(ctx, writer, event) - } -} -/// A type that can format a [set of fields] to a [`Writer`]. -/// -/// `FormatFields` is primarily used in the context of [`FmtSubscriber`]. Each -/// time a span or event with fields is recorded, the subscriber will format -/// those fields with its associated `FormatFields` implementation. -/// -/// [set of fields]: crate::field::RecordFields -/// [`FmtSubscriber`]: super::Subscriber -pub trait FormatFields<'writer> { - /// Format the provided `fields` to the provided [`Writer`], returning a result. - fn format_fields(&self, writer: Writer<'writer>, fields: R) -> fmt::Result; - - /// Record additional field(s) on an existing span. - /// - /// By default, this appends a space to the current set of fields if it is - /// non-empty, and then calls `self.format_fields`. If different behavior is - /// required, the default implementation of this method can be overridden. - fn add_fields( - &self, - current: &'writer mut FormattedFields, - fields: &span::Record<'_>, - ) -> fmt::Result { - if !current.fields.is_empty() { - current.fields.push(' '); - } - self.format_fields(current.as_writer(), fields) - } -} - -/// Returns the default configuration for an [event formatter]. -/// -/// Methods on the returned event formatter can be used for further -/// configuration. For example: -/// -/// ```rust -/// let format = tracing_subscriber::fmt::format() -/// .without_time() // Don't include timestamps -/// .with_target(false) // Don't include event targets. -/// .with_level(false) // Don't include event levels. -/// .compact(); // Use a more compact, abbreviated format. -/// -/// // Use the configured formatter when building a new subscriber. -/// tracing_subscriber::fmt() -/// .event_format(format) -/// .init(); -/// ``` -pub fn format() -> Format { - Format::default() -} - -/// Returns the default configuration for a JSON [event formatter]. -#[cfg(feature = "json")] -#[cfg_attr(docsrs, doc(cfg(feature = "json")))] -pub fn json() -> Format { - format().json() -} - -/// Returns a [`FormatFields`] implementation that formats fields using the -/// provided function or closure. -/// -pub fn debug_fn(f: F) -> FieldFn -where - F: Fn(&mut Writer<'_>, &Field, &dyn fmt::Debug) -> fmt::Result + Clone, -{ - FieldFn(f) -} - -/// A writer to which formatted representations of spans and events are written. -/// -/// This type is provided as input to the [`FormatEvent::format_event`] and -/// [`FormatFields::format_fields`] methods, which will write formatted -/// representations of [`Event`]s and [fields] to the `Writer`. -/// -/// This type implements the [`std::fmt::Write`] trait, allowing it to be used -/// with any function that takes an instance of [`std::fmt::Write`]. -/// Additionally, it can be used with the standard library's [`std::write!`] and -/// [`std::writeln!`] macros. -/// -/// Additionally, a `Writer` may expose additional `tracing`-specific -/// information to the formatter implementation. -/// -/// [fields]: tracing_core::field -pub struct Writer<'writer> { - writer: &'writer mut dyn fmt::Write, - // TODO(eliza): add ANSI support - is_ansi: bool, -} - -/// A [`FormatFields`] implementation that formats fields by calling a function -/// or closure. -/// -#[derive(Debug, Clone)] -pub struct FieldFn(F); -/// The [visitor] produced by [`FieldFn`]'s [`MakeVisitor`] implementation. -/// -/// [visitor]: super::super::field::Visit -/// [`MakeVisitor`]: super::super::field::MakeVisitor -pub struct FieldFnVisitor<'a, F> { - f: F, - writer: Writer<'a>, - result: fmt::Result, -} -/// Marker for [`Format`] that indicates that the compact log format should be used. -/// -/// The compact format includes fields from all currently entered spans, after -/// the event's fields. Span names are listed in order before fields are -/// displayed. -/// -/// # Example Output -/// -///
:; cargo run --example fmt-compact
-///     Finished dev [unoptimized + debuginfo] target(s) in 0.08s
-///      Running `target/debug/examples/fmt-compact`
-/// 2022-02-17T19:51:05.809287Z  INFO fmt_compact: preparing to shave yaks number_of_yaks=3
-/// 2022-02-17T19:51:05.809367Z  INFO shaving_yaks: fmt_compact::yak_shave: shaving yaks yaks=3
-/// 2022-02-17T19:51:05.809414Z TRACE shaving_yaks:shave: fmt_compact::yak_shave: hello! I'm gonna shave a yak excitement="yay!" yaks=3 yak=1
-/// 2022-02-17T19:51:05.809443Z TRACE shaving_yaks:shave: fmt_compact::yak_shave: yak shaved successfully yaks=3 yak=1
-/// 2022-02-17T19:51:05.809477Z DEBUG shaving_yaks: yak_events: yak=1 shaved=true yaks=3
-/// 2022-02-17T19:51:05.809500Z TRACE shaving_yaks: fmt_compact::yak_shave: yaks_shaved=1 yaks=3
-/// 2022-02-17T19:51:05.809531Z TRACE shaving_yaks:shave: fmt_compact::yak_shave: hello! I'm gonna shave a yak excitement="yay!" yaks=3 yak=2
-/// 2022-02-17T19:51:05.809554Z TRACE shaving_yaks:shave: fmt_compact::yak_shave: yak shaved successfully yaks=3 yak=2
-/// 2022-02-17T19:51:05.809581Z DEBUG shaving_yaks: yak_events: yak=2 shaved=true yaks=3
-/// 2022-02-17T19:51:05.809606Z TRACE shaving_yaks: fmt_compact::yak_shave: yaks_shaved=2 yaks=3
-/// 2022-02-17T19:51:05.809635Z TRACE shaving_yaks:shave: fmt_compact::yak_shave: hello! I'm gonna shave a yak excitement="yay!" yaks=3 yak=3
-/// 2022-02-17T19:51:05.809664Z  WARN shaving_yaks:shave: fmt_compact::yak_shave: could not locate yak yaks=3 yak=3
-/// 2022-02-17T19:51:05.809693Z DEBUG shaving_yaks: yak_events: yak=3 shaved=false yaks=3
-/// 2022-02-17T19:51:05.809717Z ERROR shaving_yaks: fmt_compact::yak_shave: failed to shave yak yak=3 error=missing yak error.sources=[out of space, out of cash] yaks=3
-/// 2022-02-17T19:51:05.809743Z TRACE shaving_yaks: fmt_compact::yak_shave: yaks_shaved=2 yaks=3
-/// 2022-02-17T19:51:05.809768Z  INFO fmt_compact: yak shaving completed all_yaks_shaved=false
-///
-/// 
-#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct Compact; - -/// Marker for [`Format`] that indicates that the default log format should be used. -/// -/// This formatter shows the span context before printing event data. Spans are -/// displayed including their names and fields. -/// -/// # Example Output -/// -///
:; cargo run --example fmt
-///     Finished dev [unoptimized + debuginfo] target(s) in 0.08s
-///      Running `target/debug/examples/fmt`
-/// 2022-02-15T18:40:14.289898Z  INFO fmt: preparing to shave yaks number_of_yaks=3
-/// 2022-02-15T18:40:14.289974Z  INFO shaving_yaks{yaks=3}: fmt::yak_shave: shaving yaks
-/// 2022-02-15T18:40:14.290011Z TRACE shaving_yaks{yaks=3}:shave{yak=1}: fmt::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
-/// 2022-02-15T18:40:14.290038Z TRACE shaving_yaks{yaks=3}:shave{yak=1}: fmt::yak_shave: yak shaved successfully
-/// 2022-02-15T18:40:14.290070Z DEBUG shaving_yaks{yaks=3}: yak_events: yak=1 shaved=true
-/// 2022-02-15T18:40:14.290089Z TRACE shaving_yaks{yaks=3}: fmt::yak_shave: yaks_shaved=1
-/// 2022-02-15T18:40:14.290114Z TRACE shaving_yaks{yaks=3}:shave{yak=2}: fmt::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
-/// 2022-02-15T18:40:14.290134Z TRACE shaving_yaks{yaks=3}:shave{yak=2}: fmt::yak_shave: yak shaved successfully
-/// 2022-02-15T18:40:14.290157Z DEBUG shaving_yaks{yaks=3}: yak_events: yak=2 shaved=true
-/// 2022-02-15T18:40:14.290174Z TRACE shaving_yaks{yaks=3}: fmt::yak_shave: yaks_shaved=2
-/// 2022-02-15T18:40:14.290198Z TRACE shaving_yaks{yaks=3}:shave{yak=3}: fmt::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
-/// 2022-02-15T18:40:14.290222Z  WARN shaving_yaks{yaks=3}:shave{yak=3}: fmt::yak_shave: could not locate yak
-/// 2022-02-15T18:40:14.290247Z DEBUG shaving_yaks{yaks=3}: yak_events: yak=3 shaved=false
-/// 2022-02-15T18:40:14.290268Z ERROR shaving_yaks{yaks=3}: fmt::yak_shave: failed to shave yak yak=3 error=missing yak error.sources=[out of space, out of cash]
-/// 2022-02-15T18:40:14.290287Z TRACE shaving_yaks{yaks=3}: fmt::yak_shave: yaks_shaved=2
-/// 2022-02-15T18:40:14.290309Z  INFO fmt: yak shaving completed. all_yaks_shaved=false
-/// 
-#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct Full; - -/// A pre-configured event formatter. -/// -/// You will usually want to use this as the `FormatEvent` for a `FmtSubscriber`. -/// -/// The default logging format, [`Full`] includes all fields in each event and its containing -/// spans. The [`Compact`] logging format is intended to produce shorter log -/// lines; it displays each event's fields, along with fields from the current -/// span context, but other information is abbreviated. The [`Pretty`] logging -/// format is an extra-verbose, multi-line human-readable logging format -/// intended for use in development. -#[derive(Debug, Clone)] -pub struct Format { - format: F, - pub(crate) timer: T, - pub(crate) ansi: Option, - pub(crate) display_timestamp: bool, - pub(crate) display_target: bool, - pub(crate) display_level: bool, - pub(crate) display_thread_id: bool, - pub(crate) display_thread_name: bool, - pub(crate) display_filename: bool, - pub(crate) display_line_number: bool, -} - -// === impl Writer === - -impl<'writer> Writer<'writer> { - // TODO(eliza): consider making this a public API? - // We may not want to do that if we choose to expose specialized - // constructors instead (e.g. `from_string` that stores whether the string - // is empty...?) - pub(crate) fn new(writer: &'writer mut impl fmt::Write) -> Self { - Self { - writer: writer as &mut dyn fmt::Write, - is_ansi: false, - } - } - - // TODO(eliza): consider making this a public API? - pub(crate) fn with_ansi(self, is_ansi: bool) -> Self { - Self { is_ansi, ..self } - } - - /// Return a new `Writer` that mutably borrows `self`. - /// - /// This can be used to temporarily borrow a `Writer` to pass a new `Writer` - /// to a function that takes a `Writer` by value, allowing the original writer - /// to still be used once that function returns. - pub fn by_ref(&mut self) -> Writer<'_> { - let is_ansi = self.is_ansi; - Writer { - writer: self as &mut dyn fmt::Write, - is_ansi, - } - } - - /// Writes a string slice into this `Writer`, returning whether the write succeeded. - /// - /// This method can only succeed if the entire string slice was successfully - /// written, and this method will not return until all data has been written - /// or an error occurs. - /// - /// This is identical to calling the [`write_str` method] from the `Writer`'s - /// [`std::fmt::Write`] implementation. However, it is also provided as an - /// inherent method, so that `Writer`s can be used without needing to import the - /// [`std::fmt::Write`] trait. - /// - /// # Errors - /// - /// This function will return an instance of [`std::fmt::Error`] on error. - /// - /// [`write_str` method]: std::fmt::Write::write_str - #[inline] - pub fn write_str(&mut self, s: &str) -> fmt::Result { - self.writer.write_str(s) - } - - /// Writes a [`char`] into this writer, returning whether the write succeeded. - /// - /// A single [`char`] may be encoded as more than one byte. - /// This method can only succeed if the entire byte sequence was successfully - /// written, and this method will not return until all data has been - /// written or an error occurs. - /// - /// This is identical to calling the [`write_char` method] from the `Writer`'s - /// [`std::fmt::Write`] implementation. However, it is also provided as an - /// inherent method, so that `Writer`s can be used without needing to import the - /// [`std::fmt::Write`] trait. - /// - /// # Errors - /// - /// This function will return an instance of [`std::fmt::Error`] on error. - /// - /// [`write_char` method]: std::fmt::Write::write_char - #[inline] - pub fn write_char(&mut self, c: char) -> fmt::Result { - self.writer.write_char(c) - } - - /// Glue for usage of the [`write!`] macro with `Writer`s. - /// - /// This method should generally not be invoked manually, but rather through - /// the [`write!`] macro itself. - /// - /// This is identical to calling the [`write_fmt` method] from the `Writer`'s - /// [`std::fmt::Write`] implementation. However, it is also provided as an - /// inherent method, so that `Writer`s can be used with the [`write!` macro] - /// without needing to import the - /// [`std::fmt::Write`] trait. - /// - /// [`write_fmt` method]: std::fmt::Write::write_fmt - pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { - self.writer.write_fmt(args) - } - - /// Returns `true` if [ANSI escape codes] may be used to add colors - /// and other formatting when writing to this `Writer`. - /// - /// If this returns `false`, formatters should not emit ANSI escape codes. - /// - /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code - pub fn has_ansi_escapes(&self) -> bool { - self.is_ansi - } - - pub(in crate::fmt::format) fn bold(&self) -> Style { - #[cfg(feature = "ansi")] - { - if self.is_ansi { - return Style::new().bold(); - } - } - - Style::new() - } - - pub(in crate::fmt::format) fn dimmed(&self) -> Style { - #[cfg(feature = "ansi")] - { - if self.is_ansi { - return Style::new().dimmed(); - } - } - - Style::new() - } - - pub(in crate::fmt::format) fn italic(&self) -> Style { - #[cfg(feature = "ansi")] - { - if self.is_ansi { - return Style::new().italic(); - } - } - - Style::new() - } -} - -impl fmt::Write for Writer<'_> { - #[inline] - fn write_str(&mut self, s: &str) -> fmt::Result { - Writer::write_str(self, s) - } - - #[inline] - fn write_char(&mut self, c: char) -> fmt::Result { - Writer::write_char(self, c) - } - - #[inline] - fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { - Writer::write_fmt(self, args) - } -} - -impl fmt::Debug for Writer<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Writer") - .field("writer", &format_args!("<&mut dyn fmt::Write>")) - .field("is_ansi", &self.is_ansi) - .finish() - } -} - -// === impl Format === - -impl Default for Format { - fn default() -> Self { - Format { - format: Full, - timer: SystemTime, - ansi: None, - display_timestamp: true, - display_target: true, - display_level: true, - display_thread_id: false, - display_thread_name: false, - display_filename: false, - display_line_number: false, - } - } -} - -impl Format { - /// Use a less verbose output format. - /// - /// See [`Compact`]. - pub fn compact(self) -> Format { - Format { - format: Compact, - timer: self.timer, - ansi: self.ansi, - display_target: self.display_target, - display_timestamp: self.display_timestamp, - display_level: self.display_level, - display_thread_id: self.display_thread_id, - display_thread_name: self.display_thread_name, - display_filename: self.display_filename, - display_line_number: self.display_line_number, - } - } - - /// Use an excessively pretty, human-readable output format. - /// - /// See [`Pretty`]. - /// - /// Note that this requires the "ansi" feature to be enabled. - /// - /// # Options - /// - /// [`Format::with_ansi`] can be used to disable ANSI terminal escape codes (which enable - /// formatting such as colors, bold, italic, etc) in event formatting. However, a field - /// formatter must be manually provided to avoid ANSI in the formatting of parent spans, like - /// so: - /// - /// ``` - /// # use tracing_subscriber::fmt::format; - /// tracing_subscriber::fmt() - /// .pretty() - /// .with_ansi(false) - /// .fmt_fields(format::PrettyFields::new().with_ansi(false)) - /// // ... other settings ... - /// .init(); - /// ``` - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] - pub fn pretty(self) -> Format { - Format { - format: Pretty::default(), - timer: self.timer, - ansi: self.ansi, - display_target: self.display_target, - display_timestamp: self.display_timestamp, - display_level: self.display_level, - display_thread_id: self.display_thread_id, - display_thread_name: self.display_thread_name, - display_filename: true, - display_line_number: true, - } - } - - /// Use the full JSON format. - /// - /// The full format includes fields from all entered spans. - /// - /// # Example Output - /// - /// ```ignore,json - /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate","fields":{"message":"some message", "key": "value"}} - /// ``` - /// - /// # Options - /// - /// - [`Format::flatten_event`] can be used to enable flattening event fields into the root - /// object. - #[cfg(feature = "json")] - #[cfg_attr(docsrs, doc(cfg(feature = "json")))] - pub fn json(self) -> Format { - Format { - format: Json::default(), - timer: self.timer, - ansi: self.ansi, - display_target: self.display_target, - display_timestamp: self.display_timestamp, - display_level: self.display_level, - display_thread_id: self.display_thread_id, - display_thread_name: self.display_thread_name, - display_filename: self.display_filename, - display_line_number: self.display_line_number, - } - } - - /// Use the given [`timer`] for log message timestamps. - /// - /// See [`time` module] for the provided timer implementations. - /// - /// Note that using the `"time"` feature flag enables the - /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the - /// [`time` crate] to provide more sophisticated timestamp formatting - /// options. - /// - /// [`timer`]: super::time::FormatTime - /// [`time` module]: mod@super::time - /// [`UtcTime`]: super::time::UtcTime - /// [`LocalTime`]: super::time::LocalTime - /// [`time` crate]: https://docs.rs/time/0.3 - pub fn with_timer(self, timer: T2) -> Format { - Format { - format: self.format, - timer, - ansi: self.ansi, - display_target: self.display_target, - display_timestamp: self.display_timestamp, - display_level: self.display_level, - display_thread_id: self.display_thread_id, - display_thread_name: self.display_thread_name, - display_filename: self.display_filename, - display_line_number: self.display_line_number, - } - } - - /// Do not emit timestamps with log messages. - pub fn without_time(self) -> Format { - Format { - format: self.format, - timer: (), - ansi: self.ansi, - display_timestamp: false, - display_target: self.display_target, - display_level: self.display_level, - display_thread_id: self.display_thread_id, - display_thread_name: self.display_thread_name, - display_filename: self.display_filename, - display_line_number: self.display_line_number, - } - } - - /// Enable ANSI terminal colors for formatted output. - pub fn with_ansi(self, ansi: bool) -> Format { - Format { - ansi: Some(ansi), - ..self - } - } - - /// Sets whether or not an event's target is displayed. - pub fn with_target(self, display_target: bool) -> Format { - Format { - display_target, - ..self - } - } - - /// Sets whether or not an event's level is displayed. - pub fn with_level(self, display_level: bool) -> Format { - Format { - display_level, - ..self - } - } - - /// Sets whether or not the [thread ID] of the current thread is displayed - /// when formatting events. - /// - /// [thread ID]: std::thread::ThreadId - pub fn with_thread_ids(self, display_thread_id: bool) -> Format { - Format { - display_thread_id, - ..self - } - } - - /// Sets whether or not the [name] of the current thread is displayed - /// when formatting events. - /// - /// [name]: std::thread#naming-threads - pub fn with_thread_names(self, display_thread_name: bool) -> Format { - Format { - display_thread_name, - ..self - } - } - - /// Sets whether or not an event's [source code file path][file] is - /// displayed. - /// - /// [file]: tracing_core::Metadata::file - pub fn with_file(self, display_filename: bool) -> Format { - Format { - display_filename, - ..self - } - } - - /// Sets whether or not an event's [source code line number][line] is - /// displayed. - /// - /// [line]: tracing_core::Metadata::line - pub fn with_line_number(self, display_line_number: bool) -> Format { - Format { - display_line_number, - ..self - } - } - - /// Sets whether or not the source code location from which an event - /// originated is displayed. - /// - /// This is equivalent to calling [`Format::with_file`] and - /// [`Format::with_line_number`] with the same value. - pub fn with_source_location(self, display_location: bool) -> Self { - self.with_line_number(display_location) - .with_file(display_location) - } - - #[inline] - fn format_timestamp(&self, writer: &mut Writer<'_>) -> fmt::Result - where - T: FormatTime, - { - // If timestamps are disabled, do nothing. - if !self.display_timestamp { - return Ok(()); - } - - // If ANSI color codes are enabled, format the timestamp with ANSI - // colors. - #[cfg(feature = "ansi")] - { - if writer.has_ansi_escapes() { - let style = Style::new().dimmed(); - write!(writer, "{}", style.prefix())?; - - // If getting the timestamp failed, don't bail --- only bail on - // formatting errors. - if self.timer.format_time(writer).is_err() { - writer.write_str("")?; - } - - write!(writer, "{} ", style.suffix())?; - return Ok(()); - } - } - - // Otherwise, just format the timestamp without ANSI formatting. - // If getting the timestamp failed, don't bail --- only bail on - // formatting errors. - if self.timer.format_time(writer).is_err() { - writer.write_str("")?; - } - writer.write_char(' ') - } -} - -#[cfg(feature = "json")] -#[cfg_attr(docsrs, doc(cfg(feature = "json")))] -impl Format { - /// Use the full JSON format with the event's event fields flattened. - /// - /// # Example Output - /// - /// ```ignore,json - /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate", "message":"some message", "key": "value"} - /// ``` - /// See [`Json`][super::format::Json]. - #[cfg(feature = "json")] - #[cfg_attr(docsrs, doc(cfg(feature = "json")))] - pub fn flatten_event(mut self, flatten_event: bool) -> Format { - self.format.flatten_event(flatten_event); - self - } - - /// Sets whether or not the formatter will include the current span in - /// formatted events. - /// - /// See [`format::Json`][Json] - #[cfg(feature = "json")] - #[cfg_attr(docsrs, doc(cfg(feature = "json")))] - pub fn with_current_span(mut self, display_current_span: bool) -> Format { - self.format.with_current_span(display_current_span); - self - } - - /// Sets whether or not the formatter will include a list (from root to - /// leaf) of all currently entered spans in formatted events. - /// - /// See [`format::Json`][Json] - #[cfg(feature = "json")] - #[cfg_attr(docsrs, doc(cfg(feature = "json")))] - pub fn with_span_list(mut self, display_span_list: bool) -> Format { - self.format.with_span_list(display_span_list); - self - } -} - -impl FormatEvent for Format -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'a> FormatFields<'a> + 'static, - T: FormatTime, -{ - fn format_event( - &self, - ctx: &FmtContext<'_, S, N>, - mut writer: Writer<'_>, - event: &Event<'_>, - ) -> fmt::Result { - #[cfg(feature = "tracing-log")] - let normalized_meta = event.normalized_metadata(); - #[cfg(feature = "tracing-log")] - let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - #[cfg(not(feature = "tracing-log"))] - let meta = event.metadata(); - - // if the `Format` struct *also* has an ANSI color configuration, - // override the writer...the API for configuring ANSI color codes on the - // `Format` struct is deprecated, but we still need to honor those - // configurations. - if let Some(ansi) = self.ansi { - writer = writer.with_ansi(ansi); - } - - self.format_timestamp(&mut writer)?; - - if self.display_level { - let fmt_level = { - #[cfg(feature = "ansi")] - { - FmtLevel::new(meta.level(), writer.has_ansi_escapes()) - } - #[cfg(not(feature = "ansi"))] - { - FmtLevel::new(meta.level()) - } - }; - write!(writer, "{} ", fmt_level)?; - } - - if self.display_thread_name { - let current_thread = std::thread::current(); - match current_thread.name() { - Some(name) => { - write!(writer, "{} ", FmtThreadName::new(name))?; - } - // fall-back to thread id when name is absent and ids are not enabled - None if !self.display_thread_id => { - write!(writer, "{:0>2?} ", current_thread.id())?; - } - _ => {} - } - } - - if self.display_thread_id { - write!(writer, "{:0>2?} ", std::thread::current().id())?; - } - - let dimmed = writer.dimmed(); - - if let Some(scope) = ctx.event_scope() { - let bold = writer.bold(); - - let mut seen = false; - - for span in scope.from_root() { - write!(writer, "{}", bold.paint(span.metadata().name()))?; - seen = true; - - let ext = span.extensions(); - if let Some(fields) = &ext.get::>() { - if !fields.is_empty() { - write!(writer, "{}{}{}", bold.paint("{"), fields, bold.paint("}"))?; - } - } - write!(writer, "{}", dimmed.paint(":"))?; - } - - if seen { - writer.write_char(' ')?; - } - }; - - if self.display_target { - write!( - writer, - "{}{} ", - dimmed.paint(meta.target()), - dimmed.paint(":") - )?; - } - - let line_number = if self.display_line_number { - meta.line() - } else { - None - }; - - if self.display_filename { - if let Some(filename) = meta.file() { - write!( - writer, - "{}{}{}", - dimmed.paint(filename), - dimmed.paint(":"), - if line_number.is_some() { "" } else { " " } - )?; - } - } - - if let Some(line_number) = line_number { - write!( - writer, - "{}{}:{} ", - dimmed.prefix(), - line_number, - dimmed.suffix() - )?; - } - - ctx.format_fields(writer.by_ref(), event)?; - writeln!(writer) - } -} - -impl FormatEvent for Format -where - S: Subscriber + for<'a> LookupSpan<'a>, - N: for<'a> FormatFields<'a> + 'static, - T: FormatTime, -{ - fn format_event( - &self, - ctx: &FmtContext<'_, S, N>, - mut writer: Writer<'_>, - event: &Event<'_>, - ) -> fmt::Result { - #[cfg(feature = "tracing-log")] - let normalized_meta = event.normalized_metadata(); - #[cfg(feature = "tracing-log")] - let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - #[cfg(not(feature = "tracing-log"))] - let meta = event.metadata(); - - // if the `Format` struct *also* has an ANSI color configuration, - // override the writer...the API for configuring ANSI color codes on the - // `Format` struct is deprecated, but we still need to honor those - // configurations. - if let Some(ansi) = self.ansi { - writer = writer.with_ansi(ansi); - } - - self.format_timestamp(&mut writer)?; - - if self.display_level { - let fmt_level = { - #[cfg(feature = "ansi")] - { - FmtLevel::new(meta.level(), writer.has_ansi_escapes()) - } - #[cfg(not(feature = "ansi"))] - { - FmtLevel::new(meta.level()) - } - }; - write!(writer, "{} ", fmt_level)?; - } - - if self.display_thread_name { - let current_thread = std::thread::current(); - match current_thread.name() { - Some(name) => { - write!(writer, "{} ", FmtThreadName::new(name))?; - } - // fall-back to thread id when name is absent and ids are not enabled - None if !self.display_thread_id => { - write!(writer, "{:0>2?} ", current_thread.id())?; - } - _ => {} - } - } - - if self.display_thread_id { - write!(writer, "{:0>2?} ", std::thread::current().id())?; - } - - let fmt_ctx = { - #[cfg(feature = "ansi")] - { - FmtCtx::new(ctx, event.parent(), writer.has_ansi_escapes()) - } - #[cfg(not(feature = "ansi"))] - { - FmtCtx::new(&ctx, event.parent()) - } - }; - write!(writer, "{}", fmt_ctx)?; - - let bold = writer.bold(); - let dimmed = writer.dimmed(); - - let mut needs_space = false; - if self.display_target { - write!(writer, "{}{}", bold.paint(meta.target()), dimmed.paint(":"))?; - needs_space = true; - } - - if self.display_filename { - if let Some(filename) = meta.file() { - if self.display_target { - writer.write_char(' ')?; - } - write!(writer, "{}{}", bold.paint(filename), dimmed.paint(":"))?; - needs_space = true; - } - } - - if self.display_line_number { - if let Some(line_number) = meta.line() { - write!( - writer, - "{}{}{}{}", - bold.prefix(), - line_number, - bold.suffix(), - dimmed.paint(":") - )?; - needs_space = true; - } - } - - if needs_space { - writer.write_char(' ')?; - } - - ctx.format_fields(writer.by_ref(), event)?; - - for span in ctx - .event_scope() - .into_iter() - .flat_map(crate::registry::Scope::from_root) - { - let exts = span.extensions(); - if let Some(fields) = exts.get::>() { - if !fields.is_empty() { - write!(writer, " {}", dimmed.paint(&fields.fields))?; - } - } - } - writeln!(writer) - } -} - -// === impl FormatFields === -impl<'writer, M> FormatFields<'writer> for M -where - M: MakeOutput, fmt::Result>, - M::Visitor: VisitFmt + VisitOutput, -{ - fn format_fields(&self, writer: Writer<'writer>, fields: R) -> fmt::Result { - let mut v = self.make_visitor(writer); - fields.record(&mut v); - v.finish() - } -} - -/// The default [`FormatFields`] implementation. -/// -#[derive(Debug)] -pub struct DefaultFields { - // reserve the ability to add fields to this without causing a breaking - // change in the future. - _private: (), -} - -/// The [visitor] produced by [`DefaultFields`]'s [`MakeVisitor`] implementation. -/// -/// [visitor]: super::super::field::Visit -/// [`MakeVisitor`]: super::super::field::MakeVisitor -#[derive(Debug)] -pub struct DefaultVisitor<'a> { - writer: Writer<'a>, - is_empty: bool, - result: fmt::Result, -} - -impl DefaultFields { - /// Returns a new default [`FormatFields`] implementation. - /// - pub fn new() -> Self { - Self { _private: () } - } -} - -impl Default for DefaultFields { - fn default() -> Self { - Self::new() - } -} - -impl<'a> MakeVisitor> for DefaultFields { - type Visitor = DefaultVisitor<'a>; - - #[inline] - fn make_visitor(&self, target: Writer<'a>) -> Self::Visitor { - DefaultVisitor::new(target, true) - } -} - -// === impl DefaultVisitor === - -impl<'a> DefaultVisitor<'a> { - /// Returns a new default visitor that formats to the provided `writer`. - /// - /// # Arguments - /// - `writer`: the writer to format to. - /// - `is_empty`: whether or not any fields have been previously written to - /// that writer. - pub fn new(writer: Writer<'a>, is_empty: bool) -> Self { - Self { - writer, - is_empty, - result: Ok(()), - } - } - - fn maybe_pad(&mut self) { - if self.is_empty { - self.is_empty = false; - } else { - self.result = write!(self.writer, " "); - } - } -} - -impl<'a> field::Visit for DefaultVisitor<'a> { - fn record_str(&mut self, field: &Field, value: &str) { - if self.result.is_err() { - return; - } - - if field.name() == "message" { - self.record_debug(field, &format_args!("{}", value)) - } else { - self.record_debug(field, &value) - } - } - - fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { - if let Some(source) = value.source() { - let italic = self.writer.italic(); - self.record_debug( - field, - &format_args!( - "{} {}{}{}{}", - value, - italic.paint(field.name()), - italic.paint(".sources"), - self.writer.dimmed().paint("="), - ErrorSourceList(source) - ), - ) - } else { - self.record_debug(field, &format_args!("{}", value)) - } - } - - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - if self.result.is_err() { - return; - } - - self.maybe_pad(); - self.result = match field.name() { - "message" => write!(self.writer, "{:?}", value), - // Skip fields that are actually log metadata that have already been handled - #[cfg(feature = "tracing-log")] - name if name.starts_with("log.") => Ok(()), - name if name.starts_with("r#") => write!( - self.writer, - "{}{}{:?}", - self.writer.italic().paint(&name[2..]), - self.writer.dimmed().paint("="), - value - ), - name => write!( - self.writer, - "{}{}{:?}", - self.writer.italic().paint(name), - self.writer.dimmed().paint("="), - value - ), - }; - } -} - -impl<'a> crate::field::VisitOutput for DefaultVisitor<'a> { - fn finish(self) -> fmt::Result { - self.result - } -} - -impl<'a> crate::field::VisitFmt for DefaultVisitor<'a> { - fn writer(&mut self) -> &mut dyn fmt::Write { - &mut self.writer - } -} - -/// Renders an error into a list of sources, *including* the error -struct ErrorSourceList<'a>(&'a (dyn std::error::Error + 'static)); - -impl<'a> Display for ErrorSourceList<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut list = f.debug_list(); - let mut curr = Some(self.0); - while let Some(curr_err) = curr { - list.entry(&format_args!("{}", curr_err)); - curr = curr_err.source(); - } - list.finish() - } -} - -struct FmtCtx<'a, S, N> { - ctx: &'a FmtContext<'a, S, N>, - span: Option<&'a span::Id>, - #[cfg(feature = "ansi")] - ansi: bool, -} - -impl<'a, S, N: 'a> FmtCtx<'a, S, N> -where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static, -{ - #[cfg(feature = "ansi")] - pub(crate) fn new( - ctx: &'a FmtContext<'_, S, N>, - span: Option<&'a span::Id>, - ansi: bool, - ) -> Self { - Self { ctx, span, ansi } - } - - #[cfg(not(feature = "ansi"))] - pub(crate) fn new(ctx: &'a FmtContext<'_, S, N>, span: Option<&'a span::Id>) -> Self { - Self { ctx, span } - } - - fn bold(&self) -> Style { - #[cfg(feature = "ansi")] - { - if self.ansi { - return Style::new().bold(); - } - } - - Style::new() - } -} - -impl<'a, S, N: 'a> fmt::Display for FmtCtx<'a, S, N> -where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - N: for<'writer> FormatFields<'writer> + 'static, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let bold = self.bold(); - let mut seen = false; - - let span = self - .span - .and_then(|id| self.ctx.ctx.span(id)) - .or_else(|| self.ctx.ctx.lookup_current()); - - let scope = span.into_iter().flat_map(|span| span.scope().from_root()); - - for span in scope { - seen = true; - write!(f, "{}:", bold.paint(span.metadata().name()))?; - } - - if seen { - f.write_char(' ')?; - } - Ok(()) - } -} - -#[cfg(not(feature = "ansi"))] -struct Style; - -#[cfg(not(feature = "ansi"))] -impl Style { - fn new() -> Self { - Style - } - - fn bold(self) -> Self { - self - } - - fn paint(&self, d: impl fmt::Display) -> impl fmt::Display { - d - } - - fn prefix(&self) -> impl fmt::Display { - "" - } - - fn suffix(&self) -> impl fmt::Display { - "" - } -} - -struct FmtThreadName<'a> { - name: &'a str, -} - -impl<'a> FmtThreadName<'a> { - pub(crate) fn new(name: &'a str) -> Self { - Self { name } - } -} - -impl<'a> fmt::Display for FmtThreadName<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use std::sync::atomic::{ - AtomicUsize, - Ordering::{AcqRel, Acquire, Relaxed}, - }; - - // Track the longest thread name length we've seen so far in an atomic, - // so that it can be updated by any thread. - static MAX_LEN: AtomicUsize = AtomicUsize::new(0); - let len = self.name.len(); - // Snapshot the current max thread name length. - let mut max_len = MAX_LEN.load(Relaxed); - - while len > max_len { - // Try to set a new max length, if it is still the value we took a - // snapshot of. - match MAX_LEN.compare_exchange(max_len, len, AcqRel, Acquire) { - // We successfully set the new max value - Ok(_) => break, - // Another thread set a new max value since we last observed - // it! It's possible that the new length is actually longer than - // ours, so we'll loop again and check whether our length is - // still the longest. If not, we'll just use the newer value. - Err(actual) => max_len = actual, - } - } - - // pad thread name using `max_len` - write!(f, "{:>width$}", self.name, width = max_len) - } -} - -struct FmtLevel<'a> { - level: &'a Level, - #[cfg(feature = "ansi")] - ansi: bool, -} - -impl<'a> FmtLevel<'a> { - #[cfg(feature = "ansi")] - pub(crate) fn new(level: &'a Level, ansi: bool) -> Self { - Self { level, ansi } - } - - #[cfg(not(feature = "ansi"))] - pub(crate) fn new(level: &'a Level) -> Self { - Self { level } - } -} - -const TRACE_STR: &str = "TRACE"; -const DEBUG_STR: &str = "DEBUG"; -const INFO_STR: &str = " INFO"; -const WARN_STR: &str = " WARN"; -const ERROR_STR: &str = "ERROR"; - -#[cfg(not(feature = "ansi"))] -impl<'a> fmt::Display for FmtLevel<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self.level { - Level::TRACE => f.pad(TRACE_STR), - Level::DEBUG => f.pad(DEBUG_STR), - Level::INFO => f.pad(INFO_STR), - Level::WARN => f.pad(WARN_STR), - Level::ERROR => f.pad(ERROR_STR), - } - } -} - -#[cfg(feature = "ansi")] -impl<'a> fmt::Display for FmtLevel<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.ansi { - match *self.level { - Level::TRACE => write!(f, "{}", Colour::Purple.paint(TRACE_STR)), - Level::DEBUG => write!(f, "{}", Colour::Blue.paint(DEBUG_STR)), - Level::INFO => write!(f, "{}", Colour::Green.paint(INFO_STR)), - Level::WARN => write!(f, "{}", Colour::Yellow.paint(WARN_STR)), - Level::ERROR => write!(f, "{}", Colour::Red.paint(ERROR_STR)), - } - } else { - match *self.level { - Level::TRACE => f.pad(TRACE_STR), - Level::DEBUG => f.pad(DEBUG_STR), - Level::INFO => f.pad(INFO_STR), - Level::WARN => f.pad(WARN_STR), - Level::ERROR => f.pad(ERROR_STR), - } - } - } -} - -// === impl FieldFn === - -impl<'a, F> MakeVisitor> for FieldFn -where - F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result + Clone, -{ - type Visitor = FieldFnVisitor<'a, F>; - - fn make_visitor(&self, writer: Writer<'a>) -> Self::Visitor { - FieldFnVisitor { - writer, - f: self.0.clone(), - result: Ok(()), - } - } -} - -impl<'a, F> Visit for FieldFnVisitor<'a, F> -where - F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result, -{ - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - if self.result.is_ok() { - self.result = (self.f)(&mut self.writer, field, value) - } - } -} - -impl<'a, F> VisitOutput for FieldFnVisitor<'a, F> -where - F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result, -{ - fn finish(self) -> fmt::Result { - self.result - } -} - -impl<'a, F> VisitFmt for FieldFnVisitor<'a, F> -where - F: Fn(&mut Writer<'a>, &Field, &dyn fmt::Debug) -> fmt::Result, -{ - fn writer(&mut self) -> &mut dyn fmt::Write { - &mut self.writer - } -} - -impl<'a, F> fmt::Debug for FieldFnVisitor<'a, F> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FieldFnVisitor") - .field("f", &format_args!("{}", std::any::type_name::())) - .field("writer", &self.writer) - .field("result", &self.result) - .finish() - } -} - -// === printing synthetic Span events === - -/// Configures what points in the span lifecycle are logged as events. -/// -/// See also [`with_span_events`](super::SubscriberBuilder.html::with_span_events). -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)] -pub struct FmtSpan(u8); - -impl FmtSpan { - /// one event when span is created - pub const NEW: FmtSpan = FmtSpan(1 << 0); - /// one event per enter of a span - pub const ENTER: FmtSpan = FmtSpan(1 << 1); - /// one event per exit of a span - pub const EXIT: FmtSpan = FmtSpan(1 << 2); - /// one event when the span is dropped - pub const CLOSE: FmtSpan = FmtSpan(1 << 3); - - /// spans are ignored (this is the default) - pub const NONE: FmtSpan = FmtSpan(0); - /// one event per enter/exit of a span - pub const ACTIVE: FmtSpan = FmtSpan(FmtSpan::ENTER.0 | FmtSpan::EXIT.0); - /// events at all points (new, enter, exit, drop) - pub const FULL: FmtSpan = - FmtSpan(FmtSpan::NEW.0 | FmtSpan::ENTER.0 | FmtSpan::EXIT.0 | FmtSpan::CLOSE.0); - - /// Check whether or not a certain flag is set for this [`FmtSpan`] - fn contains(&self, other: FmtSpan) -> bool { - self.clone() & other.clone() == other - } -} - -macro_rules! impl_fmt_span_bit_op { - ($trait:ident, $func:ident, $op:tt) => { - impl std::ops::$trait for FmtSpan { - type Output = FmtSpan; - - fn $func(self, rhs: Self) -> Self::Output { - FmtSpan(self.0 $op rhs.0) - } - } - }; -} - -macro_rules! impl_fmt_span_bit_assign_op { - ($trait:ident, $func:ident, $op:tt) => { - impl std::ops::$trait for FmtSpan { - fn $func(&mut self, rhs: Self) { - *self = FmtSpan(self.0 $op rhs.0) - } - } - }; -} - -impl_fmt_span_bit_op!(BitAnd, bitand, &); -impl_fmt_span_bit_op!(BitOr, bitor, |); -impl_fmt_span_bit_op!(BitXor, bitxor, ^); - -impl_fmt_span_bit_assign_op!(BitAndAssign, bitand_assign, &); -impl_fmt_span_bit_assign_op!(BitOrAssign, bitor_assign, |); -impl_fmt_span_bit_assign_op!(BitXorAssign, bitxor_assign, ^); - -impl Debug for FmtSpan { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut wrote_flag = false; - let mut write_flags = |flag, flag_str| -> fmt::Result { - if self.contains(flag) { - if wrote_flag { - f.write_str(" | ")?; - } - - f.write_str(flag_str)?; - wrote_flag = true; - } - - Ok(()) - }; - - if FmtSpan::NONE | self.clone() == FmtSpan::NONE { - f.write_str("FmtSpan::NONE")?; - } else { - write_flags(FmtSpan::NEW, "FmtSpan::NEW")?; - write_flags(FmtSpan::ENTER, "FmtSpan::ENTER")?; - write_flags(FmtSpan::EXIT, "FmtSpan::EXIT")?; - write_flags(FmtSpan::CLOSE, "FmtSpan::CLOSE")?; - } - - Ok(()) - } -} - -pub(super) struct FmtSpanConfig { - pub(super) kind: FmtSpan, - pub(super) fmt_timing: bool, -} - -impl FmtSpanConfig { - pub(super) fn without_time(self) -> Self { - Self { - kind: self.kind, - fmt_timing: false, - } - } - pub(super) fn with_kind(self, kind: FmtSpan) -> Self { - Self { - kind, - fmt_timing: self.fmt_timing, - } - } - pub(super) fn trace_new(&self) -> bool { - self.kind.contains(FmtSpan::NEW) - } - pub(super) fn trace_enter(&self) -> bool { - self.kind.contains(FmtSpan::ENTER) - } - pub(super) fn trace_exit(&self) -> bool { - self.kind.contains(FmtSpan::EXIT) - } - pub(super) fn trace_close(&self) -> bool { - self.kind.contains(FmtSpan::CLOSE) - } -} - -impl Debug for FmtSpanConfig { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.kind.fmt(f) - } -} - -impl Default for FmtSpanConfig { - fn default() -> Self { - Self { - kind: FmtSpan::NONE, - fmt_timing: true, - } - } -} - -pub(super) struct TimingDisplay(pub(super) u64); -impl Display for TimingDisplay { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut t = self.0 as f64; - for unit in ["ns", "µs", "ms", "s"].iter() { - if t < 10.0 { - return write!(f, "{:.2}{}", t, unit); - } else if t < 100.0 { - return write!(f, "{:.1}{}", t, unit); - } else if t < 1000.0 { - return write!(f, "{:.0}{}", t, unit); - } - t /= 1000.0; - } - write!(f, "{:.0}s", t * 1000.0) - } -} - -#[cfg(test)] -pub(super) mod test { - use crate::fmt::{test::MockMakeWriter, time::FormatTime}; - use tracing::{ - self, - dispatcher::{set_default, Dispatch}, - subscriber::with_default, - }; - - use super::*; - - use regex::Regex; - use std::{fmt, path::Path}; - - pub(crate) struct MockTime; - impl FormatTime for MockTime { - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - write!(w, "fake time") - } - } - - #[test] - fn disable_everything() { - // This test reproduces https://github.com/tokio-rs/tracing/issues/1354 - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .without_time() - .with_level(false) - .with_target(false) - .with_thread_ids(false) - .with_thread_names(false); - #[cfg(feature = "ansi")] - let subscriber = subscriber.with_ansi(false); - assert_info_hello(subscriber, make_writer, "hello\n") - } - - fn test_ansi( - is_ansi: bool, - expected: &str, - builder: crate::fmt::SubscriberBuilder>, - ) where - Format: FormatEvent, - T: Send + Sync + 'static, - { - let make_writer = MockMakeWriter::default(); - let subscriber = builder - .with_writer(make_writer.clone()) - .with_ansi(is_ansi) - .with_timer(MockTime); - run_test(subscriber, make_writer, expected) - } - - #[cfg(not(feature = "ansi"))] - fn test_without_ansi( - expected: &str, - builder: crate::fmt::SubscriberBuilder>, - ) where - Format: FormatEvent, - T: Send + Sync, - { - let make_writer = MockMakeWriter::default(); - let subscriber = builder.with_writer(make_writer).with_timer(MockTime); - run_test(subscriber, make_writer, expected) - } - - fn test_without_level( - expected: &str, - builder: crate::fmt::SubscriberBuilder>, - ) where - Format: FormatEvent, - T: Send + Sync + 'static, - { - let make_writer = MockMakeWriter::default(); - let subscriber = builder - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime); - run_test(subscriber, make_writer, expected); - } - - #[test] - fn with_line_number_and_file_name() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_file(true) - .with_line_number(true) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime); - - let expected = Regex::new(&format!( - "^fake time tracing_subscriber::fmt::format::test: {}:[0-9]+: hello\n$", - current_path() - // if we're on Windows, the path might contain backslashes, which - // have to be escpaed before compiling the regex. - .replace('\\', "\\\\") - )) - .unwrap(); - let _default = set_default(&subscriber.into()); - tracing::info!("hello"); - let res = make_writer.get_string(); - assert!(expected.is_match(&res)); - } - - #[test] - fn with_line_number() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_line_number(true) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime); - - let expected = - Regex::new("^fake time tracing_subscriber::fmt::format::test: [0-9]+: hello\n$") - .unwrap(); - let _default = set_default(&subscriber.into()); - tracing::info!("hello"); - let res = make_writer.get_string(); - assert!(expected.is_match(&res)); - } - - #[test] - fn with_filename() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_file(true) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime); - let expected = &format!( - "fake time tracing_subscriber::fmt::format::test: {}: hello\n", - current_path(), - ); - assert_info_hello(subscriber, make_writer, expected); - } - - #[test] - fn with_thread_ids() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_thread_ids(true) - .with_ansi(false) - .with_timer(MockTime); - let expected = - "fake time INFO ThreadId(NUMERIC) tracing_subscriber::fmt::format::test: hello\n"; - - assert_info_hello_ignore_numeric(subscriber, make_writer, expected); - } - - #[test] - fn pretty_default() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .pretty() - .with_writer(make_writer.clone()) - .with_ansi(false) - .with_timer(MockTime); - let expected = format!( - r#" fake time INFO tracing_subscriber::fmt::format::test: hello - at {}:NUMERIC - -"#, - file!() - ); - - assert_info_hello_ignore_numeric(subscriber, make_writer, &expected) - } - - fn assert_info_hello(subscriber: impl Into, buf: MockMakeWriter, expected: &str) { - let _default = set_default(&subscriber.into()); - tracing::info!("hello"); - let result = buf.get_string(); - - assert_eq!(expected, result) - } - - // When numeric characters are used they often form a non-deterministic value as they usually represent things like a thread id or line number. - // This assert method should be used when non-deterministic numeric characters are present. - fn assert_info_hello_ignore_numeric( - subscriber: impl Into, - buf: MockMakeWriter, - expected: &str, - ) { - let _default = set_default(&subscriber.into()); - tracing::info!("hello"); - - let regex = Regex::new("[0-9]+").unwrap(); - let result = buf.get_string(); - let result_cleaned = regex.replace_all(&result, "NUMERIC"); - - assert_eq!(expected, result_cleaned) - } - - fn test_overridden_parents( - expected: &str, - builder: crate::fmt::SubscriberBuilder>, - ) where - Format: FormatEvent, - T: Send + Sync + 'static, - { - let make_writer = MockMakeWriter::default(); - let subscriber = builder - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", span = 1); - let span2 = tracing::info_span!(parent: &span1, "span2", span = 2); - tracing::info!(parent: &span2, "hello"); - }); - assert_eq!(expected, make_writer.get_string()); - } - - fn test_overridden_parents_in_scope( - expected1: &str, - expected2: &str, - builder: crate::fmt::SubscriberBuilder>, - ) where - Format: FormatEvent, - T: Send + Sync + 'static, - { - let make_writer = MockMakeWriter::default(); - let subscriber = builder - .with_writer(make_writer.clone()) - .with_level(false) - .with_ansi(false) - .with_timer(MockTime) - .finish(); - - with_default(subscriber, || { - let span1 = tracing::info_span!("span1", span = 1); - let span2 = tracing::info_span!(parent: &span1, "span2", span = 2); - let span3 = tracing::info_span!("span3", span = 3); - let _e3 = span3.enter(); - - tracing::info!("hello"); - assert_eq!(expected1, make_writer.get_string().as_str()); - - tracing::info!(parent: &span2, "hello"); - assert_eq!(expected2, make_writer.get_string().as_str()); - }); - } - - fn run_test(subscriber: impl Into, buf: MockMakeWriter, expected: &str) { - let _default = set_default(&subscriber.into()); - tracing::info!("hello"); - assert_eq!(expected, buf.get_string()) - } - - mod default { - use super::*; - - #[test] - fn with_thread_ids() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .with_writer(make_writer.clone()) - .with_thread_ids(true) - .with_ansi(false) - .with_timer(MockTime); - let expected = - "fake time INFO ThreadId(NUMERIC) tracing_subscriber::fmt::format::test: hello\n"; - - assert_info_hello_ignore_numeric(subscriber, make_writer, expected); - } - - #[cfg(feature = "ansi")] - #[test] - fn with_ansi_true() { - let expected = "\u{1b}[2mfake time\u{1b}[0m \u{1b}[32m INFO\u{1b}[0m \u{1b}[2mtracing_subscriber::fmt::format::test\u{1b}[0m\u{1b}[2m:\u{1b}[0m hello\n"; - test_ansi(true, expected, crate::fmt::Subscriber::builder()); - } - - #[cfg(feature = "ansi")] - #[test] - fn with_ansi_false() { - let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; - test_ansi(false, expected, crate::fmt::Subscriber::builder()); - } - - #[cfg(not(feature = "ansi"))] - #[test] - fn without_ansi() { - let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; - test_without_ansi(expected, crate::fmt::Subscriber::builder()) - } - - #[test] - fn without_level() { - let expected = "fake time tracing_subscriber::fmt::format::test: hello\n"; - test_without_level(expected, crate::fmt::Subscriber::builder()) - } - - #[test] - fn overridden_parents() { - let expected = "fake time span1{span=1}:span2{span=2}: tracing_subscriber::fmt::format::test: hello\n"; - test_overridden_parents(expected, crate::fmt::Subscriber::builder()) - } - - #[test] - fn overridden_parents_in_scope() { - test_overridden_parents_in_scope( - "fake time span3{span=3}: tracing_subscriber::fmt::format::test: hello\n", - "fake time span1{span=1}:span2{span=2}: tracing_subscriber::fmt::format::test: hello\n", - crate::fmt::Subscriber::builder(), - ) - } - } - - mod compact { - use super::*; - - #[cfg(feature = "ansi")] - #[test] - fn with_ansi_true() { - let expected = "\u{1b}[2mfake time\u{1b}[0m \u{1b}[32m INFO\u{1b}[0m \u{1b}[1mtracing_subscriber::fmt::format::test\u{1b}[0m\u{1b}[2m:\u{1b}[0m hello\n"; - test_ansi(true, expected, crate::fmt::Subscriber::builder().compact()) - } - - #[cfg(feature = "ansi")] - #[test] - fn with_ansi_false() { - let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; - test_ansi(false, expected, crate::fmt::Subscriber::builder().compact()); - } - - #[cfg(not(feature = "ansi"))] - #[test] - fn without_ansi() { - let expected = "fake time INFO tracing_subscriber::fmt::format::test: hello\n"; - test_without_ansi(expected, crate::fmt::Subscriber::builder().compact()) - } - - #[test] - fn without_level() { - let expected = "fake time tracing_subscriber::fmt::format::test: hello\n"; - test_without_level(expected, crate::fmt::Subscriber::builder().compact()); - } - - #[test] - fn overridden_parents() { - let expected = "fake time span1:span2: tracing_subscriber::fmt::format::test: hello span=1 span=2\n"; - test_overridden_parents(expected, crate::fmt::Subscriber::builder().compact()) - } - - #[test] - fn overridden_parents_in_scope() { - test_overridden_parents_in_scope( - "fake time span3: tracing_subscriber::fmt::format::test: hello span=3\n", - "fake time span1:span2: tracing_subscriber::fmt::format::test: hello span=1 span=2\n", - crate::fmt::Subscriber::builder().compact(), - ) - } - } - - mod pretty { - use super::*; - - #[test] - fn pretty_default() { - let make_writer = MockMakeWriter::default(); - let subscriber = crate::fmt::Subscriber::builder() - .pretty() - .with_writer(make_writer.clone()) - .with_ansi(false) - .with_timer(MockTime); - let expected = format!( - " fake time INFO tracing_subscriber::fmt::format::test: hello\n at {}:NUMERIC\n\n", - file!() - ); - - assert_info_hello_ignore_numeric(subscriber, make_writer, &expected) - } - } - - #[test] - fn format_nanos() { - fn fmt(t: u64) -> String { - TimingDisplay(t).to_string() - } - - assert_eq!(fmt(1), "1.00ns"); - assert_eq!(fmt(12), "12.0ns"); - assert_eq!(fmt(123), "123ns"); - assert_eq!(fmt(1234), "1.23µs"); - assert_eq!(fmt(12345), "12.3µs"); - assert_eq!(fmt(123456), "123µs"); - assert_eq!(fmt(1234567), "1.23ms"); - assert_eq!(fmt(12345678), "12.3ms"); - assert_eq!(fmt(123456789), "123ms"); - assert_eq!(fmt(1234567890), "1.23s"); - assert_eq!(fmt(12345678901), "12.3s"); - assert_eq!(fmt(123456789012), "123s"); - assert_eq!(fmt(1234567890123), "1235s"); - } - - #[test] - fn fmt_span_combinations() { - let f = FmtSpan::NONE; - assert!(!f.contains(FmtSpan::NEW)); - assert!(!f.contains(FmtSpan::ENTER)); - assert!(!f.contains(FmtSpan::EXIT)); - assert!(!f.contains(FmtSpan::CLOSE)); - - let f = FmtSpan::ACTIVE; - assert!(!f.contains(FmtSpan::NEW)); - assert!(f.contains(FmtSpan::ENTER)); - assert!(f.contains(FmtSpan::EXIT)); - assert!(!f.contains(FmtSpan::CLOSE)); - - let f = FmtSpan::FULL; - assert!(f.contains(FmtSpan::NEW)); - assert!(f.contains(FmtSpan::ENTER)); - assert!(f.contains(FmtSpan::EXIT)); - assert!(f.contains(FmtSpan::CLOSE)); - - let f = FmtSpan::NEW | FmtSpan::CLOSE; - assert!(f.contains(FmtSpan::NEW)); - assert!(!f.contains(FmtSpan::ENTER)); - assert!(!f.contains(FmtSpan::EXIT)); - assert!(f.contains(FmtSpan::CLOSE)); - } - - /// Returns the test's module path. - fn current_path() -> String { - Path::new("tracing-subscriber") - .join("src") - .join("fmt") - .join("format") - .join("mod.rs") - .to_str() - .expect("path must not contain invalid unicode") - .to_owned() - } -} diff --git a/vendor/tracing-subscriber/src/fmt/format/pretty.rs b/vendor/tracing-subscriber/src/fmt/format/pretty.rs deleted file mode 100644 index a50d08ba7..000000000 --- a/vendor/tracing-subscriber/src/fmt/format/pretty.rs +++ /dev/null @@ -1,511 +0,0 @@ -use super::*; -use crate::{ - field::{VisitFmt, VisitOutput}, - fmt::fmt_layer::{FmtContext, FormattedFields}, - registry::LookupSpan, -}; - -use std::fmt; -use tracing_core::{ - field::{self, Field}, - Event, Level, Subscriber, -}; - -#[cfg(feature = "tracing-log")] -use tracing_log::NormalizeEvent; - -use ansi_term::{Colour, Style}; - -/// An excessively pretty, human-readable event formatter. -/// -/// Unlike the [`Full`], [`Compact`], and [`Json`] formatters, this is a -/// multi-line output format. Each individual event may output multiple lines of -/// text. -/// -/// # Example Output -/// -///
:; cargo run --example fmt-pretty
-///     Finished dev [unoptimized + debuginfo] target(s) in 0.08s
-///      Running `target/debug/examples/fmt-pretty`
-///   2022-02-15T18:44:24.535324Z  INFO fmt_pretty: preparing to shave yaks, number_of_yaks: 3
-///     at examples/examples/fmt-pretty.rs:16 on main
-///
-///   2022-02-15T18:44:24.535403Z  INFO fmt_pretty::yak_shave: shaving yaks
-///     at examples/examples/fmt/yak_shave.rs:41 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535442Z TRACE fmt_pretty::yak_shave: hello! I'm gonna shave a yak, excitement: "yay!"
-///     at examples/examples/fmt/yak_shave.rs:16 on main
-///     in fmt_pretty::yak_shave::shave with yak: 1
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535469Z TRACE fmt_pretty::yak_shave: yak shaved successfully
-///     at examples/examples/fmt/yak_shave.rs:25 on main
-///     in fmt_pretty::yak_shave::shave with yak: 1
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535502Z DEBUG yak_events: yak: 1, shaved: true
-///     at examples/examples/fmt/yak_shave.rs:46 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535524Z TRACE fmt_pretty::yak_shave: yaks_shaved: 1
-///     at examples/examples/fmt/yak_shave.rs:55 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535551Z TRACE fmt_pretty::yak_shave: hello! I'm gonna shave a yak, excitement: "yay!"
-///     at examples/examples/fmt/yak_shave.rs:16 on main
-///     in fmt_pretty::yak_shave::shave with yak: 2
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535573Z TRACE fmt_pretty::yak_shave: yak shaved successfully
-///     at examples/examples/fmt/yak_shave.rs:25 on main
-///     in fmt_pretty::yak_shave::shave with yak: 2
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535600Z DEBUG yak_events: yak: 2, shaved: true
-///     at examples/examples/fmt/yak_shave.rs:46 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535618Z TRACE fmt_pretty::yak_shave: yaks_shaved: 2
-///     at examples/examples/fmt/yak_shave.rs:55 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535644Z TRACE fmt_pretty::yak_shave: hello! I'm gonna shave a yak, excitement: "yay!"
-///     at examples/examples/fmt/yak_shave.rs:16 on main
-///     in fmt_pretty::yak_shave::shave with yak: 3
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535670Z  WARN fmt_pretty::yak_shave: could not locate yak
-///     at examples/examples/fmt/yak_shave.rs:18 on main
-///     in fmt_pretty::yak_shave::shave with yak: 3
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535698Z DEBUG yak_events: yak: 3, shaved: false
-///     at examples/examples/fmt/yak_shave.rs:46 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535720Z ERROR fmt_pretty::yak_shave: failed to shave yak, yak: 3, error: missing yak, error.sources: [out of space, out of cash]
-///     at examples/examples/fmt/yak_shave.rs:51 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535742Z TRACE fmt_pretty::yak_shave: yaks_shaved: 2
-///     at examples/examples/fmt/yak_shave.rs:55 on main
-///     in fmt_pretty::yak_shave::shaving_yaks with yaks: 3
-///
-///   2022-02-15T18:44:24.535765Z  INFO fmt_pretty: yak shaving completed, all_yaks_shaved: false
-///     at examples/examples/fmt-pretty.rs:19 on main
-/// 
-#[derive(Debug, Clone, Eq, PartialEq)] -pub struct Pretty { - display_location: bool, -} - -/// The [visitor] produced by [`Pretty`]'s [`MakeVisitor`] implementation. -/// -/// [visitor]: field::Visit -/// [`MakeVisitor`]: crate::field::MakeVisitor -#[derive(Debug)] -pub struct PrettyVisitor<'a> { - writer: Writer<'a>, - is_empty: bool, - style: Style, - result: fmt::Result, -} - -/// An excessively pretty, human-readable [`MakeVisitor`] implementation. -/// -/// [`MakeVisitor`]: crate::field::MakeVisitor -#[derive(Debug)] -pub struct PrettyFields { - /// A value to override the provided `Writer`'s ANSI formatting - /// configuration. - /// - /// If this is `Some`, we override the `Writer`'s ANSI setting. This is - /// necessary in order to continue supporting the deprecated - /// `PrettyFields::with_ansi` method. If it is `None`, we don't override the - /// ANSI formatting configuration (because the deprecated method was not - /// called). - // TODO: when `PrettyFields::with_ansi` is removed, we can get rid - // of this entirely. - ansi: Option, -} - -// === impl Pretty === - -impl Default for Pretty { - fn default() -> Self { - Self { - display_location: true, - } - } -} - -impl Pretty { - fn style_for(level: &Level) -> Style { - match *level { - Level::TRACE => Style::new().fg(Colour::Purple), - Level::DEBUG => Style::new().fg(Colour::Blue), - Level::INFO => Style::new().fg(Colour::Green), - Level::WARN => Style::new().fg(Colour::Yellow), - Level::ERROR => Style::new().fg(Colour::Red), - } - } - - /// Sets whether the event's source code location is displayed. - /// - /// This defaults to `true`. - #[deprecated( - since = "0.3.6", - note = "all formatters now support configurable source locations. Use `Format::with_source_location` instead." - )] - pub fn with_source_location(self, display_location: bool) -> Self { - Self { - display_location, - ..self - } - } -} - -impl FormatEvent for Format -where - C: Subscriber + for<'a> LookupSpan<'a>, - N: for<'a> FormatFields<'a> + 'static, - T: FormatTime, -{ - fn format_event( - &self, - ctx: &FmtContext<'_, C, N>, - mut writer: Writer<'_>, - event: &Event<'_>, - ) -> fmt::Result { - #[cfg(feature = "tracing-log")] - let normalized_meta = event.normalized_metadata(); - #[cfg(feature = "tracing-log")] - let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - #[cfg(not(feature = "tracing-log"))] - let meta = event.metadata(); - write!(&mut writer, " ")?; - - // if the `Format` struct *also* has an ANSI color configuration, - // override the writer...the API for configuring ANSI color codes on the - // `Format` struct is deprecated, but we still need to honor those - // configurations. - if let Some(ansi) = self.ansi { - writer = writer.with_ansi(ansi); - } - - self.format_timestamp(&mut writer)?; - - let style = if self.display_level && writer.has_ansi_escapes() { - Pretty::style_for(meta.level()) - } else { - Style::new() - }; - - if self.display_level { - write!( - writer, - "{} ", - super::FmtLevel::new(meta.level(), writer.has_ansi_escapes()) - )?; - } - - if self.display_target { - let target_style = if writer.has_ansi_escapes() { - style.bold() - } else { - style - }; - write!( - writer, - "{}{}{}:", - target_style.prefix(), - meta.target(), - target_style.infix(style) - )?; - } - let line_number = if self.display_line_number { - meta.line() - } else { - None - }; - - // If the file name is disabled, format the line number right after the - // target. Otherwise, if we also display the file, it'll go on a - // separate line. - if let (Some(line_number), false, true) = ( - line_number, - self.display_filename, - self.format.display_location, - ) { - write!( - writer, - "{}{}{}:", - style.prefix(), - line_number, - style.infix(style) - )?; - } - - writer.write_char(' ')?; - - let mut v = PrettyVisitor::new(writer.by_ref(), true).with_style(style); - event.record(&mut v); - v.finish()?; - writer.write_char('\n')?; - - let dimmed = if writer.has_ansi_escapes() { - Style::new().dimmed().italic() - } else { - Style::new() - }; - let thread = self.display_thread_name || self.display_thread_id; - - if let (Some(file), true, true) = ( - meta.file(), - self.format.display_location, - self.display_filename, - ) { - write!(writer, " {} {}", dimmed.paint("at"), file,)?; - - if let Some(line) = line_number { - write!(writer, ":{}", line)?; - } - writer.write_char(if thread { ' ' } else { '\n' })?; - } else if thread { - write!(writer, " ")?; - }; - - if thread { - write!(writer, "{} ", dimmed.paint("on"))?; - let thread = std::thread::current(); - if self.display_thread_name { - if let Some(name) = thread.name() { - write!(writer, "{}", name)?; - if self.display_thread_id { - writer.write_char(' ')?; - } - } - } - if self.display_thread_id { - write!(writer, "{:?}", thread.id())?; - } - writer.write_char('\n')?; - } - - let bold = writer.bold(); - let span = event - .parent() - .and_then(|id| ctx.span(id)) - .or_else(|| ctx.lookup_current()); - - let scope = span.into_iter().flat_map(|span| span.scope()); - - for span in scope { - let meta = span.metadata(); - if self.display_target { - write!( - writer, - " {} {}::{}", - dimmed.paint("in"), - meta.target(), - bold.paint(meta.name()), - )?; - } else { - write!( - writer, - " {} {}", - dimmed.paint("in"), - bold.paint(meta.name()), - )?; - } - - let ext = span.extensions(); - let fields = &ext - .get::>() - .expect("Unable to find FormattedFields in extensions; this is a bug"); - if !fields.is_empty() { - write!(writer, " {} {}", dimmed.paint("with"), fields)?; - } - writer.write_char('\n')?; - } - - writer.write_char('\n') - } -} - -impl<'writer> FormatFields<'writer> for Pretty { - fn format_fields(&self, writer: Writer<'writer>, fields: R) -> fmt::Result { - let mut v = PrettyVisitor::new(writer, true); - fields.record(&mut v); - v.finish() - } - - fn add_fields( - &self, - current: &'writer mut FormattedFields, - fields: &span::Record<'_>, - ) -> fmt::Result { - let empty = current.is_empty(); - let writer = current.as_writer(); - let mut v = PrettyVisitor::new(writer, empty); - fields.record(&mut v); - v.finish() - } -} - -// === impl PrettyFields === - -impl Default for PrettyFields { - fn default() -> Self { - Self::new() - } -} - -impl PrettyFields { - /// Returns a new default [`PrettyFields`] implementation. - pub fn new() -> Self { - // By default, don't override the `Writer`'s ANSI colors - // configuration. We'll only do this if the user calls the - // deprecated `PrettyFields::with_ansi` method. - Self { ansi: None } - } - - /// Enable ANSI encoding for formatted fields. - #[deprecated( - since = "0.3.3", - note = "Use `fmt::Subscriber::with_ansi` or `fmt::Layer::with_ansi` instead." - )] - pub fn with_ansi(self, ansi: bool) -> Self { - Self { - ansi: Some(ansi), - ..self - } - } -} - -impl<'a> MakeVisitor> for PrettyFields { - type Visitor = PrettyVisitor<'a>; - - #[inline] - fn make_visitor(&self, mut target: Writer<'a>) -> Self::Visitor { - if let Some(ansi) = self.ansi { - target = target.with_ansi(ansi); - } - PrettyVisitor::new(target, true) - } -} - -// === impl PrettyVisitor === - -impl<'a> PrettyVisitor<'a> { - /// Returns a new default visitor that formats to the provided `writer`. - /// - /// # Arguments - /// - `writer`: the writer to format to. - /// - `is_empty`: whether or not any fields have been previously written to - /// that writer. - pub fn new(writer: Writer<'a>, is_empty: bool) -> Self { - Self { - writer, - is_empty, - style: Style::default(), - result: Ok(()), - } - } - - pub(crate) fn with_style(self, style: Style) -> Self { - Self { style, ..self } - } - - fn write_padded(&mut self, value: &impl fmt::Debug) { - let padding = if self.is_empty { - self.is_empty = false; - "" - } else { - ", " - }; - self.result = write!(self.writer, "{}{:?}", padding, value); - } - - fn bold(&self) -> Style { - if self.writer.has_ansi_escapes() { - self.style.bold() - } else { - Style::new() - } - } -} - -impl<'a> field::Visit for PrettyVisitor<'a> { - fn record_str(&mut self, field: &Field, value: &str) { - if self.result.is_err() { - return; - } - - if field.name() == "message" { - self.record_debug(field, &format_args!("{}", value)) - } else { - self.record_debug(field, &value) - } - } - - fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { - if let Some(source) = value.source() { - let bold = self.bold(); - self.record_debug( - field, - &format_args!( - "{}, {}{}.sources{}: {}", - value, - bold.prefix(), - field, - bold.infix(self.style), - ErrorSourceList(source), - ), - ) - } else { - self.record_debug(field, &format_args!("{}", value)) - } - } - - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - if self.result.is_err() { - return; - } - let bold = self.bold(); - match field.name() { - "message" => self.write_padded(&format_args!("{}{:?}", self.style.prefix(), value,)), - // Skip fields that are actually log metadata that have already been handled - #[cfg(feature = "tracing-log")] - name if name.starts_with("log.") => self.result = Ok(()), - name if name.starts_with("r#") => self.write_padded(&format_args!( - "{}{}{}: {:?}", - bold.prefix(), - &name[2..], - bold.infix(self.style), - value - )), - name => self.write_padded(&format_args!( - "{}{}{}: {:?}", - bold.prefix(), - name, - bold.infix(self.style), - value - )), - }; - } -} - -impl<'a> VisitOutput for PrettyVisitor<'a> { - fn finish(mut self) -> fmt::Result { - write!(&mut self.writer, "{}", self.style.suffix())?; - self.result - } -} - -impl<'a> VisitFmt for PrettyVisitor<'a> { - fn writer(&mut self) -> &mut dyn fmt::Write { - &mut self.writer - } -} diff --git a/vendor/tracing-subscriber/src/fmt/mod.rs b/vendor/tracing-subscriber/src/fmt/mod.rs deleted file mode 100644 index 3c6a6ac40..000000000 --- a/vendor/tracing-subscriber/src/fmt/mod.rs +++ /dev/null @@ -1,1324 +0,0 @@ -//! A `Subscriber` for formatting and logging `tracing` data. -//! -//! # Overview -//! -//! [`tracing`] is a framework for instrumenting Rust programs with context-aware, -//! structured, event-based diagnostic information. This crate provides an -//! implementation of the [`Subscriber`] trait that records `tracing`'s `Event`s -//! and `Span`s by formatting them as text and logging them to stdout. -//! -//! # Usage -//! -//! First, add this to your `Cargo.toml` file: -//! -//! ```toml -//! [dependencies] -//! tracing-subscriber = "0.3" -//! ``` -//! -//! *Compiler support: [requires `rustc` 1.49+][msrv]* -//! -//! [msrv]: super#supported-rust-versions -//! -//! Add the following to your executable to initialize the default subscriber: -//! ```rust -//! use tracing_subscriber; -//! -//! tracing_subscriber::fmt::init(); -//! ``` -//! -//! ## Filtering Events with Environment Variables -//! -//! The default subscriber installed by `init` enables you to filter events -//! at runtime using environment variables (using the [`EnvFilter`]). -//! -//! The filter syntax is a superset of the [`env_logger`] syntax. -//! -//! For example: -//! - Setting `RUST_LOG=debug` enables all `Span`s and `Event`s -//! set to the log level `DEBUG` or higher -//! - Setting `RUST_LOG=my_crate=trace` enables `Span`s and `Event`s -//! in `my_crate` at all log levels -//! -//! **Note**: This should **not** be called by libraries. Libraries should use -//! [`tracing`] to publish `tracing` `Event`s. -//! -//! # Configuration -//! -//! You can configure a subscriber instead of using the defaults with -//! the following functions: -//! -//! ### Subscriber -//! -//! The [`FmtSubscriber`] formats and records `tracing` events as line-oriented logs. -//! You can create one by calling: -//! -//! ```rust -//! let subscriber = tracing_subscriber::fmt() -//! // ... add configuration -//! .finish(); -//! ``` -//! -//! You can find the configuration methods for [`FmtSubscriber`] in -//! [`SubscriberBuilder`]. -//! -//! ## Formatters -//! -//! The output format used by the layer and subscriber in this module is -//! represented by implementing the [`FormatEvent`] trait, and can be -//! customized. This module provides a number of formatter implementations: -//! -//! * [`format::Full`]: The default formatter. This emits human-readable, -//! single-line logs for each event that occurs, with the current span context -//! displayed before the formatted representation of the event. See -//! [here](format::Full#example-output) for sample output. -//! -//! * [`format::Compact`]: A variant of the default formatter, optimized for -//! short line lengths. Fields from the current span context are appended to -//! the fields of the formatted event. See -//! [here](format::Compact#example-output) for sample output. -//! -//! * [`format::Pretty`]: Emits excessively pretty, multi-line logs, optimized -//! for human readability. This is primarily intended to be used in local -//! development and debugging, or for command-line applications, where -//! automated analysis and compact storage of logs is less of a priority than -//! readability and visual appeal. See [here](format::Pretty#example-output) -//! for sample output. -//! -//! * [`format::Json`]: Outputs newline-delimited JSON logs. This is intended -//! for production use with systems where structured logs are consumed as JSON -//! by analysis and viewing tools. The JSON output is not optimized for human -//! readability. See [here](format::Json#example-output) for sample output. -//! -//! ### Customizing Formatters -//! -//! The formatting of log lines for spans and events is controlled by two -//! traits, [`FormatEvent`] and [`FormatFields`]. The [`FormatEvent`] trait -//! determines the overall formatting of the log line, such as what information -//! from the event's metadata and span context is included and in what order. -//! The [`FormatFields`] trait determines how fields — both the event's -//! fields and fields on spans — are formatted. -//! -//! The [`fmt::format`] module provides several types which implement these traits, -//! many of which expose additional configuration options to customize their -//! output. The [`format::Format`] type implements common configuration used by -//! all the formatters provided in this crate, and can be used as a builder to -//! set specific formatting settings. For example: -//! -//! ``` -//! use tracing_subscriber::fmt; -//! -//! // Configure a custom event formatter -//! let format = fmt::format() -//! .with_level(false) // don't include levels in formatted output -//! .with_target(false) // don't include targets -//! .with_thread_ids(true) // include the thread ID of the current thread -//! .with_thread_names(true) // include the name of the current thread -//! .compact(); // use the `Compact` formatting style. -//! -//! // Create a `fmt` subscriber that uses our custom event format, and set it -//! // as the default. -//! tracing_subscriber::fmt() -//! .event_format(format) -//! .init(); -//! ``` -//! -//! However, if a specific output format is needed, other crates can -//! also implement [`FormatEvent`] and [`FormatFields`]. See those traits' -//! documentation for details on how to implement them. -//! -//! ## Filters -//! -//! If you want to filter the `tracing` `Events` based on environment -//! variables, you can use the [`EnvFilter`] as follows: -//! -//! ```rust -//! use tracing_subscriber::EnvFilter; -//! -//! let filter = EnvFilter::from_default_env(); -//! ``` -//! -//! As mentioned above, the [`EnvFilter`] allows `Span`s and `Event`s to -//! be filtered at runtime by setting the `RUST_LOG` environment variable. -//! -//! You can find the other available [`filter`]s in the documentation. -//! -//! ### Using Your Subscriber -//! -//! Finally, once you have configured your `Subscriber`, you need to -//! configure your executable to use it. -//! -//! A subscriber can be installed globally using: -//! ```rust -//! use tracing; -//! use tracing_subscriber::FmtSubscriber; -//! -//! let subscriber = FmtSubscriber::new(); -//! -//! tracing::subscriber::set_global_default(subscriber) -//! .map_err(|_err| eprintln!("Unable to set global default subscriber")); -//! // Note this will only fail if you try to set the global default -//! // subscriber multiple times -//! ``` -//! -//! ### Composing Layers -//! -//! Composing an [`EnvFilter`] `Layer` and a [format `Layer`][super::fmt::Layer]: -//! -//! ```rust -//! use tracing_subscriber::{fmt, EnvFilter}; -//! use tracing_subscriber::prelude::*; -//! -//! let fmt_layer = fmt::layer() -//! .with_target(false); -//! let filter_layer = EnvFilter::try_from_default_env() -//! .or_else(|_| EnvFilter::try_new("info")) -//! .unwrap(); -//! -//! tracing_subscriber::registry() -//! .with(filter_layer) -//! .with(fmt_layer) -//! .init(); -//! ``` -//! -//! [`EnvFilter`]: super::filter::EnvFilter -//! [`env_logger`]: https://docs.rs/env_logger/ -//! [`filter`]: super::filter -//! [`FmtSubscriber`]: Subscriber -//! [`Subscriber`]: -//! https://docs.rs/tracing/latest/tracing/trait.Subscriber.html -//! [`tracing`]: https://crates.io/crates/tracing -//! [`fmt::format`]: mod@crate::fmt::format -use std::{any::TypeId, error::Error, io}; -use tracing_core::{span, subscriber::Interest, Event, Metadata}; - -mod fmt_layer; -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -pub mod format; -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -pub mod time; -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -pub mod writer; - -pub use fmt_layer::{FmtContext, FormattedFields, Layer}; - -use crate::layer::Layer as _; -use crate::util::SubscriberInitExt; -use crate::{ - filter::LevelFilter, - layer, - registry::{LookupSpan, Registry}, -}; - -#[doc(inline)] -pub use self::{ - format::{format, FormatEvent, FormatFields}, - time::time, - writer::{MakeWriter, TestWriter}, -}; - -/// A `Subscriber` that logs formatted representations of `tracing` events. -/// -/// This consists of an inner `Formatter` wrapped in a layer that performs filtering. -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -#[derive(Debug)] -pub struct Subscriber< - N = format::DefaultFields, - E = format::Format, - F = LevelFilter, - W = fn() -> io::Stdout, -> { - inner: layer::Layered>, -} - -/// A `Subscriber` that logs formatted representations of `tracing` events. -/// This type only logs formatted events; it does not perform any filtering. -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -pub type Formatter< - N = format::DefaultFields, - E = format::Format, - W = fn() -> io::Stdout, -> = layer::Layered, Registry>; - -/// Configures and constructs `Subscriber`s. -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -#[derive(Debug)] -pub struct SubscriberBuilder< - N = format::DefaultFields, - E = format::Format, - F = LevelFilter, - W = fn() -> io::Stdout, -> { - filter: F, - inner: Layer, -} - -/// Returns a new [`SubscriberBuilder`] for configuring a [formatting subscriber]. -/// -/// This is essentially shorthand for [`SubscriberBuilder::default()]`. -/// -/// # Examples -/// -/// Using [`init`] to set the default subscriber: -/// -/// ```rust -/// tracing_subscriber::fmt().init(); -/// ``` -/// -/// Configuring the output format: -/// -/// ```rust -/// -/// tracing_subscriber::fmt() -/// // Configure formatting settings. -/// .with_target(false) -/// .with_timer(tracing_subscriber::fmt::time::uptime()) -/// .with_level(true) -/// // Set the subscriber as the default. -/// .init(); -/// ``` -/// -/// [`try_init`] returns an error if the default subscriber could not be set: -/// -/// ```rust -/// use std::error::Error; -/// -/// fn init_subscriber() -> Result<(), Box> { -/// tracing_subscriber::fmt() -/// // Configure the subscriber to emit logs in JSON format. -/// .json() -/// // Configure the subscriber to flatten event fields in the output JSON objects. -/// .flatten_event(true) -/// // Set the subscriber as the default, returning an error if this fails. -/// .try_init()?; -/// -/// Ok(()) -/// } -/// ``` -/// -/// Rather than setting the subscriber as the default, [`finish`] _returns_ the -/// constructed subscriber, which may then be passed to other functions: -/// -/// ```rust -/// let subscriber = tracing_subscriber::fmt() -/// .with_max_level(tracing::Level::DEBUG) -/// .compact() -/// .finish(); -/// -/// tracing::subscriber::with_default(subscriber, || { -/// // the subscriber will only be set as the default -/// // inside this closure... -/// }) -/// ``` -/// -/// [formatting subscriber]: Subscriber -/// [`SubscriberBuilder::default()`]: SubscriberBuilder::default -/// [`init`]: SubscriberBuilder::init() -/// [`try_init`]: SubscriberBuilder::try_init() -/// [`finish`]: SubscriberBuilder::finish() -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -pub fn fmt() -> SubscriberBuilder { - SubscriberBuilder::default() -} - -/// Returns a new [formatting layer] that can be [composed] with other layers to -/// construct a [`Subscriber`]. -/// -/// This is a shorthand for the equivalent [`Layer::default()`] function. -/// -/// [formatting layer]: Layer -/// [composed]: crate::layer -/// [`Layer::default()`]: Layer::default -#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] -pub fn layer() -> Layer { - Layer::default() -} - -impl Subscriber { - /// The maximum [verbosity level] that is enabled by a `Subscriber` by - /// default. - /// - /// This can be overridden with the [`SubscriberBuilder::with_max_level`] method. - /// - /// [verbosity level]: tracing_core::Level - /// [`SubscriberBuilder::with_max_level`]: SubscriberBuilder::with_max_level - pub const DEFAULT_MAX_LEVEL: LevelFilter = LevelFilter::INFO; - - /// Returns a new `SubscriberBuilder` for configuring a format subscriber. - pub fn builder() -> SubscriberBuilder { - SubscriberBuilder::default() - } - - /// Returns a new format subscriber with the default configuration. - pub fn new() -> Self { - Default::default() - } -} - -impl Default for Subscriber { - fn default() -> Self { - SubscriberBuilder::default().finish() - } -} - -// === impl Subscriber === - -impl tracing_core::Subscriber for Subscriber -where - N: for<'writer> FormatFields<'writer> + 'static, - E: FormatEvent + 'static, - F: layer::Layer> + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, - layer::Layered>: tracing_core::Subscriber, - fmt_layer::Layer: layer::Layer, -{ - #[inline] - fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest { - self.inner.register_callsite(meta) - } - - #[inline] - fn enabled(&self, meta: &Metadata<'_>) -> bool { - self.inner.enabled(meta) - } - - #[inline] - fn new_span(&self, attrs: &span::Attributes<'_>) -> span::Id { - self.inner.new_span(attrs) - } - - #[inline] - fn record(&self, span: &span::Id, values: &span::Record<'_>) { - self.inner.record(span, values) - } - - #[inline] - fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { - self.inner.record_follows_from(span, follows) - } - - #[inline] - fn event_enabled(&self, event: &Event<'_>) -> bool { - self.inner.event_enabled(event) - } - - #[inline] - fn event(&self, event: &Event<'_>) { - self.inner.event(event); - } - - #[inline] - fn enter(&self, id: &span::Id) { - // TODO: add on_enter hook - self.inner.enter(id); - } - - #[inline] - fn exit(&self, id: &span::Id) { - self.inner.exit(id); - } - - #[inline] - fn current_span(&self) -> span::Current { - self.inner.current_span() - } - - #[inline] - fn clone_span(&self, id: &span::Id) -> span::Id { - self.inner.clone_span(id) - } - - #[inline] - fn try_close(&self, id: span::Id) -> bool { - self.inner.try_close(id) - } - - #[inline] - fn max_level_hint(&self) -> Option { - self.inner.max_level_hint() - } - - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - if id == TypeId::of::() { - Some(self as *const Self as *const ()) - } else { - self.inner.downcast_raw(id) - } - } -} - -impl<'a, N, E, F, W> LookupSpan<'a> for Subscriber -where - layer::Layered>: LookupSpan<'a>, -{ - type Data = > as LookupSpan<'a>>::Data; - - fn span_data(&'a self, id: &span::Id) -> Option { - self.inner.span_data(id) - } -} - -// ===== impl SubscriberBuilder ===== - -impl Default for SubscriberBuilder { - fn default() -> Self { - SubscriberBuilder { - filter: Subscriber::DEFAULT_MAX_LEVEL, - inner: Default::default(), - } - } -} - -impl SubscriberBuilder -where - N: for<'writer> FormatFields<'writer> + 'static, - E: FormatEvent + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, - F: layer::Layer> + Send + Sync + 'static, - fmt_layer::Layer: layer::Layer + Send + Sync + 'static, -{ - /// Finish the builder, returning a new `FmtSubscriber`. - pub fn finish(self) -> Subscriber { - let subscriber = self.inner.with_subscriber(Registry::default()); - Subscriber { - inner: self.filter.with_subscriber(subscriber), - } - } - - /// Install this Subscriber as the global default if one is - /// not already set. - /// - /// If the `tracing-log` feature is enabled, this will also install - /// the LogTracer to convert `Log` records into `tracing` `Event`s. - /// - /// # Errors - /// Returns an Error if the initialization was unsuccessful, likely - /// because a global subscriber was already installed by another - /// call to `try_init`. - pub fn try_init(self) -> Result<(), Box> { - use crate::util::SubscriberInitExt; - self.finish().try_init()?; - - Ok(()) - } - - /// Install this Subscriber as the global default. - /// - /// If the `tracing-log` feature is enabled, this will also install - /// the LogTracer to convert `Log` records into `tracing` `Event`s. - /// - /// # Panics - /// Panics if the initialization was unsuccessful, likely because a - /// global subscriber was already installed by another call to `try_init`. - pub fn init(self) { - self.try_init() - .expect("Unable to install global subscriber") - } -} - -impl From> for tracing_core::Dispatch -where - N: for<'writer> FormatFields<'writer> + 'static, - E: FormatEvent + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, - F: layer::Layer> + Send + Sync + 'static, - fmt_layer::Layer: layer::Layer + Send + Sync + 'static, -{ - fn from(builder: SubscriberBuilder) -> tracing_core::Dispatch { - tracing_core::Dispatch::new(builder.finish()) - } -} - -impl SubscriberBuilder, F, W> -where - N: for<'writer> FormatFields<'writer> + 'static, -{ - /// Use the given [`timer`] for log message timestamps. - /// - /// See the [`time` module] for the provided timer implementations. - /// - /// Note that using the `"time`"" feature flag enables the - /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the - /// [`time` crate] to provide more sophisticated timestamp formatting - /// options. - /// - /// [`timer`]: time::FormatTime - /// [`time` module]: mod@time - /// [`UtcTime`]: time::UtcTime - /// [`LocalTime`]: time::LocalTime - /// [`time` crate]: https://docs.rs/time/0.3 - pub fn with_timer(self, timer: T2) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.with_timer(timer), - } - } - - /// Do not emit timestamps with log messages. - pub fn without_time(self) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.without_time(), - } - } - - /// Configures how synthesized events are emitted at points in the [span - /// lifecycle][lifecycle]. - /// - /// The following options are available: - /// - /// - `FmtSpan::NONE`: No events will be synthesized when spans are - /// created, entered, exited, or closed. Data from spans will still be - /// included as the context for formatted events. This is the default. - /// - `FmtSpan::NEW`: An event will be synthesized when spans are created. - /// - `FmtSpan::ENTER`: An event will be synthesized when spans are entered. - /// - `FmtSpan::EXIT`: An event will be synthesized when spans are exited. - /// - `FmtSpan::CLOSE`: An event will be synthesized when a span closes. If - /// [timestamps are enabled][time] for this formatter, the generated - /// event will contain fields with the span's _busy time_ (the total - /// time for which it was entered) and _idle time_ (the total time that - /// the span existed but was not entered). - /// - `FmtSpan::ACTIVE`: An event will be synthesized when spans are entered - /// or exited. - /// - `FmtSpan::FULL`: Events will be synthesized whenever a span is - /// created, entered, exited, or closed. If timestamps are enabled, the - /// close event will contain the span's busy and idle time, as - /// described above. - /// - /// The options can be enabled in any combination. For instance, the following - /// will synthesize events whenever spans are created and closed: - /// - /// ```rust - /// use tracing_subscriber::fmt::format::FmtSpan; - /// use tracing_subscriber::fmt; - /// - /// let subscriber = fmt() - /// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) - /// .finish(); - /// ``` - /// - /// Note that the generated events will only be part of the log output by - /// this formatter; they will not be recorded by other `Subscriber`s or by - /// `Layer`s added to this subscriber. - /// - /// [lifecycle]: https://docs.rs/tracing/latest/tracing/span/index.html#the-span-lifecycle - /// [time]: SubscriberBuilder::without_time() - pub fn with_span_events(self, kind: format::FmtSpan) -> Self { - SubscriberBuilder { - inner: self.inner.with_span_events(kind), - ..self - } - } - - /// Enable ANSI encoding for formatted events. - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] - pub fn with_ansi(self, ansi: bool) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_ansi(ansi), - ..self - } - } - - /// Sets whether or not an event's target is displayed. - pub fn with_target( - self, - display_target: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_target(display_target), - ..self - } - } - - /// Sets whether or not an event's [source code file path][file] is - /// displayed. - /// - /// [file]: tracing_core::Metadata::file - pub fn with_file( - self, - display_filename: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_file(display_filename), - ..self - } - } - - /// Sets whether or not an event's [source code line number][line] is - /// displayed. - /// - /// [line]: tracing_core::Metadata::line - pub fn with_line_number( - self, - display_line_number: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_line_number(display_line_number), - ..self - } - } - - /// Sets whether or not an event's level is displayed. - pub fn with_level( - self, - display_level: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_level(display_level), - ..self - } - } - - /// Sets whether or not the [name] of the current thread is displayed - /// when formatting events. - /// - /// [name]: std::thread#naming-threads - pub fn with_thread_names( - self, - display_thread_names: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_thread_names(display_thread_names), - ..self - } - } - - /// Sets whether or not the [thread ID] of the current thread is displayed - /// when formatting events. - /// - /// [thread ID]: std::thread::ThreadId - pub fn with_thread_ids( - self, - display_thread_ids: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - inner: self.inner.with_thread_ids(display_thread_ids), - ..self - } - } - - /// Sets the subscriber being built to use a less verbose formatter. - /// - /// See [`format::Compact`]. - pub fn compact(self) -> SubscriberBuilder, F, W> - where - N: for<'writer> FormatFields<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.compact(), - } - } - - /// Sets the subscriber being built to use an [excessively pretty, human-readable formatter](crate::fmt::format::Pretty). - #[cfg(feature = "ansi")] - #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] - pub fn pretty( - self, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.pretty(), - } - } - - /// Sets the subscriber being built to use a JSON formatter. - /// - /// See [`format::Json`][super::fmt::format::Json] - #[cfg(feature = "json")] - #[cfg_attr(docsrs, doc(cfg(feature = "json")))] - pub fn json( - self, - ) -> SubscriberBuilder, F, W> - where - N: for<'writer> FormatFields<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.json(), - } - } -} - -#[cfg(feature = "json")] -#[cfg_attr(docsrs, doc(cfg(feature = "json")))] -impl SubscriberBuilder, F, W> { - /// Sets the json subscriber being built to flatten event metadata. - /// - /// See [`format::Json`][super::fmt::format::Json] - pub fn flatten_event( - self, - flatten_event: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.flatten_event(flatten_event), - } - } - - /// Sets whether or not the JSON subscriber being built will include the current span - /// in formatted events. - /// - /// See [`format::Json`][super::fmt::format::Json] - pub fn with_current_span( - self, - display_current_span: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.with_current_span(display_current_span), - } - } - - /// Sets whether or not the JSON subscriber being built will include a list (from - /// root to leaf) of all currently entered spans in formatted events. - /// - /// See [`format::Json`][super::fmt::format::Json] - pub fn with_span_list( - self, - display_span_list: bool, - ) -> SubscriberBuilder, F, W> { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.with_span_list(display_span_list), - } - } -} - -#[cfg(feature = "env-filter")] -#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] -impl SubscriberBuilder -where - Formatter: tracing_core::Subscriber + 'static, -{ - /// Configures the subscriber being built to allow filter reloading at - /// runtime. - pub fn with_filter_reloading( - self, - ) -> SubscriberBuilder>, W> - { - let (filter, _) = crate::reload::Layer::new(self.filter); - SubscriberBuilder { - filter, - inner: self.inner, - } - } -} - -#[cfg(feature = "env-filter")] -#[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] -impl SubscriberBuilder>, W> -where - Formatter: tracing_core::Subscriber + 'static, -{ - /// Returns a `Handle` that may be used to reload the constructed subscriber's - /// filter. - pub fn reload_handle(&self) -> crate::reload::Handle> { - self.filter.handle() - } -} - -impl SubscriberBuilder { - /// Sets the field formatter that the subscriber being built will use to record - /// fields. - /// - /// For example: - /// ```rust - /// use tracing_subscriber::fmt::format; - /// use tracing_subscriber::prelude::*; - /// - /// let formatter = - /// // Construct a custom formatter for `Debug` fields - /// format::debug_fn(|writer, field, value| write!(writer, "{}: {:?}", field, value)) - /// // Use the `tracing_subscriber::MakeFmtExt` trait to wrap the - /// // formatter so that a delimiter is added between fields. - /// .delimited(", "); - /// - /// let subscriber = tracing_subscriber::fmt() - /// .fmt_fields(formatter) - /// .finish(); - /// # drop(subscriber) - /// ``` - pub fn fmt_fields(self, fmt_fields: N2) -> SubscriberBuilder - where - N2: for<'writer> FormatFields<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.fmt_fields(fmt_fields), - } - } - - /// Sets the [`EnvFilter`] that the subscriber will use to determine if - /// a span or event is enabled. - /// - /// Note that this method requires the "env-filter" feature flag to be enabled. - /// - /// If a filter was previously set, or a maximum level was set by the - /// [`with_max_level`] method, that value is replaced by the new filter. - /// - /// # Examples - /// - /// Setting a filter based on the value of the `RUST_LOG` environment - /// variable: - /// ```rust - /// use tracing_subscriber::{fmt, EnvFilter}; - /// - /// fmt() - /// .with_env_filter(EnvFilter::from_default_env()) - /// .init(); - /// ``` - /// - /// Setting a filter based on a pre-set filter directive string: - /// ```rust - /// use tracing_subscriber::fmt; - /// - /// fmt() - /// .with_env_filter("my_crate=info,my_crate::my_mod=debug,[my_span]=trace") - /// .init(); - /// ``` - /// - /// Adding additional directives to a filter constructed from an env var: - /// ```rust - /// use tracing_subscriber::{fmt, filter::{EnvFilter, LevelFilter}}; - /// - /// # fn filter() -> Result<(), Box> { - /// let filter = EnvFilter::try_from_env("MY_CUSTOM_FILTER_ENV_VAR")? - /// // Set the base level when not matched by other directives to WARN. - /// .add_directive(LevelFilter::WARN.into()) - /// // Set the max level for `my_crate::my_mod` to DEBUG, overriding - /// // any directives parsed from the env variable. - /// .add_directive("my_crate::my_mod=debug".parse()?); - /// - /// fmt() - /// .with_env_filter(filter) - /// .try_init()?; - /// # Ok(())} - /// ``` - /// [`EnvFilter`]: super::filter::EnvFilter - /// [`with_max_level`]: SubscriberBuilder::with_max_level() - #[cfg(feature = "env-filter")] - #[cfg_attr(docsrs, doc(cfg(feature = "env-filter")))] - pub fn with_env_filter( - self, - filter: impl Into, - ) -> SubscriberBuilder - where - Formatter: tracing_core::Subscriber + 'static, - { - let filter = filter.into(); - SubscriberBuilder { - filter, - inner: self.inner, - } - } - - /// Sets the maximum [verbosity level] that will be enabled by the - /// subscriber. - /// - /// If the max level has already been set, or a [`EnvFilter`] was added by - /// [`with_env_filter`], this replaces that configuration with the new - /// maximum level. - /// - /// # Examples - /// - /// Enable up to the `DEBUG` verbosity level: - /// ```rust - /// use tracing_subscriber::fmt; - /// use tracing::Level; - /// - /// fmt() - /// .with_max_level(Level::DEBUG) - /// .init(); - /// ``` - /// This subscriber won't record any spans or events! - /// ```rust - /// use tracing_subscriber::{fmt, filter::LevelFilter}; - /// - /// let subscriber = fmt() - /// .with_max_level(LevelFilter::OFF) - /// .finish(); - /// ``` - /// [verbosity level]: tracing_core::Level - /// [`EnvFilter`]: struct@crate::filter::EnvFilter - /// [`with_env_filter`]: fn@Self::with_env_filter - pub fn with_max_level( - self, - filter: impl Into, - ) -> SubscriberBuilder { - let filter = filter.into(); - SubscriberBuilder { - filter, - inner: self.inner, - } - } - - /// Sets the [event formatter][`FormatEvent`] that the subscriber being built - /// will use to format events that occur. - /// - /// The event formatter may be any type implementing the [`FormatEvent`] - /// trait, which is implemented for all functions taking a [`FmtContext`], a - /// [`Writer`], and an [`Event`]. - /// - /// # Examples - /// - /// Setting a type implementing [`FormatEvent`] as the formatter: - /// - /// ```rust - /// use tracing_subscriber::fmt::format; - /// - /// let subscriber = tracing_subscriber::fmt() - /// .event_format(format().compact()) - /// .finish(); - /// ``` - /// - /// [`Writer`]: struct@self::format::Writer - pub fn event_format(self, fmt_event: E2) -> SubscriberBuilder - where - E2: FormatEvent + 'static, - N: for<'writer> FormatFields<'writer> + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.event_format(fmt_event), - } - } - - /// Sets the [`MakeWriter`] that the subscriber being built will use to write events. - /// - /// # Examples - /// - /// Using `stderr` rather than `stdout`: - /// - /// ```rust - /// use tracing_subscriber::fmt; - /// use std::io; - /// - /// fmt() - /// .with_writer(io::stderr) - /// .init(); - /// ``` - pub fn with_writer(self, make_writer: W2) -> SubscriberBuilder - where - W2: for<'writer> MakeWriter<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.with_writer(make_writer), - } - } - - /// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in - /// unit tests. - /// - /// See [`TestWriter`] for additional details. - /// - /// # Examples - /// - /// Using [`TestWriter`] to let `cargo test` capture test output. Note that we do not install it - /// globally as it may cause conflicts. - /// - /// ```rust - /// use tracing_subscriber::fmt; - /// use tracing::subscriber; - /// - /// subscriber::set_default( - /// fmt() - /// .with_test_writer() - /// .finish() - /// ); - /// ``` - /// - /// [capturing]: - /// https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output - /// [`TestWriter`]: writer::TestWriter - pub fn with_test_writer(self) -> SubscriberBuilder { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.with_writer(TestWriter::default()), - } - } - - /// Updates the event formatter by applying a function to the existing event formatter. - /// - /// This sets the event formatter that the subscriber being built will use to record fields. - /// - /// # Examples - /// - /// Updating an event formatter: - /// - /// ```rust - /// let subscriber = tracing_subscriber::fmt() - /// .map_event_format(|e| e.compact()) - /// .finish(); - /// ``` - pub fn map_event_format(self, f: impl FnOnce(E) -> E2) -> SubscriberBuilder - where - E2: FormatEvent + 'static, - N: for<'writer> FormatFields<'writer> + 'static, - W: for<'writer> MakeWriter<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.map_event_format(f), - } - } - - /// Updates the field formatter by applying a function to the existing field formatter. - /// - /// This sets the field formatter that the subscriber being built will use to record fields. - /// - /// # Examples - /// - /// Updating a field formatter: - /// - /// ```rust - /// use tracing_subscriber::field::MakeExt; - /// let subscriber = tracing_subscriber::fmt() - /// .map_fmt_fields(|f| f.debug_alt()) - /// .finish(); - /// ``` - pub fn map_fmt_fields(self, f: impl FnOnce(N) -> N2) -> SubscriberBuilder - where - N2: for<'writer> FormatFields<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.map_fmt_fields(f), - } - } - - /// Updates the [`MakeWriter`] by applying a function to the existing [`MakeWriter`]. - /// - /// This sets the [`MakeWriter`] that the subscriber being built will use to write events. - /// - /// # Examples - /// - /// Redirect output to stderr if level is <= WARN: - /// - /// ```rust - /// use tracing::Level; - /// use tracing_subscriber::fmt::{self, writer::MakeWriterExt}; - /// - /// let stderr = std::io::stderr.with_max_level(Level::WARN); - /// let layer = tracing_subscriber::fmt() - /// .map_writer(move |w| stderr.or_else(w)) - /// .finish(); - /// ``` - pub fn map_writer(self, f: impl FnOnce(W) -> W2) -> SubscriberBuilder - where - W2: for<'writer> MakeWriter<'writer> + 'static, - { - SubscriberBuilder { - filter: self.filter, - inner: self.inner.map_writer(f), - } - } -} - -/// Install a global tracing subscriber that listens for events and -/// filters based on the value of the [`RUST_LOG` environment variable], -/// if one is not already set. -/// -/// If the `tracing-log` feature is enabled, this will also install -/// the [`LogTracer`] to convert `log` records into `tracing` `Event`s. -/// -/// This is shorthand for -/// -/// ```rust -/// # fn doc() -> Result<(), Box> { -/// tracing_subscriber::fmt().try_init() -/// # } -/// ``` -/// -/// -/// # Errors -/// -/// Returns an Error if the initialization was unsuccessful, -/// likely because a global subscriber was already installed by another -/// call to `try_init`. -/// -/// [`LogTracer`]: -/// https://docs.rs/tracing-log/0.1.0/tracing_log/struct.LogTracer.html -/// [`RUST_LOG` environment variable]: crate::filter::EnvFilter::DEFAULT_ENV -pub fn try_init() -> Result<(), Box> { - let builder = Subscriber::builder(); - - #[cfg(feature = "env-filter")] - let builder = builder.with_env_filter(crate::EnvFilter::from_default_env()); - - // If `env-filter` is disabled, remove the default max level filter from the - // subscriber; it will be added to the `Targets` filter instead if no filter - // is set in `RUST_LOG`. - // Replacing the default `LevelFilter` with an `EnvFilter` would imply this, - // but we can't replace the builder's filter with a `Targets` filter yet. - #[cfg(not(feature = "env-filter"))] - let builder = builder.with_max_level(LevelFilter::TRACE); - - let subscriber = builder.finish(); - #[cfg(not(feature = "env-filter"))] - let subscriber = { - use crate::{filter::Targets, layer::SubscriberExt}; - use std::{env, str::FromStr}; - let targets = match env::var("RUST_LOG") { - Ok(var) => Targets::from_str(&var) - .map_err(|e| { - eprintln!("Ignoring `RUST_LOG={:?}`: {}", var, e); - }) - .unwrap_or_default(), - Err(env::VarError::NotPresent) => { - Targets::new().with_default(Subscriber::DEFAULT_MAX_LEVEL) - } - Err(e) => { - eprintln!("Ignoring `RUST_LOG`: {}", e); - Targets::new().with_default(Subscriber::DEFAULT_MAX_LEVEL) - } - }; - subscriber.with(targets) - }; - - subscriber.try_init().map_err(Into::into) -} - -/// Install a global tracing subscriber that listens for events and -/// filters based on the value of the [`RUST_LOG` environment variable]. -/// -/// If the `tracing-log` feature is enabled, this will also install -/// the LogTracer to convert `Log` records into `tracing` `Event`s. -/// -/// This is shorthand for -/// -/// ```rust -/// tracing_subscriber::fmt().init() -/// ``` -/// -/// # Panics -/// Panics if the initialization was unsuccessful, likely because a -/// global subscriber was already installed by another call to `try_init`. -/// -/// [`RUST_LOG` environment variable]: crate::filter::EnvFilter::DEFAULT_ENV -pub fn init() { - try_init().expect("Unable to install global subscriber") -} - -#[cfg(test)] -mod test { - use crate::{ - filter::LevelFilter, - fmt::{ - format::{self, Format}, - time, - writer::MakeWriter, - Subscriber, - }, - }; - use std::{ - io, - sync::{Arc, Mutex, MutexGuard, TryLockError}, - }; - use tracing_core::dispatcher::Dispatch; - - pub(crate) struct MockWriter { - buf: Arc>>, - } - - impl MockWriter { - pub(crate) fn new(buf: Arc>>) -> Self { - Self { buf } - } - - pub(crate) fn map_error(err: TryLockError) -> io::Error { - match err { - TryLockError::WouldBlock => io::Error::from(io::ErrorKind::WouldBlock), - TryLockError::Poisoned(_) => io::Error::from(io::ErrorKind::Other), - } - } - - pub(crate) fn buf(&self) -> io::Result>> { - self.buf.try_lock().map_err(Self::map_error) - } - } - - impl io::Write for MockWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.buf()?.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.buf()?.flush() - } - } - - #[derive(Clone, Default)] - pub(crate) struct MockMakeWriter { - buf: Arc>>, - } - - impl MockMakeWriter { - pub(crate) fn new(buf: Arc>>) -> Self { - Self { buf } - } - - #[cfg(feature = "json")] - pub(crate) fn buf(&self) -> MutexGuard<'_, Vec> { - self.buf.lock().unwrap() - } - - pub(crate) fn get_string(&self) -> String { - let mut buf = self.buf.lock().expect("lock shouldn't be poisoned"); - let string = std::str::from_utf8(&buf[..]) - .expect("formatter should not have produced invalid utf-8") - .to_owned(); - buf.clear(); - string - } - } - - impl<'a> MakeWriter<'a> for MockMakeWriter { - type Writer = MockWriter; - - fn make_writer(&'a self) -> Self::Writer { - MockWriter::new(self.buf.clone()) - } - } - - #[test] - fn impls() { - let f = Format::default().with_timer(time::Uptime::default()); - let subscriber = Subscriber::builder().event_format(f).finish(); - let _dispatch = Dispatch::new(subscriber); - - let f = format::Format::default(); - let subscriber = Subscriber::builder().event_format(f).finish(); - let _dispatch = Dispatch::new(subscriber); - - let f = format::Format::default().compact(); - let subscriber = Subscriber::builder().event_format(f).finish(); - let _dispatch = Dispatch::new(subscriber); - } - - #[test] - fn subscriber_downcasts() { - let subscriber = Subscriber::builder().finish(); - let dispatch = Dispatch::new(subscriber); - assert!(dispatch.downcast_ref::().is_some()); - } - - #[test] - fn subscriber_downcasts_to_parts() { - let subscriber = Subscriber::new(); - let dispatch = Dispatch::new(subscriber); - assert!(dispatch.downcast_ref::().is_some()); - assert!(dispatch.downcast_ref::().is_some()); - assert!(dispatch.downcast_ref::().is_some()) - } - - #[test] - fn is_lookup_span() { - fn assert_lookup_span crate::registry::LookupSpan<'a>>(_: T) {} - let subscriber = Subscriber::new(); - assert_lookup_span(subscriber) - } -} diff --git a/vendor/tracing-subscriber/src/fmt/time/datetime.rs b/vendor/tracing-subscriber/src/fmt/time/datetime.rs deleted file mode 100644 index 531331687..000000000 --- a/vendor/tracing-subscriber/src/fmt/time/datetime.rs +++ /dev/null @@ -1,410 +0,0 @@ -// musl as a whole is licensed under the following standard MIT license: -// -// ---------------------------------------------------------------------- -// Copyright © 2005-2020 Rich Felker, et al. -// -// 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. -// ---------------------------------------------------------------------- -// -// Authors/contributors include: -// -// A. Wilcox -// Ada Worcester -// Alex Dowad -// Alex Suykov -// Alexander Monakov -// Andre McCurdy -// Andrew Kelley -// Anthony G. Basile -// Aric Belsito -// Arvid Picciani -// Bartosz Brachaczek -// Benjamin Peterson -// Bobby Bingham -// Boris Brezillon -// Brent Cook -// Chris Spiegel -// Clément Vasseur -// Daniel Micay -// Daniel Sabogal -// Daurnimator -// David Carlier -// David Edelsohn -// Denys Vlasenko -// Dmitry Ivanov -// Dmitry V. Levin -// Drew DeVault -// Emil Renner Berthing -// Fangrui Song -// Felix Fietkau -// Felix Janda -// Gianluca Anzolin -// Hauke Mehrtens -// He X -// Hiltjo Posthuma -// Isaac Dunham -// Jaydeep Patil -// Jens Gustedt -// Jeremy Huntwork -// Jo-Philipp Wich -// Joakim Sindholt -// John Spencer -// Julien Ramseier -// Justin Cormack -// Kaarle Ritvanen -// Khem Raj -// Kylie McClain -// Leah Neukirchen -// Luca Barbato -// Luka Perkov -// M Farkas-Dyck (Strake) -// Mahesh Bodapati -// Markus Wichmann -// Masanori Ogino -// Michael Clark -// Michael Forney -// Mikhail Kremnyov -// Natanael Copa -// Nicholas J. Kain -// orc -// Pascal Cuoq -// Patrick Oppenlander -// Petr Hosek -// Petr Skocik -// Pierre Carrier -// Reini Urban -// Rich Felker -// Richard Pennington -// Ryan Fairfax -// Samuel Holland -// Segev Finer -// Shiz -// sin -// Solar Designer -// Stefan Kristiansson -// Stefan O'Rear -// Szabolcs Nagy -// Timo Teräs -// Trutz Behn -// Valentin Ochs -// Will Dietz -// William Haddon -// William Pitcock -// -// Portions of this software are derived from third-party works licensed -// under terms compatible with the above MIT license: -// -// The TRE regular expression implementation (src/regex/reg* and -// src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed -// under a 2-clause BSD license (license text in the source files). The -// included version has been heavily modified by Rich Felker in 2012, in -// the interests of size, simplicity, and namespace cleanliness. -// -// Much of the math library code (src/math/* and src/complex/*) is -// Copyright © 1993,2004 Sun Microsystems or -// Copyright © 2003-2011 David Schultz or -// Copyright © 2003-2009 Steven G. Kargl or -// Copyright © 2003-2009 Bruce D. Evans or -// Copyright © 2008 Stephen L. Moshier or -// Copyright © 2017-2018 Arm Limited -// and labelled as such in comments in the individual source files. All -// have been licensed under extremely permissive terms. -// -// The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008 -// The Android Open Source Project and is licensed under a two-clause BSD -// license. It was taken from Bionic libc, used on Android. -// -// The AArch64 memcpy and memset code (src/string/aarch64/*) are -// Copyright © 1999-2019, Arm Limited. -// -// The implementation of DES for crypt (src/crypt/crypt_des.c) is -// Copyright © 1994 David Burren. It is licensed under a BSD license. -// -// The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was -// originally written by Solar Designer and placed into the public -// domain. The code also comes with a fallback permissive license for use -// in jurisdictions that may not recognize the public domain. -// -// The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 -// Valentin Ochs and is licensed under an MIT-style license. -// -// The x86_64 port was written by Nicholas J. Kain and is licensed under -// the standard MIT terms. -// -// The mips and microblaze ports were originally written by Richard -// Pennington for use in the ellcc project. The original code was adapted -// by Rich Felker for build system and code conventions during upstream -// integration. It is licensed under the standard MIT terms. -// -// The mips64 port was contributed by Imagination Technologies and is -// licensed under the standard MIT terms. -// -// The powerpc port was also originally written by Richard Pennington, -// and later supplemented and integrated by John Spencer. It is licensed -// under the standard MIT terms. -// -// All other files which have no copyright comments are original works -// produced specifically for use as part of this library, written either -// by Rich Felker, the main author of the library, or by one or more -// contibutors listed above. Details on authorship of individual files -// can be found in the git version control history of the project. The -// omission of copyright and license comments in each file is in the -// interest of source tree size. -// -// In addition, permission is hereby granted for all public header files -// (include/* and arch/*/bits/*) and crt files intended to be linked into -// applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit -// the copyright notice and permission notice otherwise required by the -// license, and to use these files without any requirement of -// attribution. These files include substantial contributions from: -// -// Bobby Bingham -// John Spencer -// Nicholas J. Kain -// Rich Felker -// Richard Pennington -// Stefan Kristiansson -// Szabolcs Nagy -// -// all of whom have explicitly granted such permission. -// -// This file previously contained text expressing a belief that most of -// the files covered by the above exception were sufficiently trivial not -// to be subject to copyright, resulting in confusion over whether it -// negated the permissions granted in the license. In the spirit of -// permissive licensing, and of not having licensing issues being an -// obstacle to adoption, that text has been removed. - - -use std::fmt; - -/// A date/time type which exists primarily to convert `SystemTime` timestamps into an ISO 8601 -/// formatted string. -/// -/// Yes, this exists. Before you have a heart attack, understand that the meat of this is musl's -/// [`__secs_to_tm`][1] converted to Rust via [c2rust][2] and then cleaned up by hand as part of -/// the [kudu-rs project][3], [released under MIT][4]. -/// -/// [1] http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c -/// [2] https://c2rust.com/ -/// [3] https://github.com/danburkert/kudu-rs/blob/c9660067e5f4c1a54143f169b5eeb49446f82e54/src/timestamp.rs#L5-L18 -/// [4] https://github.com/tokio-rs/tracing/issues/1644#issuecomment-963888244 -/// -/// All existing `strftime`-like APIs I found were unable to handle the full range of timestamps representable -/// by `SystemTime`, including `strftime` itself, since tm.tm_year is an int. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) struct DateTime { - year: i64, - month: u8, - day: u8, - hour: u8, - minute: u8, - second: u8, - nanos: u32, -} - -impl fmt::Display for DateTime { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.year > 9999 { - write!(f, "+{}", self.year)?; - } else if self.year < 0 { - write!(f, "{:05}", self.year)?; - } else { - write!(f, "{:04}", self.year)?; - } - - write!( - f, - "-{:02}-{:02}T{:02}:{:02}:{:02}.{:06}Z", - self.month, - self.day, - self.hour, - self.minute, - self.second, - self.nanos / 1_000 - ) - } -} - -impl From for DateTime { - fn from(timestamp: std::time::SystemTime) -> DateTime { - let (t, nanos) = match timestamp.duration_since(std::time::UNIX_EPOCH) { - Ok(duration) => { - debug_assert!(duration.as_secs() <= std::i64::MAX as u64); - (duration.as_secs() as i64, duration.subsec_nanos()) - } - Err(error) => { - let duration = error.duration(); - debug_assert!(duration.as_secs() <= std::i64::MAX as u64); - let (secs, nanos) = (duration.as_secs() as i64, duration.subsec_nanos()); - if nanos == 0 { - (-secs, 0) - } else { - (-secs - 1, 1_000_000_000 - nanos) - } - } - }; - - // 2000-03-01 (mod 400 year, immediately after feb29 - const LEAPOCH: i64 = 946_684_800 + 86400 * (31 + 29); - const DAYS_PER_400Y: i32 = 365 * 400 + 97; - const DAYS_PER_100Y: i32 = 365 * 100 + 24; - const DAYS_PER_4Y: i32 = 365 * 4 + 1; - static DAYS_IN_MONTH: [i8; 12] = [31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29]; - - // Note(dcb): this bit is rearranged slightly to avoid integer overflow. - let mut days: i64 = (t / 86_400) - (LEAPOCH / 86_400); - let mut remsecs: i32 = (t % 86_400) as i32; - if remsecs < 0i32 { - remsecs += 86_400; - days -= 1 - } - - let mut qc_cycles: i32 = (days / i64::from(DAYS_PER_400Y)) as i32; - let mut remdays: i32 = (days % i64::from(DAYS_PER_400Y)) as i32; - if remdays < 0 { - remdays += DAYS_PER_400Y; - qc_cycles -= 1; - } - - let mut c_cycles: i32 = remdays / DAYS_PER_100Y; - if c_cycles == 4 { - c_cycles -= 1; - } - remdays -= c_cycles * DAYS_PER_100Y; - - let mut q_cycles: i32 = remdays / DAYS_PER_4Y; - if q_cycles == 25 { - q_cycles -= 1; - } - remdays -= q_cycles * DAYS_PER_4Y; - - let mut remyears: i32 = remdays / 365; - if remyears == 4 { - remyears -= 1; - } - remdays -= remyears * 365; - - let mut years: i64 = i64::from(remyears) - + 4 * i64::from(q_cycles) - + 100 * i64::from(c_cycles) - + 400 * i64::from(qc_cycles); - - let mut months: i32 = 0; - while i32::from(DAYS_IN_MONTH[months as usize]) <= remdays { - remdays -= i32::from(DAYS_IN_MONTH[months as usize]); - months += 1 - } - - if months >= 10 { - months -= 12; - years += 1; - } - - DateTime { - year: years + 2000, - month: (months + 3) as u8, - day: (remdays + 1) as u8, - hour: (remsecs / 3600) as u8, - minute: (remsecs / 60 % 60) as u8, - second: (remsecs % 60) as u8, - nanos, - } - } -} - -#[cfg(test)] -mod tests { - use std::i32; - use std::time::{Duration, UNIX_EPOCH}; - - use super::*; - - #[test] - fn test_datetime() { - let case = |expected: &str, secs: i64, micros: u32| { - let timestamp = if secs >= 0 { - UNIX_EPOCH + Duration::new(secs as u64, micros * 1_000) - } else { - (UNIX_EPOCH - Duration::new(!secs as u64 + 1, 0)) + Duration::new(0, micros * 1_000) - }; - assert_eq!( - expected, - format!("{}", DateTime::from(timestamp)), - "secs: {}, micros: {}", - secs, - micros - ) - }; - - // Mostly generated with: - // - date -jur +"%Y-%m-%dT%H:%M:%S.000000Z" - // - http://unixtimestamp.50x.eu/ - - case("1970-01-01T00:00:00.000000Z", 0, 0); - - case("1970-01-01T00:00:00.000001Z", 0, 1); - case("1970-01-01T00:00:00.500000Z", 0, 500_000); - case("1970-01-01T00:00:01.000001Z", 1, 1); - case("1970-01-01T00:01:01.000001Z", 60 + 1, 1); - case("1970-01-01T01:01:01.000001Z", 60 * 60 + 60 + 1, 1); - case( - "1970-01-02T01:01:01.000001Z", - 24 * 60 * 60 + 60 * 60 + 60 + 1, - 1, - ); - - case("1969-12-31T23:59:59.000000Z", -1, 0); - case("1969-12-31T23:59:59.000001Z", -1, 1); - case("1969-12-31T23:59:59.500000Z", -1, 500_000); - case("1969-12-31T23:58:59.000001Z", -60 - 1, 1); - case("1969-12-31T22:58:59.000001Z", -60 * 60 - 60 - 1, 1); - case( - "1969-12-30T22:58:59.000001Z", - -24 * 60 * 60 - 60 * 60 - 60 - 1, - 1, - ); - - case("2038-01-19T03:14:07.000000Z", std::i32::MAX as i64, 0); - case("2038-01-19T03:14:08.000000Z", std::i32::MAX as i64 + 1, 0); - case("1901-12-13T20:45:52.000000Z", i32::MIN as i64, 0); - case("1901-12-13T20:45:51.000000Z", i32::MIN as i64 - 1, 0); - - // Skipping these tests on windows as std::time::SysteTime range is low - // on Windows compared with that of Unix which can cause the following - // high date value tests to panic - #[cfg(not(target_os = "windows"))] - { - case("+292277026596-12-04T15:30:07.000000Z", std::i64::MAX, 0); - case("+292277026596-12-04T15:30:06.000000Z", std::i64::MAX - 1, 0); - case("-292277022657-01-27T08:29:53.000000Z", i64::MIN + 1, 0); - } - - case("1900-01-01T00:00:00.000000Z", -2208988800, 0); - case("1899-12-31T23:59:59.000000Z", -2208988801, 0); - case("0000-01-01T00:00:00.000000Z", -62167219200, 0); - case("-0001-12-31T23:59:59.000000Z", -62167219201, 0); - - case("1234-05-06T07:08:09.000000Z", -23215049511, 0); - case("-1234-05-06T07:08:09.000000Z", -101097651111, 0); - case("2345-06-07T08:09:01.000000Z", 11847456541, 0); - case("-2345-06-07T08:09:01.000000Z", -136154620259, 0); - } -} diff --git a/vendor/tracing-subscriber/src/fmt/time/mod.rs b/vendor/tracing-subscriber/src/fmt/time/mod.rs deleted file mode 100644 index e5b7c83b0..000000000 --- a/vendor/tracing-subscriber/src/fmt/time/mod.rs +++ /dev/null @@ -1,138 +0,0 @@ -//! Formatters for event timestamps. -use crate::fmt::format::Writer; -use std::fmt; -use std::time::Instant; - -mod datetime; - -#[cfg(feature = "time")] -mod time_crate; -#[cfg(feature = "time")] -#[cfg_attr(docsrs, doc(cfg(feature = "time")))] -pub use time_crate::UtcTime; - -#[cfg(feature = "local-time")] -#[cfg_attr(docsrs, doc(cfg(unsound_local_offset, feature = "local-time")))] -pub use time_crate::LocalTime; - -#[cfg(feature = "time")] -#[cfg_attr(docsrs, doc(cfg(feature = "time")))] -pub use time_crate::OffsetTime; - -/// A type that can measure and format the current time. -/// -/// This trait is used by `Format` to include a timestamp with each `Event` when it is logged. -/// -/// Notable default implementations of this trait are `SystemTime` and `()`. The former prints the -/// current time as reported by `std::time::SystemTime`, and the latter does not print the current -/// time at all. `FormatTime` is also automatically implemented for any function pointer with the -/// appropriate signature. -/// -/// The full list of provided implementations can be found in [`time`]. -/// -/// [`time`]: self -pub trait FormatTime { - /// Measure and write out the current time. - /// - /// When `format_time` is called, implementors should get the current time using their desired - /// mechanism, and write it out to the given `fmt::Write`. Implementors must insert a trailing - /// space themselves if they wish to separate the time from subsequent log message text. - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result; -} - -/// Returns a new `SystemTime` timestamp provider. -/// -/// This can then be configured further to determine how timestamps should be -/// configured. -/// -/// This is equivalent to calling -/// ```rust -/// # fn timer() -> tracing_subscriber::fmt::time::SystemTime { -/// tracing_subscriber::fmt::time::SystemTime::default() -/// # } -/// ``` -pub fn time() -> SystemTime { - SystemTime::default() -} - -/// Returns a new `Uptime` timestamp provider. -/// -/// With this timer, timestamps will be formatted with the amount of time -/// elapsed since the timestamp provider was constructed. -/// -/// This can then be configured further to determine how timestamps should be -/// configured. -/// -/// This is equivalent to calling -/// ```rust -/// # fn timer() -> tracing_subscriber::fmt::time::Uptime { -/// tracing_subscriber::fmt::time::Uptime::default() -/// # } -/// ``` -pub fn uptime() -> Uptime { - Uptime::default() -} - -impl<'a, F> FormatTime for &'a F -where - F: FormatTime, -{ - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - (*self).format_time(w) - } -} - -impl FormatTime for () { - fn format_time(&self, _: &mut Writer<'_>) -> fmt::Result { - Ok(()) - } -} - -impl FormatTime for fn(&mut Writer<'_>) -> fmt::Result { - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - (*self)(w) - } -} - -/// Retrieve and print the current wall-clock time. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] -pub struct SystemTime; - -/// Retrieve and print the relative elapsed wall-clock time since an epoch. -/// -/// The `Default` implementation for `Uptime` makes the epoch the current time. -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub struct Uptime { - epoch: Instant, -} - -impl Default for Uptime { - fn default() -> Self { - Uptime { - epoch: Instant::now(), - } - } -} - -impl From for Uptime { - fn from(epoch: Instant) -> Self { - Uptime { epoch } - } -} - -impl FormatTime for SystemTime { - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - write!( - w, - "{}", - datetime::DateTime::from(std::time::SystemTime::now()) - ) - } -} - -impl FormatTime for Uptime { - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - let e = self.epoch.elapsed(); - write!(w, "{:4}.{:09}s", e.as_secs(), e.subsec_nanos()) - } -} diff --git a/vendor/tracing-subscriber/src/fmt/time/time_crate.rs b/vendor/tracing-subscriber/src/fmt/time/time_crate.rs deleted file mode 100644 index 60d57fd0b..000000000 --- a/vendor/tracing-subscriber/src/fmt/time/time_crate.rs +++ /dev/null @@ -1,470 +0,0 @@ -use crate::fmt::{format::Writer, time::FormatTime, writer::WriteAdaptor}; -use std::fmt; -use time::{format_description::well_known, formatting::Formattable, OffsetDateTime, UtcOffset}; - -/// Formats the current [local time] using a [formatter] from the [`time` crate]. -/// -/// To format the current [UTC time] instead, use the [`UtcTime`] type. -/// -///
-///
-///     Warning: The time
-///     crate must be compiled with --cfg unsound_local_offset in order to use
-///     local timestamps. When this cfg is not enabled, local timestamps cannot be recorded, and
-///     events will be logged without timestamps.
-///
-///    Alternatively, [`OffsetTime`] can log with a local offset if it is initialized early.
-///
-///    See the time
-///    documentation for more details.
-/// 
-/// -/// [local time]: time::OffsetDateTime::now_local -/// [UTC time]: time::OffsetDateTime::now_utc -/// [formatter]: time::formatting::Formattable -/// [`time` crate]: time -#[derive(Clone, Debug)] -#[cfg_attr( - docsrs, - doc(cfg(all(unsound_local_offset, feature = "time", feature = "local-time"))) -)] -#[cfg(feature = "local-time")] -pub struct LocalTime { - format: F, -} - -/// Formats the current [UTC time] using a [formatter] from the [`time` crate]. -/// -/// To format the current [local time] instead, use the [`LocalTime`] type. -/// -/// [local time]: time::OffsetDateTime::now_local -/// [UTC time]: time::OffsetDateTime::now_utc -/// [formatter]: time::formatting::Formattable -/// [`time` crate]: time -#[cfg_attr(docsrs, doc(cfg(feature = "time")))] -#[derive(Clone, Debug)] -pub struct UtcTime { - format: F, -} - -/// Formats the current time using a fixed offset and a [formatter] from the [`time` crate]. -/// -/// This is typically used as an alternative to [`LocalTime`]. `LocalTime` determines the offset -/// every time it formats a message, which may be unsound or fail. With `OffsetTime`, the offset is -/// determined once. This makes it possible to do so while the program is still single-threaded and -/// handle any errors. However, this also means the offset cannot change while the program is -/// running (the offset will not change across DST changes). -/// -/// [formatter]: time::formatting::Formattable -/// [`time` crate]: time -#[derive(Clone, Debug)] -#[cfg_attr(docsrs, doc(cfg(feature = "time")))] -pub struct OffsetTime { - offset: time::UtcOffset, - format: F, -} - -// === impl LocalTime === - -#[cfg(feature = "local-time")] -impl LocalTime { - /// Returns a formatter that formats the current [local time] in the - /// [RFC 3339] format (a subset of the [ISO 8601] timestamp format). - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time}; - /// - /// let collector = tracing_subscriber::fmt() - /// .with_timer(time::LocalTime::rfc_3339()); - /// # drop(collector); - /// ``` - /// - /// [local time]: time::OffsetDateTime::now_local - /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 - /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 - pub fn rfc_3339() -> Self { - Self::new(well_known::Rfc3339) - } -} - -#[cfg(feature = "local-time")] -impl LocalTime { - /// Returns a formatter that formats the current [local time] using the - /// [`time` crate] with the provided provided format. The format may be any - /// type that implements the [`Formattable`] trait. - /// - /// - ///
- ///
-    ///     Warning: The 
-    ///     time crate must be compiled with --cfg
-    ///     unsound_local_offset in order to use local timestamps. When this
-    ///     cfg is not enabled, local timestamps cannot be recorded, and
-    ///     events will be logged without timestamps.
-    ///
-    ///    See the 
-    ///    time documentation for more details.
-    /// 
- /// - /// Typically, the format will be a format description string, or one of the - /// `time` crate's [well-known formats]. - /// - /// If the format description is statically known, then the - /// [`format_description!`] macro should be used. This is identical to the - /// [`time::format_description::parse`] method, but runs at compile-time, - /// throwing an error if the format description is invalid. If the desired format - /// is not known statically (e.g., a user is providing a format string), then the - /// [`time::format_description::parse`] method should be used. Note that this - /// method is fallible. - /// - /// See the [`time` book] for details on the format description syntax. - /// - /// # Examples - /// - /// Using the [`format_description!`] macro: - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::LocalTime}; - /// use time::macros::format_description; - /// - /// let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]")); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// Using [`time::format_description::parse`]: - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::LocalTime}; - /// - /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") - /// .expect("format string should be valid!"); - /// let timer = LocalTime::new(time_format); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// Using the [`format_description!`] macro requires enabling the `time` - /// crate's "macros" feature flag. - /// - /// Using a [well-known format][well-known formats] (this is equivalent to - /// [`LocalTime::rfc_3339`]): - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::LocalTime}; - /// - /// let timer = LocalTime::new(time::format_description::well_known::Rfc3339); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// [local time]: time::OffsetDateTime::now_local() - /// [`time` crate]: time - /// [`Formattable`]: time::formatting::Formattable - /// [well-known formats]: time::format_description::well_known - /// [`format_description!`]: time::macros::format_description! - /// [`time::format_description::parse`]: time::format_description::parse() - /// [`time` book]: https://time-rs.github.io/book/api/format-description.html - pub fn new(format: F) -> Self { - Self { format } - } -} - -#[cfg(feature = "local-time")] -impl FormatTime for LocalTime -where - F: Formattable, -{ - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - let now = OffsetDateTime::now_local().map_err(|_| fmt::Error)?; - format_datetime(now, w, &self.format) - } -} - -#[cfg(feature = "local-time")] -impl Default for LocalTime -where - F: Formattable + Default, -{ - fn default() -> Self { - Self::new(F::default()) - } -} - -// === impl UtcTime === - -impl UtcTime { - /// Returns a formatter that formats the current [UTC time] in the - /// [RFC 3339] format, which is a subset of the [ISO 8601] timestamp format. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time}; - /// - /// let collector = tracing_subscriber::fmt() - /// .with_timer(time::UtcTime::rfc_3339()); - /// # drop(collector); - /// ``` - /// - /// [local time]: time::OffsetDateTime::now_utc - /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 - /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 - pub fn rfc_3339() -> Self { - Self::new(well_known::Rfc3339) - } -} - -impl UtcTime { - /// Returns a formatter that formats the current [UTC time] using the - /// [`time` crate], with the provided provided format. The format may be any - /// type that implements the [`Formattable`] trait. - /// - /// Typically, the format will be a format description string, or one of the - /// `time` crate's [well-known formats]. - /// - /// If the format description is statically known, then the - /// [`format_description!`] macro should be used. This is identical to the - /// [`time::format_description::parse`] method, but runs at compile-time, - /// failing an error if the format description is invalid. If the desired format - /// is not known statically (e.g., a user is providing a format string), then the - /// [`time::format_description::parse`] method should be used. Note that this - /// method is fallible. - /// - /// See the [`time` book] for details on the format description syntax. - /// - /// # Examples - /// - /// Using the [`format_description!`] macro: - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::UtcTime}; - /// use time::macros::format_description; - /// - /// let timer = UtcTime::new(format_description!("[hour]:[minute]:[second]")); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// Using the [`format_description!`] macro requires enabling the `time` - /// crate's "macros" feature flag. - /// - /// Using [`time::format_description::parse`]: - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::UtcTime}; - /// - /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") - /// .expect("format string should be valid!"); - /// let timer = UtcTime::new(time_format); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// Using a [well-known format][well-known formats] (this is equivalent to - /// [`UtcTime::rfc_3339`]): - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::UtcTime}; - /// - /// let timer = UtcTime::new(time::format_description::well_known::Rfc3339); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// [UTC time]: time::OffsetDateTime::now_utc() - /// [`time` crate]: time - /// [`Formattable`]: time::formatting::Formattable - /// [well-known formats]: time::format_description::well_known - /// [`format_description!`]: time::macros::format_description! - /// [`time::format_description::parse`]: time::format_description::parse - /// [`time` book]: https://time-rs.github.io/book/api/format-description.html - pub fn new(format: F) -> Self { - Self { format } - } -} - -impl FormatTime for UtcTime -where - F: Formattable, -{ - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - format_datetime(OffsetDateTime::now_utc(), w, &self.format) - } -} - -impl Default for UtcTime -where - F: Formattable + Default, -{ - fn default() -> Self { - Self::new(F::default()) - } -} - -// === impl OffsetTime === - -#[cfg(feature = "local-time")] -impl OffsetTime { - /// Returns a formatter that formats the current time using the [local time offset] in the [RFC - /// 3339] format (a subset of the [ISO 8601] timestamp format). - /// - /// Returns an error if the local time offset cannot be determined. This typically occurs in - /// multithreaded programs. To avoid this problem, initialize `OffsetTime` before forking - /// threads. When using Tokio, this means initializing `OffsetTime` before the Tokio runtime. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time}; - /// - /// let collector = tracing_subscriber::fmt() - /// .with_timer(time::OffsetTime::local_rfc_3339().expect("could not get local offset!")); - /// # drop(collector); - /// ``` - /// - /// Using `OffsetTime` with Tokio: - /// - /// ``` - /// use tracing_subscriber::fmt::time::OffsetTime; - /// - /// #[tokio::main] - /// async fn run() { - /// tracing::info!("runtime initialized"); - /// - /// // At this point the Tokio runtime is initialized, and we can use both Tokio and Tracing - /// // normally. - /// } - /// - /// fn main() { - /// // Because we need to get the local offset before Tokio spawns any threads, our `main` - /// // function cannot use `tokio::main`. - /// tracing_subscriber::fmt() - /// .with_timer(OffsetTime::local_rfc_3339().expect("could not get local time offset")) - /// .init(); - /// - /// // Even though `run` is written as an `async fn`, because we used `tokio::main` on it - /// // we can call it as a synchronous function. - /// run(); - /// } - /// ``` - /// - /// [local time offset]: time::UtcOffset::current_local_offset - /// [RFC 3339]: https://datatracker.ietf.org/doc/html/rfc3339 - /// [ISO 8601]: https://en.wikipedia.org/wiki/ISO_8601 - pub fn local_rfc_3339() -> Result { - Ok(Self::new( - UtcOffset::current_local_offset()?, - well_known::Rfc3339, - )) - } -} - -impl OffsetTime { - /// Returns a formatter that formats the current time using the [`time` crate] with the provided - /// provided format and [timezone offset]. The format may be any type that implements the - /// [`Formattable`] trait. - /// - /// - /// Typically, the offset will be the [local offset], and format will be a format description - /// string, or one of the `time` crate's [well-known formats]. - /// - /// If the format description is statically known, then the - /// [`format_description!`] macro should be used. This is identical to the - /// [`time::format_description::parse`] method, but runs at compile-time, - /// throwing an error if the format description is invalid. If the desired format - /// is not known statically (e.g., a user is providing a format string), then the - /// [`time::format_description::parse`] method should be used. Note that this - /// method is fallible. - /// - /// See the [`time` book] for details on the format description syntax. - /// - /// # Examples - /// - /// Using the [`format_description!`] macro: - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::OffsetTime}; - /// use time::macros::format_description; - /// use time::UtcOffset; - /// - /// let offset = UtcOffset::current_local_offset().expect("should get local offset!"); - /// let timer = OffsetTime::new(offset, format_description!("[hour]:[minute]:[second]")); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// Using [`time::format_description::parse`]: - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::OffsetTime}; - /// use time::UtcOffset; - /// - /// let offset = UtcOffset::current_local_offset().expect("should get local offset!"); - /// let time_format = time::format_description::parse("[hour]:[minute]:[second]") - /// .expect("format string should be valid!"); - /// let timer = OffsetTime::new(offset, time_format); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// Using the [`format_description!`] macro requires enabling the `time` - /// crate's "macros" feature flag. - /// - /// Using a [well-known format][well-known formats] (this is equivalent to - /// [`OffsetTime::local_rfc_3339`]): - /// - /// ``` - /// use tracing_subscriber::fmt::{self, time::OffsetTime}; - /// use time::UtcOffset; - /// - /// let offset = UtcOffset::current_local_offset().expect("should get local offset!"); - /// let timer = OffsetTime::new(offset, time::format_description::well_known::Rfc3339); - /// let collector = tracing_subscriber::fmt() - /// .with_timer(timer); - /// # drop(collector); - /// ``` - /// - /// [`time` crate]: time - /// [timezone offset]: time::UtcOffset - /// [`Formattable`]: time::formatting::Formattable - /// [local offset]: time::UtcOffset::current_local_offset() - /// [well-known formats]: time::format_description::well_known - /// [`format_description!`]: time::macros::format_description - /// [`time::format_description::parse`]: time::format_description::parse - /// [`time` book]: https://time-rs.github.io/book/api/format-description.html - pub fn new(offset: time::UtcOffset, format: F) -> Self { - Self { offset, format } - } -} - -impl FormatTime for OffsetTime -where - F: time::formatting::Formattable, -{ - fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result { - let now = OffsetDateTime::now_utc().to_offset(self.offset); - format_datetime(now, w, &self.format) - } -} - -fn format_datetime( - now: OffsetDateTime, - into: &mut Writer<'_>, - fmt: &impl Formattable, -) -> fmt::Result { - let mut into = WriteAdaptor::new(into); - now.format_into(&mut into, fmt) - .map_err(|_| fmt::Error) - .map(|_| ()) -} diff --git a/vendor/tracing-subscriber/src/fmt/writer.rs b/vendor/tracing-subscriber/src/fmt/writer.rs deleted file mode 100644 index 4aacd6d54..000000000 --- a/vendor/tracing-subscriber/src/fmt/writer.rs +++ /dev/null @@ -1,1464 +0,0 @@ -//! Abstractions for creating [`io::Write`] instances. -//! -//! [`io::Write`]: std::io::Write -use std::{ - fmt, - io::{self, Write}, - sync::{Arc, Mutex, MutexGuard}, -}; -use tracing_core::Metadata; - -/// A type that can create [`io::Write`] instances. -/// -/// `MakeWriter` is used by [`fmt::Layer`] or [`fmt::Subscriber`] to print -/// formatted text representations of [`Event`]s. -/// -/// This trait is already implemented for function pointers and -/// immutably-borrowing closures that return an instance of [`io::Write`], such -/// as [`io::stdout`] and [`io::stderr`]. Additionally, it is implemented for -/// [`std::sync::Mutex`][mutex] when the tyoe inside the mutex implements -/// [`io::Write`]. -/// -/// # Examples -/// -/// The simplest usage is to pass in a named function that returns a writer. For -/// example, to log all events to stderr, we could write: -/// ``` -/// let subscriber = tracing_subscriber::fmt() -/// .with_writer(std::io::stderr) -/// .finish(); -/// # drop(subscriber); -/// ``` -/// -/// Any function that returns a writer can be used: -/// -/// ``` -/// fn make_my_great_writer() -> impl std::io::Write { -/// // ... -/// # std::io::stdout() -/// } -/// -/// let subscriber = tracing_subscriber::fmt() -/// .with_writer(make_my_great_writer) -/// .finish(); -/// # drop(subscriber); -/// ``` -/// -/// A closure can be used to introduce arbitrary logic into how the writer is -/// created. Consider the (admittedly rather silly) example of sending every 5th -/// event to stderr, and all other events to stdout: -/// -/// ``` -/// use std::io; -/// use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; -/// -/// let n = AtomicUsize::new(0); -/// let subscriber = tracing_subscriber::fmt() -/// .with_writer(move || -> Box { -/// if n.fetch_add(1, Relaxed) % 5 == 0 { -/// Box::new(io::stderr()) -/// } else { -/// Box::new(io::stdout()) -/// } -/// }) -/// .finish(); -/// # drop(subscriber); -/// ``` -/// -/// A single instance of a type implementing [`io::Write`] may be used as a -/// `MakeWriter` by wrapping it in a [`Mutex`][mutex]. For example, we could -/// write to a file like so: -/// -/// ``` -/// use std::{fs::File, sync::Mutex}; -/// -/// # fn docs() -> Result<(), Box> { -/// let log_file = File::create("my_cool_trace.log")?; -/// let subscriber = tracing_subscriber::fmt() -/// .with_writer(Mutex::new(log_file)) -/// .finish(); -/// # drop(subscriber); -/// # Ok(()) -/// # } -/// ``` -/// -/// [`io::Write`]: std::io::Write -/// [`fmt::Layer`]: crate::fmt::Layer -/// [`fmt::Subscriber`]: crate::fmt::Subscriber -/// [`Event`]: tracing_core::event::Event -/// [`io::stdout`]: std::io::stdout() -/// [`io::stderr`]: std::io::stderr() -/// [mutex]: std::sync::Mutex -/// [`MakeWriter::make_writer_for`]: MakeWriter::make_writer_for -/// [`Metadata`]: tracing_core::Metadata -/// [levels]: tracing_core::Level -/// [targets]: tracing_core::Metadata::target -pub trait MakeWriter<'a> { - /// The concrete [`io::Write`] implementation returned by [`make_writer`]. - /// - /// [`io::Write`]: std::io::Write - /// [`make_writer`]: MakeWriter::make_writer - type Writer: io::Write; - - /// Returns an instance of [`Writer`]. - /// - /// # Implementer notes - /// - /// [`fmt::Layer`] or [`fmt::Subscriber`] will call this method each time an event is recorded. Ensure any state - /// that must be saved across writes is not lost when the [`Writer`] instance is dropped. If - /// creating a [`io::Write`] instance is expensive, be sure to cache it when implementing - /// [`MakeWriter`] to improve performance. - /// - /// [`Writer`]: MakeWriter::Writer - /// [`fmt::Layer`]: crate::fmt::Layer - /// [`fmt::Subscriber`]: crate::fmt::Subscriber - /// [`io::Write`]: std::io::Write - fn make_writer(&'a self) -> Self::Writer; - - /// Returns a [`Writer`] for writing data from the span or event described - /// by the provided [`Metadata`]. - /// - /// By default, this calls [`self.make_writer()`][make_writer], ignoring - /// the provided metadata, but implementations can override this to provide - /// metadata-specific behaviors. - /// - /// This method allows `MakeWriter` implementations to implement different - /// behaviors based on the span or event being written. The `MakeWriter` - /// type might return different writers based on the provided metadata, or - /// might write some values to the writer before or after providing it to - /// the caller. - /// - /// For example, we might want to write data from spans and events at the - /// [`ERROR`] and [`WARN`] levels to `stderr`, and data from spans or events - /// at lower levels to stdout: - /// - /// ``` - /// use std::io::{self, Stdout, Stderr, StdoutLock, StderrLock}; - /// use tracing_subscriber::fmt::writer::MakeWriter; - /// use tracing_core::{Metadata, Level}; - /// - /// pub struct MyMakeWriter { - /// stdout: Stdout, - /// stderr: Stderr, - /// } - /// - /// /// A lock on either stdout or stderr, depending on the verbosity level - /// /// of the event being written. - /// pub enum StdioLock<'a> { - /// Stdout(StdoutLock<'a>), - /// Stderr(StderrLock<'a>), - /// } - /// - /// impl<'a> io::Write for StdioLock<'a> { - /// fn write(&mut self, buf: &[u8]) -> io::Result { - /// match self { - /// StdioLock::Stdout(lock) => lock.write(buf), - /// StdioLock::Stderr(lock) => lock.write(buf), - /// } - /// } - /// - /// fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - /// // ... - /// # match self { - /// # StdioLock::Stdout(lock) => lock.write_all(buf), - /// # StdioLock::Stderr(lock) => lock.write_all(buf), - /// # } - /// } - /// - /// fn flush(&mut self) -> io::Result<()> { - /// // ... - /// # match self { - /// # StdioLock::Stdout(lock) => lock.flush(), - /// # StdioLock::Stderr(lock) => lock.flush(), - /// # } - /// } - /// } - /// - /// impl<'a> MakeWriter<'a> for MyMakeWriter { - /// type Writer = StdioLock<'a>; - /// - /// fn make_writer(&'a self) -> Self::Writer { - /// // We must have an implementation of `make_writer` that makes - /// // a "default" writer without any configuring metadata. Let's - /// // just return stdout in that case. - /// StdioLock::Stdout(self.stdout.lock()) - /// } - /// - /// fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - /// // Here's where we can implement our special behavior. We'll - /// // check if the metadata's verbosity level is WARN or ERROR, - /// // and return stderr in that case. - /// if meta.level() <= &Level::WARN { - /// return StdioLock::Stderr(self.stderr.lock()); - /// } - /// - /// // Otherwise, we'll return stdout. - /// StdioLock::Stdout(self.stdout.lock()) - /// } - /// } - /// ``` - /// - /// [`Writer`]: MakeWriter::Writer - /// [`Metadata`]: tracing_core::Metadata - /// [make_writer]: MakeWriter::make_writer - /// [`WARN`]: tracing_core::Level::WARN - /// [`ERROR`]: tracing_core::Level::ERROR - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - let _ = meta; - self.make_writer() - } -} - -/// Extension trait adding combinators for working with types implementing -/// [`MakeWriter`]. -/// -/// This is not intended to be implemented directly for user-defined -/// [`MakeWriter`]s; instead, it should be imported when the desired methods are -/// used. -pub trait MakeWriterExt<'a>: MakeWriter<'a> { - /// Wraps `self` and returns a [`MakeWriter`] that will only write output - /// for events at or below the provided verbosity [`Level`]. For instance, - /// `Level::TRACE` is considered to be _more verbose` than `Level::INFO`. - /// - /// Events whose level is more verbose than `level` will be ignored, and no - /// output will be written. - /// - /// # Examples - /// - /// ``` - /// use tracing::Level; - /// use tracing_subscriber::fmt::writer::MakeWriterExt; - /// - /// // Construct a writer that outputs events to `stderr` only if the span or - /// // event's level is >= WARN (WARN and ERROR). - /// let mk_writer = std::io::stderr.with_max_level(Level::WARN); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// ``` - /// - /// Writing the `ERROR` and `WARN` levels to `stderr`, and everything else - /// to `stdout`: - /// - /// ``` - /// # use tracing::Level; - /// # use tracing_subscriber::fmt::writer::MakeWriterExt; - /// - /// let mk_writer = std::io::stderr - /// .with_max_level(Level::WARN) - /// .or_else(std::io::stdout); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// ``` - /// - /// Writing the `ERROR` level to `stderr`, the `INFO` and `WARN` levels to - /// `stdout`, and the `INFO` and DEBUG` levels to a file: - /// - /// ``` - /// # use tracing::Level; - /// # use tracing_subscriber::fmt::writer::MakeWriterExt; - /// use std::{sync::Arc, fs::File}; - /// # // don't actually create the file when running the tests. - /// # fn docs() -> std::io::Result<()> { - /// let debug_log = Arc::new(File::create("debug.log")?); - /// - /// let mk_writer = std::io::stderr - /// .with_max_level(Level::ERROR) - /// .or_else(std::io::stdout - /// .with_max_level(Level::INFO) - /// .and(debug_log.with_max_level(Level::DEBUG)) - /// ); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// # Ok(()) } - /// ``` - /// - /// [`Level`]: tracing_core::Level - /// [`io::Write`]: std::io::Write - fn with_max_level(self, level: tracing_core::Level) -> WithMaxLevel - where - Self: Sized, - { - WithMaxLevel::new(self, level) - } - - /// Wraps `self` and returns a [`MakeWriter`] that will only write output - /// for events at or above the provided verbosity [`Level`]. - /// - /// Events whose level is less verbose than `level` will be ignored, and no - /// output will be written. - /// - /// # Examples - /// - /// ``` - /// use tracing::Level; - /// use tracing_subscriber::fmt::writer::MakeWriterExt; - /// - /// // Construct a writer that outputs events to `stdout` only if the span or - /// // event's level is <= DEBUG (DEBUG and TRACE). - /// let mk_writer = std::io::stdout.with_min_level(Level::DEBUG); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// ``` - /// This can be combined with [`MakeWriterExt::with_max_level`] to write - /// only within a range of levels: - /// - /// ``` - /// # use tracing::Level; - /// # use tracing_subscriber::fmt::writer::MakeWriterExt; - /// // Only write the `DEBUG` and `INFO` levels to stdout. - /// let mk_writer = std::io::stdout - /// .with_max_level(Level::DEBUG) - /// .with_min_level(Level::INFO) - /// // Write the `WARN` and `ERROR` levels to stderr. - /// .and(std::io::stderr.with_min_level(Level::WARN)); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// ``` - /// [`Level`]: tracing_core::Level - /// [`io::Write`]: std::io::Write - fn with_min_level(self, level: tracing_core::Level) -> WithMinLevel - where - Self: Sized, - { - WithMinLevel::new(self, level) - } - - /// Wraps `self` with a predicate that takes a span or event's [`Metadata`] - /// and returns a `bool`. The returned [`MakeWriter`]'s - /// [`MakeWriter::make_writer_for`][mwf] method will check the predicate to - /// determine if a writer should be produced for a given span or event. - /// - /// If the predicate returns `false`, the wrapped [`MakeWriter`]'s - /// [`make_writer_for`][mwf] will return [`OptionalWriter::none`][own]. - /// Otherwise, it calls the wrapped [`MakeWriter`]'s - /// [`make_writer_for`][mwf] method, and returns the produced writer. - /// - /// This can be used to filter an output based on arbitrary [`Metadata`] - /// parameters. - /// - /// # Examples - /// - /// Writing events with a specific target to an HTTP access log, and other - /// events to stdout: - /// - /// ``` - /// use tracing_subscriber::fmt::writer::MakeWriterExt; - /// use std::{sync::Arc, fs::File}; - /// # // don't actually create the file when running the tests. - /// # fn docs() -> std::io::Result<()> { - /// let access_log = Arc::new(File::create("access.log")?); - /// - /// let mk_writer = access_log - /// // Only write events with the target "http::access_log" to the - /// // access log file. - /// .with_filter(|meta| meta.target() == "http::access_log") - /// // Write events with all other targets to stdout. - /// .or_else(std::io::stdout); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// # Ok(()) - /// # } - /// ``` - /// - /// Conditionally enabling or disabling a log file: - /// ``` - /// use tracing_subscriber::fmt::writer::MakeWriterExt; - /// use std::{ - /// sync::{Arc, atomic::{AtomicBool, Ordering}}, - /// fs::File, - /// }; - /// - /// static DEBUG_LOG_ENABLED: AtomicBool = AtomicBool::new(false); - /// - /// # // don't actually create the file when running the tests. - /// # fn docs() -> std::io::Result<()> { - /// // Create the debug log file - /// let debug_file = Arc::new(File::create("debug.log")?) - /// // Enable the debug log only if the flag is enabled. - /// .with_filter(|_| DEBUG_LOG_ENABLED.load(Ordering::Acquire)); - /// - /// // Always write to stdout - /// let mk_writer = std::io::stdout - /// // Write to the debug file if it's enabled - /// .and(debug_file); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// - /// // ... - /// - /// // Later, we can toggle on or off the debug log file. - /// DEBUG_LOG_ENABLED.store(true, Ordering::Release); - /// # Ok(()) - /// # } - /// ``` - /// - /// [`Metadata`]: tracing_core::Metadata - /// [mwf]: MakeWriter::make_writer_for - /// [own]: EitherWriter::none - fn with_filter(self, filter: F) -> WithFilter - where - Self: Sized, - F: Fn(&Metadata<'_>) -> bool, - { - WithFilter::new(self, filter) - } - - /// Combines `self` with another type implementing [`MakeWriter`], returning - /// a new [`MakeWriter`] that produces [writers] that write to *both* - /// outputs. - /// - /// If writing to either writer returns an error, the returned writer will - /// return that error. However, both writers will still be written to before - /// the error is returned, so it is possible for one writer to fail while - /// the other is written to successfully. - /// - /// # Examples - /// - /// ``` - /// use tracing_subscriber::fmt::writer::MakeWriterExt; - /// - /// // Construct a writer that outputs events to `stdout` *and* `stderr`. - /// let mk_writer = std::io::stdout.and(std::io::stderr); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// ``` - /// - /// `and` can be used in conjunction with filtering combinators. For - /// example, if we want to write to a number of outputs depending on the - /// level of an event, we could write: - /// - /// ``` - /// use tracing::Level; - /// # use tracing_subscriber::fmt::writer::MakeWriterExt; - /// use std::{sync::Arc, fs::File}; - /// # // don't actually create the file when running the tests. - /// # fn docs() -> std::io::Result<()> { - /// let debug_log = Arc::new(File::create("debug.log")?); - /// - /// // Write everything to the debug log. - /// let mk_writer = debug_log - /// // Write the `ERROR` and `WARN` levels to stderr. - /// .and(std::io::stderr.with_max_level(Level::WARN)) - /// // Write `INFO` to `stdout`. - /// .and(std::io::stdout - /// .with_max_level(Level::INFO) - /// .with_min_level(Level::INFO) - /// ); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// # Ok(()) } - /// ``` - /// - /// [writers]: std::io::Write - fn and(self, other: B) -> Tee - where - Self: Sized, - B: MakeWriter<'a> + Sized, - { - Tee::new(self, other) - } - - /// Combines `self` with another type implementing [`MakeWriter`], returning - /// a new [`MakeWriter`] that calls `other`'s [`make_writer`] if `self`'s - /// `make_writer` returns [`OptionalWriter::none`][own]. - /// - /// # Examples - /// - /// ``` - /// use tracing::Level; - /// use tracing_subscriber::fmt::writer::MakeWriterExt; - /// - /// // Produces a writer that writes to `stderr` if the level is >= WARN, - /// // or returns `OptionalWriter::none()` otherwise. - /// let stderr = std::io::stderr.with_max_level(Level::WARN); - /// - /// // If the `stderr` `MakeWriter` is disabled by the max level filter, - /// // write to stdout instead: - /// let mk_writer = stderr.or_else(std::io::stdout); - /// - /// tracing_subscriber::fmt().with_writer(mk_writer).init(); - /// ``` - /// - /// [`make_writer`]: MakeWriter::make_writer - /// [own]: EitherWriter::none - fn or_else(self, other: B) -> OrElse - where - Self: MakeWriter<'a, Writer = OptionalWriter> + Sized, - B: MakeWriter<'a> + Sized, - W: Write, - { - OrElse::new(self, other) - } -} - -/// A writer intended to support [`libtest`'s output capturing][capturing] for use in unit tests. -/// -/// `TestWriter` is used by [`fmt::Subscriber`] or [`fmt::Layer`] to enable capturing support. -/// -/// `cargo test` can only capture output from the standard library's [`print!`] macro. See -/// [`libtest`'s output capturing][capturing] for more details about output capturing. -/// -/// Writing to [`io::stdout`] and [`io::stderr`] produces the same results as using -/// [`libtest`'s `--nocapture` option][nocapture] which may make the results look unreadable. -/// -/// [`fmt::Subscriber`]: super::Subscriber -/// [`fmt::Layer`]: super::Layer -/// [capturing]: https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output -/// [nocapture]: https://doc.rust-lang.org/cargo/commands/cargo-test.html -/// [`io::stdout`]: std::io::stdout -/// [`io::stderr`]: std::io::stderr -/// [`print!`]: std::print! -#[derive(Default, Debug)] -pub struct TestWriter { - _p: (), -} - -/// A writer that erases the specific [`io::Write`] and [`MakeWriter`] types being used. -/// -/// This is useful in cases where the concrete type of the writer cannot be known -/// until runtime. -/// -/// # Examples -/// -/// A function that returns a [`Subscriber`] that will write to either stdout or stderr: -/// -/// ```rust -/// # use tracing::Subscriber; -/// # use tracing_subscriber::fmt::writer::BoxMakeWriter; -/// -/// fn dynamic_writer(use_stderr: bool) -> impl Subscriber { -/// let writer = if use_stderr { -/// BoxMakeWriter::new(std::io::stderr) -/// } else { -/// BoxMakeWriter::new(std::io::stdout) -/// }; -/// -/// tracing_subscriber::fmt().with_writer(writer).finish() -/// } -/// ``` -/// -/// [`Subscriber`]: tracing::Subscriber -/// [`io::Write`]: std::io::Write -pub struct BoxMakeWriter { - inner: Box MakeWriter<'a, Writer = Box> + Send + Sync>, - name: &'static str, -} - -/// A [writer] that is one of two types implementing [`io::Write`][writer]. -/// -/// This may be used by [`MakeWriter`] implementations that may conditionally -/// return one of two writers. -/// -/// [writer]: std::io::Write -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum EitherWriter { - /// A writer of type `A`. - A(A), - /// A writer of type `B`. - B(B), -} - -/// A [writer] which may or may not be enabled. -/// -/// This may be used by [`MakeWriter`] implementations that wish to -/// conditionally enable or disable the returned writer based on a span or -/// event's [`Metadata`]. -/// -/// [writer]: std::io::Write -pub type OptionalWriter = EitherWriter; - -/// A [`MakeWriter`] combinator that only returns an enabled [writer] for spans -/// and events with metadata at or below a specified verbosity [`Level`]. -/// -/// This is returned by the [`MakeWriterExt::with_max_level`] method. See the -/// method documentation for details. -/// -/// [writer]: std::io::Write -/// [`Level`]: tracing_core::Level -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct WithMaxLevel { - make: M, - level: tracing_core::Level, -} - -/// A [`MakeWriter`] combinator that only returns an enabled [writer] for spans -/// and events with metadata at or above a specified verbosity [`Level`]. -/// -/// This is returned by the [`MakeWriterExt::with_min_level`] method. See the -/// method documentation for details. -/// -/// [writer]: std::io::Write -/// [`Level`]: tracing_core::Level -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct WithMinLevel { - make: M, - level: tracing_core::Level, -} - -/// A [`MakeWriter`] combinator that wraps a [`MakeWriter`] with a predicate for -/// span and event [`Metadata`], so that the [`MakeWriter::make_writer_for`] -/// method returns [`OptionalWriter::some`][ows] when the predicate returns `true`, -/// and [`OptionalWriter::none`][own] when the predicate returns `false`. -/// -/// This is returned by the [`MakeWriterExt::with_filter`] method. See the -/// method documentation for details. -/// -/// [`Metadata`]: tracing_core::Metadata -/// [ows]: EitherWriter::some -/// [own]: EitherWriter::none -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct WithFilter { - make: M, - filter: F, -} - -/// Combines a [`MakeWriter`] that returns an [`OptionalWriter`] with another -/// [`MakeWriter`], so that the second [`MakeWriter`] is used when the first -/// [`MakeWriter`] returns [`OptionalWriter::none`][own]. -/// -/// This is returned by the [`MakeWriterExt::or_else] method. See the -/// method documentation for details. -/// -/// [own]: EitherWriter::none -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct OrElse { - inner: A, - or_else: B, -} - -/// Combines two types implementing [`MakeWriter`] (or [`std::io::Write`]) to -/// produce a writer that writes to both [`MakeWriter`]'s returned writers. -/// -/// This is returned by the [`MakeWriterExt::and`] method. See the method -/// documentation for details. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct Tee { - a: A, - b: B, -} - -/// A type implementing [`io::Write`] for a [`MutexGuard`] where the type -/// inside the [`Mutex`] implements [`io::Write`]. -/// -/// This is used by the [`MakeWriter`] implementation for [`Mutex`], because -/// [`MutexGuard`] itself will not implement [`io::Write`] — instead, it -/// _dereferences_ to a type implementing [`io::Write`]. Because [`MakeWriter`] -/// requires the `Writer` type to implement [`io::Write`], it's necessary to add -/// a newtype that forwards the trait implementation. -/// -/// [`io::Write`]: std::io::Write -/// [`MutexGuard`]: std::sync::MutexGuard -/// [`Mutex`]: std::sync::Mutex -#[derive(Debug)] -pub struct MutexGuardWriter<'a, W>(MutexGuard<'a, W>); - -/// Implements [`std::io::Write`] for an [`Arc`] where `&W: Write`. -/// -/// This is an implementation detail of the [`MakeWriter`] impl for [`Arc`]. -#[derive(Clone, Debug)] -pub struct ArcWriter(Arc); - -/// A bridge between `fmt::Write` and `io::Write`. -/// -/// This is used by the timestamp formatting implementation for the `time` -/// crate and by the JSON formatter. In both cases, this is needed because -/// `tracing-subscriber`'s `FormatEvent`/`FormatTime` traits expect a -/// `fmt::Write` implementation, while `serde_json::Serializer` and `time`'s -/// `format_into` methods expect an `io::Write`. -#[cfg(any(feature = "json", feature = "time"))] -pub(in crate::fmt) struct WriteAdaptor<'a> { - fmt_write: &'a mut dyn fmt::Write, -} - -impl<'a, F, W> MakeWriter<'a> for F -where - F: Fn() -> W, - W: io::Write, -{ - type Writer = W; - - fn make_writer(&'a self) -> Self::Writer { - (self)() - } -} - -impl<'a, W> MakeWriter<'a> for Arc -where - &'a W: io::Write + 'a, -{ - type Writer = &'a W; - fn make_writer(&'a self) -> Self::Writer { - &*self - } -} - -impl<'a> MakeWriter<'a> for std::fs::File { - type Writer = &'a std::fs::File; - fn make_writer(&'a self) -> Self::Writer { - self - } -} - -// === impl TestWriter === - -impl TestWriter { - /// Returns a new `TestWriter` with the default configuration. - pub fn new() -> Self { - Self::default() - } -} - -impl io::Write for TestWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - let out_str = String::from_utf8_lossy(buf); - print!("{}", out_str); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl<'a> MakeWriter<'a> for TestWriter { - type Writer = Self; - - fn make_writer(&'a self) -> Self::Writer { - Self::default() - } -} - -// === impl BoxMakeWriter === - -impl BoxMakeWriter { - /// Constructs a `BoxMakeWriter` wrapping a type implementing [`MakeWriter`]. - /// - pub fn new(make_writer: M) -> Self - where - M: for<'a> MakeWriter<'a> + Send + Sync + 'static, - { - Self { - inner: Box::new(Boxed(make_writer)), - name: std::any::type_name::(), - } - } -} - -impl fmt::Debug for BoxMakeWriter { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("BoxMakeWriter") - .field(&format_args!("<{}>", self.name)) - .finish() - } -} - -impl<'a> MakeWriter<'a> for BoxMakeWriter { - type Writer = Box; - - #[inline] - fn make_writer(&'a self) -> Self::Writer { - self.inner.make_writer() - } - - #[inline] - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - self.inner.make_writer_for(meta) - } -} - -struct Boxed(M); - -impl<'a, M> MakeWriter<'a> for Boxed -where - M: MakeWriter<'a>, -{ - type Writer = Box; - - fn make_writer(&'a self) -> Self::Writer { - let w = self.0.make_writer(); - Box::new(w) - } - - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - let w = self.0.make_writer_for(meta); - Box::new(w) - } -} - -// === impl Mutex/MutexGuardWriter === - -impl<'a, W> MakeWriter<'a> for Mutex -where - W: io::Write + 'a, -{ - type Writer = MutexGuardWriter<'a, W>; - - fn make_writer(&'a self) -> Self::Writer { - MutexGuardWriter(self.lock().expect("lock poisoned")) - } -} - -impl<'a, W> io::Write for MutexGuardWriter<'a, W> -where - W: io::Write, -{ - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - self.0.flush() - } - - #[inline] - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { - self.0.write_vectored(bufs) - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.0.write_all(buf) - } - - #[inline] - fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { - self.0.write_fmt(fmt) - } -} - -// === impl EitherWriter === - -impl io::Write for EitherWriter -where - A: io::Write, - B: io::Write, -{ - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - match self { - EitherWriter::A(a) => a.write(buf), - EitherWriter::B(b) => b.write(buf), - } - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - match self { - EitherWriter::A(a) => a.flush(), - EitherWriter::B(b) => b.flush(), - } - } - - #[inline] - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { - match self { - EitherWriter::A(a) => a.write_vectored(bufs), - EitherWriter::B(b) => b.write_vectored(bufs), - } - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - match self { - EitherWriter::A(a) => a.write_all(buf), - EitherWriter::B(b) => b.write_all(buf), - } - } - - #[inline] - fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { - match self { - EitherWriter::A(a) => a.write_fmt(fmt), - EitherWriter::B(b) => b.write_fmt(fmt), - } - } -} - -impl OptionalWriter { - /// Returns a [disabled writer]. - /// - /// Any bytes written to the returned writer are discarded. - /// - /// This is equivalent to returning [`Option::None`]. - /// - /// [disabled writer]: std::io::sink - #[inline] - pub fn none() -> Self { - EitherWriter::B(std::io::sink()) - } - - /// Returns an enabled writer of type `T`. - /// - /// This is equivalent to returning [`Option::Some`]. - #[inline] - pub fn some(t: T) -> Self { - EitherWriter::A(t) - } -} - -impl From> for OptionalWriter { - #[inline] - fn from(opt: Option) -> Self { - match opt { - Some(writer) => Self::some(writer), - None => Self::none(), - } - } -} - -// === impl WithMaxLevel === - -impl WithMaxLevel { - /// Wraps the provided [`MakeWriter`] with a maximum [`Level`], so that it - /// returns [`OptionalWriter::none`] for spans and events whose level is - /// more verbose than the maximum level. - /// - /// See [`MakeWriterExt::with_max_level`] for details. - /// - /// [`Level`]: tracing_core::Level - pub fn new(make: M, level: tracing_core::Level) -> Self { - Self { make, level } - } -} - -impl<'a, M: MakeWriter<'a>> MakeWriter<'a> for WithMaxLevel { - type Writer = OptionalWriter; - - #[inline] - fn make_writer(&'a self) -> Self::Writer { - // If we don't know the level, assume it's disabled. - OptionalWriter::none() - } - - #[inline] - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - if meta.level() <= &self.level { - return OptionalWriter::some(self.make.make_writer_for(meta)); - } - OptionalWriter::none() - } -} - -// === impl WithMinLevel === - -impl WithMinLevel { - /// Wraps the provided [`MakeWriter`] with a minimum [`Level`], so that it - /// returns [`OptionalWriter::none`] for spans and events whose level is - /// less verbose than the maximum level. - /// - /// See [`MakeWriterExt::with_min_level`] for details. - /// - /// [`Level`]: tracing_core::Level - pub fn new(make: M, level: tracing_core::Level) -> Self { - Self { make, level } - } -} - -impl<'a, M: MakeWriter<'a>> MakeWriter<'a> for WithMinLevel { - type Writer = OptionalWriter; - - #[inline] - fn make_writer(&'a self) -> Self::Writer { - // If we don't know the level, assume it's disabled. - OptionalWriter::none() - } - - #[inline] - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - if meta.level() >= &self.level { - return OptionalWriter::some(self.make.make_writer_for(meta)); - } - OptionalWriter::none() - } -} - -// ==== impl WithFilter === - -impl WithFilter { - /// Wraps `make` with the provided `filter`, returning a [`MakeWriter`] that - /// will call `make.make_writer_for()` when `filter` returns `true` for a - /// span or event's [`Metadata`], and returns a [`sink`] otherwise. - /// - /// See [`MakeWriterExt::with_filter`] for details. - /// - /// [`Metadata`]: tracing_core::Metadata - /// [`sink`]: std::io::sink - pub fn new(make: M, filter: F) -> Self - where - F: Fn(&Metadata<'_>) -> bool, - { - Self { make, filter } - } -} - -impl<'a, M, F> MakeWriter<'a> for WithFilter -where - M: MakeWriter<'a>, - F: Fn(&Metadata<'_>) -> bool, -{ - type Writer = OptionalWriter; - - #[inline] - fn make_writer(&'a self) -> Self::Writer { - OptionalWriter::some(self.make.make_writer()) - } - - #[inline] - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - if (self.filter)(meta) { - OptionalWriter::some(self.make.make_writer_for(meta)) - } else { - OptionalWriter::none() - } - } -} - -// === impl Tee === - -impl Tee { - /// Combines two types implementing [`MakeWriter`], returning - /// a new [`MakeWriter`] that produces [writers] that write to *both* - /// outputs. - /// - /// See the documentation for [`MakeWriterExt::and`] for details. - /// - /// [writers]: std::io::Write - pub fn new(a: A, b: B) -> Self { - Self { a, b } - } -} - -impl<'a, A, B> MakeWriter<'a> for Tee -where - A: MakeWriter<'a>, - B: MakeWriter<'a>, -{ - type Writer = Tee; - - #[inline] - fn make_writer(&'a self) -> Self::Writer { - Tee::new(self.a.make_writer(), self.b.make_writer()) - } - - #[inline] - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - Tee::new(self.a.make_writer_for(meta), self.b.make_writer_for(meta)) - } -} - -macro_rules! impl_tee { - ($self_:ident.$f:ident($($arg:ident),*)) => { - { - let res_a = $self_.a.$f($($arg),*); - let res_b = $self_.b.$f($($arg),*); - (res_a?, res_b?) - } - } -} - -impl io::Write for Tee -where - A: io::Write, - B: io::Write, -{ - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - let (a, b) = impl_tee!(self.write(buf)); - Ok(std::cmp::max(a, b)) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - impl_tee!(self.flush()); - Ok(()) - } - - #[inline] - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { - let (a, b) = impl_tee!(self.write_vectored(bufs)); - Ok(std::cmp::max(a, b)) - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - impl_tee!(self.write_all(buf)); - Ok(()) - } - - #[inline] - fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { - impl_tee!(self.write_fmt(fmt)); - Ok(()) - } -} - -// === impl OrElse === - -impl OrElse { - /// Combines - pub fn new<'a, W>(inner: A, or_else: B) -> Self - where - A: MakeWriter<'a, Writer = OptionalWriter>, - B: MakeWriter<'a>, - W: Write, - { - Self { inner, or_else } - } -} - -impl<'a, A, B, W> MakeWriter<'a> for OrElse -where - A: MakeWriter<'a, Writer = OptionalWriter>, - B: MakeWriter<'a>, - W: io::Write, -{ - type Writer = EitherWriter; - - #[inline] - fn make_writer(&'a self) -> Self::Writer { - match self.inner.make_writer() { - EitherWriter::A(writer) => EitherWriter::A(writer), - EitherWriter::B(_) => EitherWriter::B(self.or_else.make_writer()), - } - } - - #[inline] - fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { - match self.inner.make_writer_for(meta) { - EitherWriter::A(writer) => EitherWriter::A(writer), - EitherWriter::B(_) => EitherWriter::B(self.or_else.make_writer_for(meta)), - } - } -} - -// === impl ArcWriter === - -impl io::Write for ArcWriter -where - for<'a> &'a W: io::Write, -{ - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - (&*self.0).write(buf) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - (&*self.0).flush() - } - - #[inline] - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { - (&*self.0).write_vectored(bufs) - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - (&*self.0).write_all(buf) - } - - #[inline] - fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> { - (&*self.0).write_fmt(fmt) - } -} - -// === impl WriteAdaptor === - -#[cfg(any(feature = "json", feature = "time"))] -impl<'a> WriteAdaptor<'a> { - pub(in crate::fmt) fn new(fmt_write: &'a mut dyn fmt::Write) -> Self { - Self { fmt_write } - } -} -#[cfg(any(feature = "json", feature = "time"))] -impl<'a> io::Write for WriteAdaptor<'a> { - fn write(&mut self, buf: &[u8]) -> io::Result { - let s = - std::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; - - self.fmt_write - .write_str(s) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; - - Ok(s.as_bytes().len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -#[cfg(any(feature = "json", feature = "time"))] -impl<'a> fmt::Debug for WriteAdaptor<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad("WriteAdaptor { .. }") - } -} -// === blanket impls === - -impl<'a, M> MakeWriterExt<'a> for M where M: MakeWriter<'a> {} -#[cfg(test)] -mod test { - use super::*; - use crate::fmt::format::Format; - use crate::fmt::test::{MockMakeWriter, MockWriter}; - use crate::fmt::Subscriber; - use std::sync::atomic::{AtomicBool, Ordering}; - use std::sync::{Arc, Mutex}; - use tracing::{debug, error, info, trace, warn, Level}; - use tracing_core::dispatcher::{self, Dispatch}; - - fn test_writer(make_writer: T, msg: &str, buf: &Mutex>) - where - T: for<'writer> MakeWriter<'writer> + Send + Sync + 'static, - { - let subscriber = { - #[cfg(feature = "ansi")] - let f = Format::default().without_time().with_ansi(false); - #[cfg(not(feature = "ansi"))] - let f = Format::default().without_time(); - Subscriber::builder() - .event_format(f) - .with_writer(make_writer) - .finish() - }; - let dispatch = Dispatch::from(subscriber); - - dispatcher::with_default(&dispatch, || { - error!("{}", msg); - }); - - let expected = format!("ERROR {}: {}\n", module_path!(), msg); - let actual = String::from_utf8(buf.try_lock().unwrap().to_vec()).unwrap(); - assert!(actual.contains(expected.as_str())); - } - - fn has_lines(buf: &Mutex>, msgs: &[(tracing::Level, &str)]) { - let actual = String::from_utf8(buf.try_lock().unwrap().to_vec()).unwrap(); - let mut expected_lines = msgs.iter(); - for line in actual.lines() { - let line = dbg!(line).trim(); - let (level, msg) = expected_lines - .next() - .unwrap_or_else(|| panic!("expected no more lines, but got: {:?}", line)); - let expected = format!("{} {}: {}", level, module_path!(), msg); - assert_eq!(line, expected.as_str()); - } - } - - #[test] - fn custom_writer_closure() { - let buf = Arc::new(Mutex::new(Vec::new())); - let buf2 = buf.clone(); - let make_writer = move || MockWriter::new(buf2.clone()); - let msg = "my custom writer closure error"; - test_writer(make_writer, msg, &buf); - } - - #[test] - fn custom_writer_struct() { - let buf = Arc::new(Mutex::new(Vec::new())); - let make_writer = MockMakeWriter::new(buf.clone()); - let msg = "my custom writer struct error"; - test_writer(make_writer, msg, &buf); - } - - #[test] - fn custom_writer_mutex() { - let buf = Arc::new(Mutex::new(Vec::new())); - let writer = MockWriter::new(buf.clone()); - let make_writer = Mutex::new(writer); - let msg = "my mutex writer error"; - test_writer(make_writer, msg, &buf); - } - - #[test] - fn combinators_level_filters() { - let info_buf = Arc::new(Mutex::new(Vec::new())); - let info = MockMakeWriter::new(info_buf.clone()); - - let debug_buf = Arc::new(Mutex::new(Vec::new())); - let debug = MockMakeWriter::new(debug_buf.clone()); - - let warn_buf = Arc::new(Mutex::new(Vec::new())); - let warn = MockMakeWriter::new(warn_buf.clone()); - - let err_buf = Arc::new(Mutex::new(Vec::new())); - let err = MockMakeWriter::new(err_buf.clone()); - - let make_writer = info - .with_max_level(Level::INFO) - .and(debug.with_max_level(Level::DEBUG)) - .and(warn.with_max_level(Level::WARN)) - .and(err.with_max_level(Level::ERROR)); - - let c = { - #[cfg(feature = "ansi")] - let f = Format::default().without_time().with_ansi(false); - #[cfg(not(feature = "ansi"))] - let f = Format::default().without_time(); - Subscriber::builder() - .event_format(f) - .with_writer(make_writer) - .with_max_level(Level::TRACE) - .finish() - }; - - let _s = tracing::subscriber::set_default(c); - - trace!("trace"); - debug!("debug"); - info!("info"); - warn!("warn"); - error!("error"); - - let all_lines = [ - (Level::TRACE, "trace"), - (Level::DEBUG, "debug"), - (Level::INFO, "info"), - (Level::WARN, "warn"), - (Level::ERROR, "error"), - ]; - - println!("max level debug"); - has_lines(&debug_buf, &all_lines[1..]); - - println!("max level info"); - has_lines(&info_buf, &all_lines[2..]); - - println!("max level warn"); - has_lines(&warn_buf, &all_lines[3..]); - - println!("max level error"); - has_lines(&err_buf, &all_lines[4..]); - } - - #[test] - fn combinators_or_else() { - let some_buf = Arc::new(Mutex::new(Vec::new())); - let some = MockMakeWriter::new(some_buf.clone()); - - let or_else_buf = Arc::new(Mutex::new(Vec::new())); - let or_else = MockMakeWriter::new(or_else_buf.clone()); - - let return_some = AtomicBool::new(true); - let make_writer = move || { - if return_some.swap(false, Ordering::Relaxed) { - OptionalWriter::some(some.make_writer()) - } else { - OptionalWriter::none() - } - }; - let make_writer = make_writer.or_else(or_else); - let c = { - #[cfg(feature = "ansi")] - let f = Format::default().without_time().with_ansi(false); - #[cfg(not(feature = "ansi"))] - let f = Format::default().without_time(); - Subscriber::builder() - .event_format(f) - .with_writer(make_writer) - .with_max_level(Level::TRACE) - .finish() - }; - - let _s = tracing::subscriber::set_default(c); - info!("hello"); - info!("world"); - info!("goodbye"); - - has_lines(&some_buf, &[(Level::INFO, "hello")]); - has_lines( - &or_else_buf, - &[(Level::INFO, "world"), (Level::INFO, "goodbye")], - ); - } - - #[test] - fn combinators_or_else_chain() { - let info_buf = Arc::new(Mutex::new(Vec::new())); - let info = MockMakeWriter::new(info_buf.clone()); - - let debug_buf = Arc::new(Mutex::new(Vec::new())); - let debug = MockMakeWriter::new(debug_buf.clone()); - - let warn_buf = Arc::new(Mutex::new(Vec::new())); - let warn = MockMakeWriter::new(warn_buf.clone()); - - let err_buf = Arc::new(Mutex::new(Vec::new())); - let err = MockMakeWriter::new(err_buf.clone()); - - let make_writer = err.with_max_level(Level::ERROR).or_else( - warn.with_max_level(Level::WARN).or_else( - info.with_max_level(Level::INFO) - .or_else(debug.with_max_level(Level::DEBUG)), - ), - ); - - let c = { - #[cfg(feature = "ansi")] - let f = Format::default().without_time().with_ansi(false); - #[cfg(not(feature = "ansi"))] - let f = Format::default().without_time(); - Subscriber::builder() - .event_format(f) - .with_writer(make_writer) - .with_max_level(Level::TRACE) - .finish() - }; - - let _s = tracing::subscriber::set_default(c); - - trace!("trace"); - debug!("debug"); - info!("info"); - warn!("warn"); - error!("error"); - - println!("max level debug"); - has_lines(&debug_buf, &[(Level::DEBUG, "debug")]); - - println!("max level info"); - has_lines(&info_buf, &[(Level::INFO, "info")]); - - println!("max level warn"); - has_lines(&warn_buf, &[(Level::WARN, "warn")]); - - println!("max level error"); - has_lines(&err_buf, &[(Level::ERROR, "error")]); - } - - #[test] - fn combinators_and() { - let a_buf = Arc::new(Mutex::new(Vec::new())); - let a = MockMakeWriter::new(a_buf.clone()); - - let b_buf = Arc::new(Mutex::new(Vec::new())); - let b = MockMakeWriter::new(b_buf.clone()); - - let lines = &[(Level::INFO, "hello"), (Level::INFO, "world")]; - - let make_writer = a.and(b); - let c = { - #[cfg(feature = "ansi")] - let f = Format::default().without_time().with_ansi(false); - #[cfg(not(feature = "ansi"))] - let f = Format::default().without_time(); - Subscriber::builder() - .event_format(f) - .with_writer(make_writer) - .with_max_level(Level::TRACE) - .finish() - }; - - let _s = tracing::subscriber::set_default(c); - info!("hello"); - info!("world"); - - has_lines(&a_buf, &lines[..]); - has_lines(&b_buf, &lines[..]); - } -} diff --git a/vendor/tracing-subscriber/src/layer/context.rs b/vendor/tracing-subscriber/src/layer/context.rs deleted file mode 100644 index 46254994f..000000000 --- a/vendor/tracing-subscriber/src/layer/context.rs +++ /dev/null @@ -1,434 +0,0 @@ -use tracing_core::{metadata::Metadata, span, subscriber::Subscriber, Event}; - -use crate::registry::{self, LookupSpan, SpanRef}; - -#[cfg(all(feature = "registry", feature = "std"))] -use crate::{filter::FilterId, registry::Registry}; -/// Represents information about the current context provided to [`Layer`]s by the -/// wrapped [`Subscriber`]. -/// -/// To access [stored data] keyed by a span ID, implementors of the `Layer` -/// trait should ensure that the `Subscriber` type parameter is *also* bound by the -/// [`LookupSpan`]: -/// -/// ```rust -/// use tracing::Subscriber; -/// use tracing_subscriber::{Layer, registry::LookupSpan}; -/// -/// pub struct MyLayer; -/// -/// impl Layer for MyLayer -/// where -/// S: Subscriber + for<'a> LookupSpan<'a>, -/// { -/// // ... -/// } -/// ``` -/// -/// [`Layer`]: super::Layer -/// [`Subscriber`]: tracing_core::Subscriber -/// [stored data]: crate::registry::SpanRef -/// [`LookupSpan`]: crate::registry::LookupSpan -#[derive(Debug)] -pub struct Context<'a, S> { - subscriber: Option<&'a S>, - /// The bitmask of all [`Filtered`] layers that currently apply in this - /// context. If there is only a single [`Filtered`] wrapping the layer that - /// produced this context, then this is that filter's ID. Otherwise, if we - /// are in a nested tree with multiple filters, this is produced by - /// [`and`]-ing together the [`FilterId`]s of each of the filters that wrap - /// the current layer. - /// - /// [`Filtered`]: crate::filter::Filtered - /// [`FilterId`]: crate::filter::FilterId - /// [`and`]: crate::filter::FilterId::and - #[cfg(all(feature = "registry", feature = "std"))] - filter: FilterId, -} - -// === impl Context === - -impl<'a, S> Context<'a, S> -where - S: Subscriber, -{ - pub(super) fn new(subscriber: &'a S) -> Self { - Self { - subscriber: Some(subscriber), - - #[cfg(feature = "registry")] - filter: FilterId::none(), - } - } - - /// Returns the wrapped subscriber's view of the current span. - #[inline] - pub fn current_span(&self) -> span::Current { - self.subscriber - .map(Subscriber::current_span) - // TODO: this would be more correct as "unknown", so perhaps - // `tracing-core` should make `Current::unknown()` public? - .unwrap_or_else(span::Current::none) - } - - /// Returns whether the wrapped subscriber would enable the current span. - #[inline] - pub fn enabled(&self, metadata: &Metadata<'_>) -> bool { - self.subscriber - .map(|subscriber| subscriber.enabled(metadata)) - // If this context is `None`, we are registering a callsite, so - // return `true` so that the layer does not incorrectly assume that - // the inner subscriber has disabled this metadata. - // TODO(eliza): would it be more correct for this to return an `Option`? - .unwrap_or(true) - } - - /// Records the provided `event` with the wrapped subscriber. - /// - /// # Notes - /// - /// - The subscriber is free to expect that the event's callsite has been - /// [registered][register], and may panic or fail to observe the event if this is - /// not the case. The `tracing` crate's macros ensure that all events are - /// registered, but if the event is constructed through other means, the - /// user is responsible for ensuring that [`register_callsite`][register] - /// has been called prior to calling this method. - /// - This does _not_ call [`enabled`] on the inner subscriber. If the - /// caller wishes to apply the wrapped subscriber's filter before choosing - /// whether to record the event, it may first call [`Context::enabled`] to - /// check whether the event would be enabled. This allows `Layer`s to - /// elide constructing the event if it would not be recorded. - /// - /// [register]: tracing_core::subscriber::Subscriber::register_callsite() - /// [`enabled`]: tracing_core::subscriber::Subscriber::enabled() - /// [`Context::enabled`]: Context::enabled() - #[inline] - pub fn event(&self, event: &Event<'_>) { - if let Some(subscriber) = self.subscriber { - subscriber.event(event); - } - } - - /// Returns a [`SpanRef`] for the parent span of the given [`Event`], if - /// it has a parent. - /// - /// If the event has an explicitly overridden parent, this method returns - /// a reference to that span. If the event's parent is the current span, - /// this returns a reference to the current span, if there is one. If this - /// returns `None`, then either the event's parent was explicitly set to - /// `None`, or the event's parent was defined contextually, but no span - /// is currently entered. - /// - /// Compared to [`Context::current_span`] and [`Context::lookup_current`], - /// this respects overrides provided by the [`Event`]. - /// - /// Compared to [`Event::parent`], this automatically falls back to the contextual - /// span, if required. - /// - /// ```rust - /// use tracing::{Event, Subscriber}; - /// use tracing_subscriber::{ - /// layer::{Context, Layer}, - /// prelude::*, - /// registry::LookupSpan, - /// }; - /// - /// struct PrintingLayer; - /// impl Layer for PrintingLayer - /// where - /// S: Subscriber + for<'lookup> LookupSpan<'lookup>, - /// { - /// fn on_event(&self, event: &Event, ctx: Context) { - /// let span = ctx.event_span(event); - /// println!("Event in span: {:?}", span.map(|s| s.name())); - /// } - /// } - /// - /// tracing::subscriber::with_default(tracing_subscriber::registry().with(PrintingLayer), || { - /// tracing::info!("no span"); - /// // Prints: Event in span: None - /// - /// let span = tracing::info_span!("span"); - /// tracing::info!(parent: &span, "explicitly specified"); - /// // Prints: Event in span: Some("span") - /// - /// let _guard = span.enter(); - /// tracing::info!("contextual span"); - /// // Prints: Event in span: Some("span") - /// }); - /// ``` - /// - ///
-    ///     Note: This requires the wrapped subscriber to
-    ///     implement the 
-    ///     LookupSpan trait. See the documentation on
-    ///     Context's
-    ///     declaration for details.
-    /// 
- #[inline] - pub fn event_span(&self, event: &Event<'_>) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - if event.is_root() { - None - } else if event.is_contextual() { - self.lookup_current() - } else { - // TODO(eliza): this should handle parent IDs - event.parent().and_then(|id| self.span(id)) - } - } - - /// Returns metadata for the span with the given `id`, if it exists. - /// - /// If this returns `None`, then no span exists for that ID (either it has - /// closed or the ID is invalid). - #[inline] - pub fn metadata(&self, id: &span::Id) -> Option<&'static Metadata<'static>> - where - S: for<'lookup> LookupSpan<'lookup>, - { - let span = self.span(id)?; - Some(span.metadata()) - } - - /// Returns [stored data] for the span with the given `id`, if it exists. - /// - /// If this returns `None`, then no span exists for that ID (either it has - /// closed or the ID is invalid). - /// - ///
-    ///     Note: This requires the wrapped subscriber to
-    ///     implement the 
-    ///     LookupSpan trait. See the documentation on
-    ///     Context's
-    ///     declaration for details.
-    /// 
- /// - /// [stored data]: crate::registry::SpanRef - #[inline] - pub fn span(&self, id: &span::Id) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - let span = self.subscriber.as_ref()?.span(id)?; - - #[cfg(all(feature = "registry", feature = "std"))] - return span.try_with_filter(self.filter); - - #[cfg(not(feature = "registry"))] - Some(span) - } - - /// Returns `true` if an active span exists for the given `Id`. - /// - ///
-    ///     Note: This requires the wrapped subscriber to
-    ///     implement the 
-    ///     LookupSpan trait. See the documentation on
-    ///     Context's
-    ///     declaration for details.
-    /// 
- #[inline] - pub fn exists(&self, id: &span::Id) -> bool - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.subscriber.as_ref().and_then(|s| s.span(id)).is_some() - } - - /// Returns [stored data] for the span that the wrapped subscriber considers - /// to be the current. - /// - /// If this returns `None`, then we are not currently within a span. - /// - ///
-    ///     Note: This requires the wrapped subscriber to
-    ///     implement the 
-    ///     LookupSpan trait. See the documentation on
-    ///     Context's
-    ///     declaration for details.
-    /// 
- /// - /// [stored data]: crate::registry::SpanRef - #[inline] - pub fn lookup_current(&self) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - let subscriber = *self.subscriber.as_ref()?; - let current = subscriber.current_span(); - let id = current.id()?; - let span = subscriber.span(id); - debug_assert!( - span.is_some(), - "the subscriber should have data for the current span ({:?})!", - id, - ); - - // If we found a span, and our per-layer filter enables it, return that - // span! - #[cfg(all(feature = "registry", feature = "std"))] - { - if let Some(span) = span?.try_with_filter(self.filter) { - Some(span) - } else { - // Otherwise, the span at the *top* of the stack is disabled by - // per-layer filtering, but there may be additional spans in the stack. - // - // Currently, `LookupSpan` doesn't have a nice way of exposing access to - // the whole span stack. However, if we can downcast the innermost - // subscriber to a a `Registry`, we can iterate over its current span - // stack. - // - // TODO(eliza): when https://github.com/tokio-rs/tracing/issues/1459 is - // implemented, change this to use that instead... - self.lookup_current_filtered(subscriber) - } - } - - #[cfg(not(feature = "registry"))] - span - } - - /// Slow path for when the current span is disabled by PLF and we have a - /// registry. - // This is called by `lookup_current` in the case that per-layer filtering - // is in use. `lookup_current` is allowed to be inlined, but this method is - // factored out to prevent the loop and (potentially-recursive) subscriber - // downcasting from being inlined if `lookup_current` is inlined. - #[inline(never)] - #[cfg(all(feature = "registry", feature = "std"))] - fn lookup_current_filtered<'lookup>( - &self, - subscriber: &'lookup S, - ) -> Option> - where - S: LookupSpan<'lookup>, - { - let registry = (subscriber as &dyn Subscriber).downcast_ref::()?; - registry - .span_stack() - .iter() - .find_map(|id| subscriber.span(id)?.try_with_filter(self.filter)) - } - - /// Returns an iterator over the [stored data] for all the spans in the - /// current context, starting with the specified span and ending with the - /// root of the trace tree and ending with the current span. - /// - ///
-    /// Note: Compared to scope this
-    /// returns the spans in reverse order (from leaf to root). Use
-    /// Scope::from_root
-    /// in case root-to-leaf ordering is desired.
-    /// 
- /// - ///
-    ///     Note: This requires the wrapped subscriber to
-    ///     implement the 
-    ///     LookupSpan trait. See the documentation on
-    ///     Context's
-    ///     declaration for details.
-    /// 
- /// - /// [stored data]: crate::registry::SpanRef - pub fn span_scope(&self, id: &span::Id) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - Some(self.span(id)?.scope()) - } - - /// Returns an iterator over the [stored data] for all the spans in the - /// current context, starting with the parent span of the specified event, - /// and ending with the root of the trace tree and ending with the current span. - /// - ///
-    /// Note: Compared to scope this
-    /// returns the spans in reverse order (from leaf to root). Use
-    /// Scope::from_root
-    /// in case root-to-leaf ordering is desired.
-    /// 
- /// - ///
-    ///     Note: This requires the wrapped subscriber to
-    ///     implement the 
-    ///     LookupSpan trait. See the documentation on
-    ///     Context's
-    ///     declaration for details.
-    /// 
- /// - /// [stored data]: crate::registry::SpanRef - pub fn event_scope(&self, event: &Event<'_>) -> Option> - where - S: for<'lookup> LookupSpan<'lookup>, - { - Some(self.event_span(event)?.scope()) - } - - #[cfg(all(feature = "registry", feature = "std"))] - pub(crate) fn with_filter(self, filter: FilterId) -> Self { - // If we already have our own `FilterId`, combine it with the provided - // one. That way, the new `FilterId` will consider a span to be disabled - // if it was disabled by the given `FilterId` *or* any `FilterId`s for - // layers "above" us in the stack. - // - // See the doc comment for `FilterId::and` for details. - let filter = self.filter.and(filter); - Self { filter, ..self } - } - - #[cfg(all(feature = "registry", feature = "std"))] - pub(crate) fn is_enabled_for(&self, span: &span::Id, filter: FilterId) -> bool - where - S: for<'lookup> LookupSpan<'lookup>, - { - self.is_enabled_inner(span, filter).unwrap_or(false) - } - - #[cfg(all(feature = "registry", feature = "std"))] - pub(crate) fn if_enabled_for(self, span: &span::Id, filter: FilterId) -> Option - where - S: for<'lookup> LookupSpan<'lookup>, - { - if self.is_enabled_inner(span, filter)? { - Some(self.with_filter(filter)) - } else { - None - } - } - - #[cfg(all(feature = "registry", feature = "std"))] - fn is_enabled_inner(&self, span: &span::Id, filter: FilterId) -> Option - where - S: for<'lookup> LookupSpan<'lookup>, - { - Some(self.span(span)?.is_enabled_for(filter)) - } -} - -impl<'a, S> Context<'a, S> { - pub(crate) fn none() -> Self { - Self { - subscriber: None, - - #[cfg(feature = "registry")] - filter: FilterId::none(), - } - } -} - -impl<'a, S> Clone for Context<'a, S> { - #[inline] - fn clone(&self) -> Self { - let subscriber = self.subscriber.as_ref().copied(); - Context { - subscriber, - - #[cfg(all(feature = "registry", feature = "std"))] - filter: self.filter, - } - } -} diff --git a/vendor/tracing-subscriber/src/layer/layered.rs b/vendor/tracing-subscriber/src/layer/layered.rs deleted file mode 100644 index 805ec13dc..000000000 --- a/vendor/tracing-subscriber/src/layer/layered.rs +++ /dev/null @@ -1,520 +0,0 @@ -use tracing_core::{ - metadata::Metadata, - span, - subscriber::{Interest, Subscriber}, - Event, LevelFilter, -}; - -use crate::{ - filter, - layer::{Context, Layer}, - registry::LookupSpan, -}; -#[cfg(all(feature = "registry", feature = "std"))] -use crate::{filter::FilterId, registry::Registry}; -use core::{ - any::{Any, TypeId}, - cmp, fmt, - marker::PhantomData, -}; - -/// A [`Subscriber`] composed of a `Subscriber` wrapped by one or more -/// [`Layer`]s. -/// -/// [`Layer`]: crate::Layer -/// [`Subscriber`]: tracing_core::Subscriber -#[derive(Clone)] -pub struct Layered { - /// The layer. - layer: L, - - /// The inner value that `self.layer` was layered onto. - /// - /// If this is also a `Layer`, then this `Layered` will implement `Layer`. - /// If this is a `Subscriber`, then this `Layered` will implement - /// `Subscriber` instead. - inner: I, - - // These booleans are used to determine how to combine `Interest`s and max - // level hints when per-layer filters are in use. - /// Is `self.inner` a `Registry`? - /// - /// If so, when combining `Interest`s, we want to "bubble up" its - /// `Interest`. - inner_is_registry: bool, - - /// Does `self.layer` have per-layer filters? - /// - /// This will be true if: - /// - `self.inner` is a `Filtered`. - /// - `self.inner` is a tree of `Layered`s where _all_ arms of those - /// `Layered`s have per-layer filters. - /// - /// Otherwise, if it's a `Layered` with one per-layer filter in one branch, - /// but a non-per-layer-filtered layer in the other branch, this will be - /// _false_, because the `Layered` is already handling the combining of - /// per-layer filter `Interest`s and max level hints with its non-filtered - /// `Layer`. - has_layer_filter: bool, - - /// Does `self.inner` have per-layer filters? - /// - /// This is determined according to the same rules as - /// `has_layer_filter` above. - inner_has_layer_filter: bool, - _s: PhantomData, -} - -// === impl Layered === - -impl Layered -where - L: Layer, - S: Subscriber, -{ - /// Returns `true` if this [`Subscriber`] is the same type as `T`. - pub fn is(&self) -> bool { - self.downcast_ref::().is_some() - } - - /// Returns some reference to this [`Subscriber`] value if it is of type `T`, - /// or `None` if it isn't. - pub fn downcast_ref(&self) -> Option<&T> { - unsafe { - let raw = self.downcast_raw(TypeId::of::())?; - if raw.is_null() { - None - } else { - Some(&*(raw as *const T)) - } - } - } -} - -impl Subscriber for Layered -where - L: Layer, - S: Subscriber, -{ - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.pick_interest(self.layer.register_callsite(metadata), || { - self.inner.register_callsite(metadata) - }) - } - - fn enabled(&self, metadata: &Metadata<'_>) -> bool { - if self.layer.enabled(metadata, self.ctx()) { - // if the outer layer enables the callsite metadata, ask the subscriber. - self.inner.enabled(metadata) - } else { - // otherwise, the callsite is disabled by the layer - - // If per-layer filters are in use, and we are short-circuiting - // (rather than calling into the inner type), clear the current - // per-layer filter `enabled` state. - #[cfg(feature = "registry")] - filter::FilterState::clear_enabled(); - - false - } - } - - fn max_level_hint(&self) -> Option { - self.pick_level_hint(self.layer.max_level_hint(), self.inner.max_level_hint()) - } - - fn new_span(&self, span: &span::Attributes<'_>) -> span::Id { - let id = self.inner.new_span(span); - self.layer.on_new_span(span, &id, self.ctx()); - id - } - - fn record(&self, span: &span::Id, values: &span::Record<'_>) { - self.inner.record(span, values); - self.layer.on_record(span, values, self.ctx()); - } - - fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { - self.inner.record_follows_from(span, follows); - self.layer.on_follows_from(span, follows, self.ctx()); - } - - fn event_enabled(&self, event: &Event<'_>) -> bool { - if self.layer.event_enabled(event, self.ctx()) { - // if the outer layer enables the event, ask the inner subscriber. - self.inner.event_enabled(event) - } else { - // otherwise, the event is disabled by this layer - false - } - } - - fn event(&self, event: &Event<'_>) { - self.inner.event(event); - self.layer.on_event(event, self.ctx()); - } - - fn enter(&self, span: &span::Id) { - self.inner.enter(span); - self.layer.on_enter(span, self.ctx()); - } - - fn exit(&self, span: &span::Id) { - self.inner.exit(span); - self.layer.on_exit(span, self.ctx()); - } - - fn clone_span(&self, old: &span::Id) -> span::Id { - let new = self.inner.clone_span(old); - if &new != old { - self.layer.on_id_change(old, &new, self.ctx()) - }; - new - } - - #[inline] - fn drop_span(&self, id: span::Id) { - self.try_close(id); - } - - fn try_close(&self, id: span::Id) -> bool { - #[cfg(all(feature = "registry", feature = "std"))] - let subscriber = &self.inner as &dyn Subscriber; - #[cfg(all(feature = "registry", feature = "std"))] - let mut guard = subscriber - .downcast_ref::() - .map(|registry| registry.start_close(id.clone())); - if self.inner.try_close(id.clone()) { - // If we have a registry's close guard, indicate that the span is - // closing. - #[cfg(all(feature = "registry", feature = "std"))] - { - if let Some(g) = guard.as_mut() { - g.set_closing() - }; - } - - self.layer.on_close(id, self.ctx()); - true - } else { - false - } - } - - #[inline] - fn current_span(&self) -> span::Current { - self.inner.current_span() - } - - #[doc(hidden)] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - // Unlike the implementation of `Layer` for `Layered`, we don't have to - // handle the "magic PLF downcast marker" here. If a `Layered` - // implements `Subscriber`, we already know that the `inner` branch is - // going to contain something that doesn't have per-layer filters (the - // actual root `Subscriber`). Thus, a `Layered` that implements - // `Subscriber` will always be propagating the root subscriber's - // `Interest`/level hint, even if it includes a `Layer` that has - // per-layer filters, because it will only ever contain layers where - // _one_ child has per-layer filters. - // - // The complex per-layer filter detection logic is only relevant to - // *trees* of layers, which involve the `Layer` implementation for - // `Layered`, not *lists* of layers, where every `Layered` implements - // `Subscriber`. Of course, a linked list can be thought of as a - // degenerate tree...but luckily, we are able to make a type-level - // distinction between individual `Layered`s that are definitely - // list-shaped (their inner child implements `Subscriber`), and - // `Layered`s that might be tree-shaped (the inner child is also a - // `Layer`). - - // If downcasting to `Self`, return a pointer to `self`. - if id == TypeId::of::() { - return Some(self as *const _ as *const ()); - } - - self.layer - .downcast_raw(id) - .or_else(|| self.inner.downcast_raw(id)) - } -} - -impl Layer for Layered -where - A: Layer, - B: Layer, - S: Subscriber, -{ - fn on_layer(&mut self, subscriber: &mut S) { - self.layer.on_layer(subscriber); - self.inner.on_layer(subscriber); - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.pick_interest(self.layer.register_callsite(metadata), || { - self.inner.register_callsite(metadata) - }) - } - - fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { - if self.layer.enabled(metadata, ctx.clone()) { - // if the outer subscriber enables the callsite metadata, ask the inner layer. - self.inner.enabled(metadata, ctx) - } else { - // otherwise, the callsite is disabled by this layer - false - } - } - - fn max_level_hint(&self) -> Option { - self.pick_level_hint(self.layer.max_level_hint(), self.inner.max_level_hint()) - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - self.inner.on_new_span(attrs, id, ctx.clone()); - self.layer.on_new_span(attrs, id, ctx); - } - - #[inline] - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - self.inner.on_record(span, values, ctx.clone()); - self.layer.on_record(span, values, ctx); - } - - #[inline] - fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { - self.inner.on_follows_from(span, follows, ctx.clone()); - self.layer.on_follows_from(span, follows, ctx); - } - - #[inline] - fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool { - if self.layer.event_enabled(event, ctx.clone()) { - // if the outer layer enables the event, ask the inner subscriber. - self.inner.event_enabled(event, ctx) - } else { - // otherwise, the event is disabled by this layer - false - } - } - - #[inline] - fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { - self.inner.on_event(event, ctx.clone()); - self.layer.on_event(event, ctx); - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - self.inner.on_enter(id, ctx.clone()); - self.layer.on_enter(id, ctx); - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - self.inner.on_exit(id, ctx.clone()); - self.layer.on_exit(id, ctx); - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - self.inner.on_close(id.clone(), ctx.clone()); - self.layer.on_close(id, ctx); - } - - #[inline] - fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { - self.inner.on_id_change(old, new, ctx.clone()); - self.layer.on_id_change(old, new, ctx); - } - - #[doc(hidden)] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - match id { - // If downcasting to `Self`, return a pointer to `self`. - id if id == TypeId::of::() => Some(self as *const _ as *const ()), - - // Oh, we're looking for per-layer filters! - // - // This should only happen if we are inside of another `Layered`, - // and it's trying to determine how it should combine `Interest`s - // and max level hints. - // - // In that case, this `Layered` should be considered to be - // "per-layer filtered" if *both* the outer layer and the inner - // layer/subscriber have per-layer filters. Otherwise, this `Layered - // should *not* be considered per-layer filtered (even if one or the - // other has per layer filters). If only one `Layer` is per-layer - // filtered, *this* `Layered` will handle aggregating the `Interest` - // and level hints on behalf of its children, returning the - // aggregate (which is the value from the &non-per-layer-filtered* - // child). - // - // Yes, this rule *is* slightly counter-intuitive, but it's - // necessary due to a weird edge case that can occur when two - // `Layered`s where one side is per-layer filtered and the other - // isn't are `Layered` together to form a tree. If we didn't have - // this rule, we would actually end up *ignoring* `Interest`s from - // the non-per-layer-filtered layers, since both branches would - // claim to have PLF. - // - // If you don't understand this...that's fine, just don't mess with - // it. :) - id if filter::is_plf_downcast_marker(id) => { - self.layer.downcast_raw(id).and(self.inner.downcast_raw(id)) - } - - // Otherwise, try to downcast both branches normally... - _ => self - .layer - .downcast_raw(id) - .or_else(|| self.inner.downcast_raw(id)), - } - } -} - -impl<'a, L, S> LookupSpan<'a> for Layered -where - S: Subscriber + LookupSpan<'a>, -{ - type Data = S::Data; - - fn span_data(&'a self, id: &span::Id) -> Option { - self.inner.span_data(id) - } - - #[cfg(all(feature = "registry", feature = "std"))] - fn register_filter(&mut self) -> FilterId { - self.inner.register_filter() - } -} - -impl Layered -where - S: Subscriber, -{ - fn ctx(&self) -> Context<'_, S> { - Context::new(&self.inner) - } -} - -impl Layered -where - A: Layer, - S: Subscriber, -{ - pub(super) fn new(layer: A, inner: B, inner_has_layer_filter: bool) -> Self { - #[cfg(all(feature = "registry", feature = "std"))] - let inner_is_registry = TypeId::of::() == TypeId::of::(); - - #[cfg(not(all(feature = "registry", feature = "std")))] - let inner_is_registry = false; - - let inner_has_layer_filter = inner_has_layer_filter || inner_is_registry; - let has_layer_filter = filter::layer_has_plf(&layer); - Self { - layer, - inner, - has_layer_filter, - inner_has_layer_filter, - inner_is_registry, - _s: PhantomData, - } - } - - fn pick_interest(&self, outer: Interest, inner: impl FnOnce() -> Interest) -> Interest { - if self.has_layer_filter { - return inner(); - } - - // If the outer layer has disabled the callsite, return now so that - // the inner layer/subscriber doesn't get its hopes up. - if outer.is_never() { - // If per-layer filters are in use, and we are short-circuiting - // (rather than calling into the inner type), clear the current - // per-layer filter interest state. - #[cfg(feature = "registry")] - filter::FilterState::take_interest(); - - return outer; - } - - // The `inner` closure will call `inner.register_callsite()`. We do this - // before the `if` statement to ensure that the inner subscriber is - // informed that the callsite exists regardless of the outer layer's - // filtering decision. - let inner = inner(); - if outer.is_sometimes() { - // if this interest is "sometimes", return "sometimes" to ensure that - // filters are reevaluated. - return outer; - } - - // If there is a per-layer filter in the `inner` stack, and it returns - // `never`, change the interest to `sometimes`, because the `outer` - // layer didn't return `never`. This means that _some_ layer still wants - // to see that callsite, even though the inner stack's per-layer filter - // didn't want it. Therefore, returning `sometimes` will ensure - // `enabled` is called so that the per-layer filter can skip that - // span/event, while the `outer` layer still gets to see it. - if inner.is_never() && self.inner_has_layer_filter { - return Interest::sometimes(); - } - - // otherwise, allow the inner subscriber or collector to weigh in. - inner - } - - fn pick_level_hint( - &self, - outer_hint: Option, - inner_hint: Option, - ) -> Option { - if self.inner_is_registry { - return outer_hint; - } - - if self.has_layer_filter && self.inner_has_layer_filter { - return Some(cmp::max(outer_hint?, inner_hint?)); - } - - if self.has_layer_filter && inner_hint.is_none() { - return None; - } - - if self.inner_has_layer_filter && outer_hint.is_none() { - return None; - } - - cmp::max(outer_hint, inner_hint) - } -} - -impl fmt::Debug for Layered -where - A: fmt::Debug, - B: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(all(feature = "registry", feature = "std"))] - let alt = f.alternate(); - let mut s = f.debug_struct("Layered"); - // These additional fields are more verbose and usually only necessary - // for internal debugging purposes, so only print them if alternate mode - // is enabled. - - #[cfg(all(feature = "registry", feature = "std"))] - { - if alt { - s.field("inner_is_registry", &self.inner_is_registry) - .field("has_layer_filter", &self.has_layer_filter) - .field("inner_has_layer_filter", &self.inner_has_layer_filter); - } - } - - s.field("layer", &self.layer) - .field("inner", &self.inner) - .finish() - } -} diff --git a/vendor/tracing-subscriber/src/layer/mod.rs b/vendor/tracing-subscriber/src/layer/mod.rs deleted file mode 100644 index 24b853323..000000000 --- a/vendor/tracing-subscriber/src/layer/mod.rs +++ /dev/null @@ -1,1798 +0,0 @@ -//! The [`Layer`] trait, a composable abstraction for building [`Subscriber`]s. -//! -//! The [`Subscriber`] trait in `tracing-core` represents the _complete_ set of -//! functionality required to consume `tracing` instrumentation. This means that -//! a single `Subscriber` instance is a self-contained implementation of a -//! complete strategy for collecting traces; but it _also_ means that the -//! `Subscriber` trait cannot easily be composed with other `Subscriber`s. -//! -//! In particular, [`Subscriber`]s are responsible for generating [span IDs] and -//! assigning them to spans. Since these IDs must uniquely identify a span -//! within the context of the current trace, this means that there may only be -//! a single `Subscriber` for a given thread at any point in time — -//! otherwise, there would be no authoritative source of span IDs. -//! -//! On the other hand, the majority of the [`Subscriber`] trait's functionality -//! is composable: any number of subscribers may _observe_ events, span entry -//! and exit, and so on, provided that there is a single authoritative source of -//! span IDs. The [`Layer`] trait represents this composable subset of the -//! [`Subscriber`] behavior; it can _observe_ events and spans, but does not -//! assign IDs. -//! -//! # Composing Layers -//! -//! Since a [`Layer`] does not implement a complete strategy for collecting -//! traces, it must be composed with a `Subscriber` in order to be used. The -//! [`Layer`] trait is generic over a type parameter (called `S` in the trait -//! definition), representing the types of `Subscriber` they can be composed -//! with. Thus, a [`Layer`] may be implemented that will only compose with a -//! particular `Subscriber` implementation, or additional trait bounds may be -//! added to constrain what types implementing `Subscriber` a `Layer` can wrap. -//! -//! `Layer`s may be added to a `Subscriber` by using the [`SubscriberExt::with`] -//! method, which is provided by `tracing-subscriber`'s [prelude]. This method -//! returns a [`Layered`] struct that implements `Subscriber` by composing the -//! `Layer` with the `Subscriber`. -//! -//! For example: -//! ```rust -//! use tracing_subscriber::Layer; -//! use tracing_subscriber::prelude::*; -//! use tracing::Subscriber; -//! -//! pub struct MyLayer { -//! // ... -//! } -//! -//! impl Layer for MyLayer { -//! // ... -//! } -//! -//! pub struct MySubscriber { -//! // ... -//! } -//! -//! # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; -//! impl Subscriber for MySubscriber { -//! // ... -//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } -//! # fn record(&self, _: &Id, _: &Record) {} -//! # fn event(&self, _: &Event) {} -//! # fn record_follows_from(&self, _: &Id, _: &Id) {} -//! # fn enabled(&self, _: &Metadata) -> bool { false } -//! # fn enter(&self, _: &Id) {} -//! # fn exit(&self, _: &Id) {} -//! } -//! # impl MyLayer { -//! # fn new() -> Self { Self {} } -//! # } -//! # impl MySubscriber { -//! # fn new() -> Self { Self { }} -//! # } -//! -//! let subscriber = MySubscriber::new() -//! .with(MyLayer::new()); -//! -//! tracing::subscriber::set_global_default(subscriber); -//! ``` -//! -//! Multiple `Layer`s may be composed in the same manner: -//! ```rust -//! # use tracing_subscriber::{Layer, layer::SubscriberExt}; -//! # use tracing::Subscriber; -//! pub struct MyOtherLayer { -//! // ... -//! } -//! -//! impl Layer for MyOtherLayer { -//! // ... -//! } -//! -//! pub struct MyThirdLayer { -//! // ... -//! } -//! -//! impl Layer for MyThirdLayer { -//! // ... -//! } -//! # pub struct MyLayer {} -//! # impl Layer for MyLayer {} -//! # pub struct MySubscriber { } -//! # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; -//! # impl Subscriber for MySubscriber { -//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } -//! # fn record(&self, _: &Id, _: &Record) {} -//! # fn event(&self, _: &Event) {} -//! # fn record_follows_from(&self, _: &Id, _: &Id) {} -//! # fn enabled(&self, _: &Metadata) -> bool { false } -//! # fn enter(&self, _: &Id) {} -//! # fn exit(&self, _: &Id) {} -//! } -//! # impl MyLayer { -//! # fn new() -> Self { Self {} } -//! # } -//! # impl MyOtherLayer { -//! # fn new() -> Self { Self {} } -//! # } -//! # impl MyThirdLayer { -//! # fn new() -> Self { Self {} } -//! # } -//! # impl MySubscriber { -//! # fn new() -> Self { Self { }} -//! # } -//! -//! let subscriber = MySubscriber::new() -//! .with(MyLayer::new()) -//! .with(MyOtherLayer::new()) -//! .with(MyThirdLayer::new()); -//! -//! tracing::subscriber::set_global_default(subscriber); -//! ``` -//! -//! The [`Layer::with_subscriber`] constructs the [`Layered`] type from a -//! [`Layer`] and [`Subscriber`], and is called by [`SubscriberExt::with`]. In -//! general, it is more idiomatic to use [`SubscriberExt::with`], and treat -//! [`Layer::with_subscriber`] as an implementation detail, as `with_subscriber` -//! calls must be nested, leading to less clear code for the reader. -//! -//! ## Runtime Configuration With `Layer`s -//! -//! In some cases, a particular [`Layer`] may be enabled or disabled based on -//! runtime configuration. This can introduce challenges, because the type of a -//! layered [`Subscriber`] depends on which layers are added to it: if an `if` -//! or `match` expression adds some [`Layer`] implementation in one branch, -//! and other layers in another, the [`Subscriber`] values returned by those -//! branches will have different types. For example, the following _will not_ -//! work: -//! -//! ```compile_fail -//! # fn docs() -> Result<(), Box> { -//! # struct Config { -//! # is_prod: bool, -//! # path: &'static str, -//! # } -//! # let cfg = Config { is_prod: false, path: "debug.log" }; -//! use std::fs::File; -//! use tracing_subscriber::{Registry, prelude::*}; -//! -//! let stdout_log = tracing_subscriber::fmt::layer().pretty(); -//! let subscriber = Registry::default().with(stdout_log); -//! -//! // The compile error will occur here because the if and else -//! // branches have different (and therefore incompatible) types. -//! let subscriber = if cfg.is_prod { -//! let file = File::create(cfg.path)?; -//! let layer = tracing_subscriber::fmt::layer() -//! .json() -//! .with_writer(Arc::new(file)); -//! layer.with(subscriber) -//! } else { -//! layer -//! }; -//! -//! tracing::subscriber::set_global_default(subscriber) -//! .expect("Unable to set global subscriber"); -//! # Ok(()) } -//! ``` -//! -//! However, a [`Layer`] wrapped in an [`Option`] [also implements the `Layer` -//! trait][option-impl]. This allows individual layers to be enabled or disabled at -//! runtime while always producing a [`Subscriber`] of the same type. For -//! example: -//! -//! ``` -//! # fn docs() -> Result<(), Box> { -//! # struct Config { -//! # is_prod: bool, -//! # path: &'static str, -//! # } -//! # let cfg = Config { is_prod: false, path: "debug.log" }; -//! use std::fs::File; -//! use tracing_subscriber::{Registry, prelude::*}; -//! -//! let stdout_log = tracing_subscriber::fmt::layer().pretty(); -//! let subscriber = Registry::default().with(stdout_log); -//! -//! // if `cfg.is_prod` is true, also log JSON-formatted logs to a file. -//! let json_log = if cfg.is_prod { -//! let file = File::create(cfg.path)?; -//! let json_log = tracing_subscriber::fmt::layer() -//! .json() -//! .with_writer(file); -//! Some(json_log) -//! } else { -//! None -//! }; -//! -//! // If `cfg.is_prod` is false, then `json` will be `None`, and this layer -//! // will do nothing. However, the subscriber will still have the same type -//! // regardless of whether the `Option`'s value is `None` or `Some`. -//! let subscriber = subscriber.with(json_log); -//! -//! tracing::subscriber::set_global_default(subscriber) -//! .expect("Unable to set global subscriber"); -//! # Ok(()) } -//! ``` -//! -//! If a [`Layer`] may be one of several different types, note that [`Box + Send + Sync>` implements `Layer`][box-impl]. -//! This may be used to erase the type of a [`Layer`]. -//! -//! For example, a function that configures a [`Layer`] to log to one of -//! several outputs might return a `Box + Send + Sync + 'static>`: -//! ``` -//! use tracing_subscriber::{ -//! Layer, -//! registry::LookupSpan, -//! prelude::*, -//! }; -//! use std::{path::PathBuf, fs::File, io}; -//! -//! /// Configures whether logs are emitted to a file, to stdout, or to stderr. -//! pub enum LogConfig { -//! File(PathBuf), -//! Stdout, -//! Stderr, -//! } -//! -//! impl LogConfig { -//! pub fn layer(self) -> Box + Send + Sync + 'static> -//! where -//! S: tracing_core::Subscriber, -//! for<'a> S: LookupSpan<'a>, -//! { -//! // Shared configuration regardless of where logs are output to. -//! let fmt = tracing_subscriber::fmt::layer() -//! .with_target(true) -//! .with_thread_names(true); -//! -//! // Configure the writer based on the desired log target: -//! match self { -//! LogConfig::File(path) => { -//! let file = File::create(path).expect("failed to create log file"); -//! Box::new(fmt.with_writer(file)) -//! }, -//! LogConfig::Stdout => Box::new(fmt.with_writer(io::stdout)), -//! LogConfig::Stderr => Box::new(fmt.with_writer(io::stderr)), -//! } -//! } -//! } -//! -//! let config = LogConfig::Stdout; -//! tracing_subscriber::registry() -//! .with(config.layer()) -//! .init(); -//! ``` -//! -//! The [`Layer::boxed`] method is provided to make boxing a `Layer` -//! more convenient, but [`Box::new`] may be used as well. -//! -//! When the number of `Layer`s varies at runtime, note that a -//! [`Vec where L: Layer` also implements `Layer`][vec-impl]. This -//! can be used to add a variable number of `Layer`s to a `Subscriber`: -//! -//! ``` -//! use tracing_subscriber::{Layer, prelude::*}; -//! struct MyLayer { -//! // ... -//! } -//! # impl MyLayer { fn new() -> Self { Self {} }} -//! -//! impl Layer for MyLayer { -//! // ... -//! } -//! -//! /// Returns how many layers we need -//! fn how_many_layers() -> usize { -//! // ... -//! # 3 -//! } -//! -//! // Create a variable-length `Vec` of layers -//! let mut layers = Vec::new(); -//! for _ in 0..how_many_layers() { -//! layers.push(MyLayer::new()); -//! } -//! -//! tracing_subscriber::registry() -//! .with(layers) -//! .init(); -//! ``` -//! -//! If a variable number of `Layer` is needed and those `Layer`s have -//! different types, a `Vec` of [boxed `Layer` trait objects][box-impl] may -//! be used. For example: -//! -//! ``` -//! use tracing_subscriber::{filter::LevelFilter, Layer, prelude::*}; -//! use std::fs::File; -//! # fn main() -> Result<(), Box> { -//! struct Config { -//! enable_log_file: bool, -//! enable_stdout: bool, -//! enable_stderr: bool, -//! // ... -//! } -//! # impl Config { -//! # fn from_config_file()-> Result> { -//! # // don't enable the log file so that the example doesn't actually create it -//! # Ok(Self { enable_log_file: false, enable_stdout: true, enable_stderr: true }) -//! # } -//! # } -//! -//! let cfg = Config::from_config_file()?; -//! -//! // Based on our dynamically loaded config file, create any number of layers: -//! let mut layers = Vec::new(); -//! -//! if cfg.enable_log_file { -//! let file = File::create("myapp.log")?; -//! let layer = tracing_subscriber::fmt::layer() -//! .with_thread_names(true) -//! .with_target(true) -//! .json() -//! .with_writer(file) -//! // Box the layer as a type-erased trait object, so that it can -//! // be pushed to the `Vec`. -//! .boxed(); -//! layers.push(layer); -//! } -//! -//! if cfg.enable_stdout { -//! let layer = tracing_subscriber::fmt::layer() -//! .pretty() -//! .with_filter(LevelFilter::INFO) -//! // Box the layer as a type-erased trait object, so that it can -//! // be pushed to the `Vec`. -//! .boxed(); -//! layers.push(layer); -//! } -//! -//! if cfg.enable_stdout { -//! let layer = tracing_subscriber::fmt::layer() -//! .with_target(false) -//! .with_filter(LevelFilter::WARN) -//! // Box the layer as a type-erased trait object, so that it can -//! // be pushed to the `Vec`. -//! .boxed(); -//! layers.push(layer); -//! } -//! -//! tracing_subscriber::registry() -//! .with(layers) -//! .init(); -//!# Ok(()) } -//! ``` -//! -//! Finally, if the number of layers _changes_ at runtime, a `Vec` of -//! subscribers can be used alongside the [`reload`](crate::reload) module to -//! add or remove subscribers dynamically at runtime. -//! -//! [option-impl]: Layer#impl-Layer-for-Option -//! [box-impl]: Layer#impl-Layer%3CS%3E-for-Box%3Cdyn%20Layer%3CS%3E%20+%20Send%20+%20Sync%3E -//! [vec-impl]: Layer#impl-Layer-for-Vec -//! [prelude]: crate::prelude -//! -//! # Recording Traces -//! -//! The [`Layer`] trait defines a set of methods for consuming notifications from -//! tracing instrumentation, which are generally equivalent to the similarly -//! named methods on [`Subscriber`]. Unlike [`Subscriber`], the methods on -//! `Layer` are additionally passed a [`Context`] type, which exposes additional -//! information provided by the wrapped subscriber (such as [the current span]) -//! to the layer. -//! -//! # Filtering with `Layer`s -//! -//! As well as strategies for handling trace events, the `Layer` trait may also -//! be used to represent composable _filters_. This allows the determination of -//! what spans and events should be recorded to be decoupled from _how_ they are -//! recorded: a filtering layer can be applied to other layers or -//! subscribers. `Layer`s can be used to implement _global filtering_, where a -//! `Layer` provides a filtering strategy for the entire subscriber. -//! Additionally, individual recording `Layer`s or sets of `Layer`s may be -//! combined with _per-layer filters_ that control what spans and events are -//! recorded by those layers. -//! -//! ## Global Filtering -//! -//! A `Layer` that implements a filtering strategy should override the -//! [`register_callsite`] and/or [`enabled`] methods. It may also choose to implement -//! methods such as [`on_enter`], if it wishes to filter trace events based on -//! the current span context. -//! -//! Note that the [`Layer::register_callsite`] and [`Layer::enabled`] methods -//! determine whether a span or event is enabled *globally*. Thus, they should -//! **not** be used to indicate whether an individual layer wishes to record a -//! particular span or event. Instead, if a layer is only interested in a subset -//! of trace data, but does *not* wish to disable other spans and events for the -//! rest of the layer stack should ignore those spans and events in its -//! notification methods. -//! -//! The filtering methods on a stack of `Layer`s are evaluated in a top-down -//! order, starting with the outermost `Layer` and ending with the wrapped -//! [`Subscriber`]. If any layer returns `false` from its [`enabled`] method, or -//! [`Interest::never()`] from its [`register_callsite`] method, filter -//! evaluation will short-circuit and the span or event will be disabled. -//! -//! ### Enabling Interest -//! -//! Whenever an tracing event (or span) is emitted, it goes through a number of -//! steps to determine how and how much it should be processed. The earlier an -//! event is disabled, the less work has to be done to process the event, so -//! `Layer`s that implement filtering should attempt to disable unwanted -//! events as early as possible. In order, each event checks: -//! -//! - [`register_callsite`], once per callsite (roughly: once per time that -//! `event!` or `span!` is written in the source code; this is cached at the -//! callsite). See [`Subscriber::register_callsite`] and -//! [`tracing_core::callsite`] for a summary of how this behaves. -//! - [`enabled`], once per emitted event (roughly: once per time that `event!` -//! or `span!` is *executed*), and only if `register_callsite` regesters an -//! [`Interest::sometimes`]. This is the main customization point to globally -//! filter events based on their [`Metadata`]. If an event can be disabled -//! based only on [`Metadata`], it should be, as this allows the construction -//! of the actual `Event`/`Span` to be skipped. -//! - For events only (and not spans), [`event_enabled`] is called just before -//! processing the event. This gives layers one last chance to say that -//! an event should be filtered out, now that the event's fields are known. -//! -//! ## Per-Layer Filtering -//! -//! **Note**: per-layer filtering APIs currently require the [`"registry"` crate -//! feature flag][feat] to be enabled. -//! -//! Sometimes, it may be desirable for one `Layer` to record a particular subset -//! of spans and events, while a different subset of spans and events are -//! recorded by other `Layer`s. For example: -//! -//! - A layer that records metrics may wish to observe only events including -//! particular tracked values, while a logging layer ignores those events. -//! - If recording a distributed trace is expensive, it might be desirable to -//! only send spans with `INFO` and lower verbosity to the distributed tracing -//! system, while logging more verbose spans to a file. -//! - Spans and events with a particular target might be recorded differently -//! from others, such as by generating an HTTP access log from a span that -//! tracks the lifetime of an HTTP request. -//! -//! The [`Filter`] trait is used to control what spans and events are -//! observed by an individual `Layer`, while still allowing other `Layer`s to -//! potentially record them. The [`Layer::with_filter`] method combines a -//! `Layer` with a [`Filter`], returning a [`Filtered`] layer. -//! -//! This crate's [`filter`] module provides a number of types which implement -//! the [`Filter`] trait, such as [`LevelFilter`], [`Targets`], and -//! [`FilterFn`]. These [`Filter`]s provide ready-made implementations of -//! common forms of filtering. For custom filtering policies, the [`FilterFn`] -//! and [`DynFilterFn`] types allow implementing a [`Filter`] with a closure or -//! function pointer. In addition, when more control is required, the [`Filter`] -//! trait may also be implemented for user-defined types. -//! -//!
-//!     Warning: Currently, the 
-//!     Registry type defined in this crate is the only root
-//!     Subscriber capable of supporting Layers with
-//!     per-layer filters. In the future, new APIs will be added to allow other
-//!     root Subscribers to support per-layer filters.
-//! 
-//! -//! For example, to generate an HTTP access log based on spans with -//! the `http_access` target, while logging other spans and events to -//! standard out, a [`Filter`] can be added to the access log layer: -//! -//! ``` -//! use tracing_subscriber::{filter, prelude::*}; -//! -//! // Generates an HTTP access log. -//! let access_log = // ... -//! # filter::LevelFilter::INFO; -//! -//! // Add a filter to the access log layer so that it only observes -//! // spans and events with the `http_access` target. -//! let access_log = access_log.with_filter(filter::filter_fn(|metadata| { -//! // Returns `true` if and only if the span or event's target is -//! // "http_access". -//! metadata.target() == "http_access" -//! })); -//! -//! // A general-purpose logging layer. -//! let fmt_layer = tracing_subscriber::fmt::layer(); -//! -//! // Build a subscriber that combines the access log and stdout log -//! // layers. -//! tracing_subscriber::registry() -//! .with(fmt_layer) -//! .with(access_log) -//! .init(); -//! ``` -//! -//! Multiple layers can have their own, separate per-layer filters. A span or -//! event will be recorded if it is enabled by _any_ per-layer filter, but it -//! will be skipped by the layers whose filters did not enable it. Building on -//! the previous example: -//! -//! ``` -//! use tracing_subscriber::{filter::{filter_fn, LevelFilter}, prelude::*}; -//! -//! let access_log = // ... -//! # LevelFilter::INFO; -//! let fmt_layer = tracing_subscriber::fmt::layer(); -//! -//! tracing_subscriber::registry() -//! // Add the filter for the "http_access" target to the access -//! // log layer, like before. -//! .with(access_log.with_filter(filter_fn(|metadata| { -//! metadata.target() == "http_access" -//! }))) -//! // Add a filter for spans and events with the INFO level -//! // and below to the logging layer. -//! .with(fmt_layer.with_filter(LevelFilter::INFO)) -//! .init(); -//! -//! // Neither layer will observe this event -//! tracing::debug!(does_anyone_care = false, "a tree fell in the forest"); -//! -//! // This event will be observed by the logging layer, but not -//! // by the access log layer. -//! tracing::warn!(dose_roentgen = %3.8, "not great, but not terrible"); -//! -//! // This event will be observed only by the access log layer. -//! tracing::trace!(target: "http_access", "HTTP request started"); -//! -//! // Both layers will observe this event. -//! tracing::error!(target: "http_access", "HTTP request failed with a very bad error!"); -//! ``` -//! -//! A per-layer filter can be applied to multiple [`Layer`]s at a time, by -//! combining them into a [`Layered`] layer using [`Layer::and_then`], and then -//! calling [`Layer::with_filter`] on the resulting [`Layered`] layer. -//! -//! Consider the following: -//! - `layer_a` and `layer_b`, which should only receive spans and events at -//! the [`INFO`] [level] and above. -//! - A third layer, `layer_c`, which should receive spans and events at -//! the [`DEBUG`] [level] as well. -//! The layers and filters would be composed thusly: -//! -//! ``` -//! use tracing_subscriber::{filter::LevelFilter, prelude::*}; -//! -//! let layer_a = // ... -//! # LevelFilter::INFO; -//! let layer_b = // ... -//! # LevelFilter::INFO; -//! let layer_c = // ... -//! # LevelFilter::INFO; -//! -//! let info_layers = layer_a -//! // Combine `layer_a` and `layer_b` into a `Layered` layer: -//! .and_then(layer_b) -//! // ...and then add an `INFO` `LevelFilter` to that layer: -//! .with_filter(LevelFilter::INFO); -//! -//! tracing_subscriber::registry() -//! // Add `layer_c` with a `DEBUG` filter. -//! .with(layer_c.with_filter(LevelFilter::DEBUG)) -//! .with(info_layers) -//! .init(); -//!``` -//! -//! If a [`Filtered`] [`Layer`] is combined with another [`Layer`] -//! [`Layer::and_then`], and a filter is added to the [`Layered`] layer, that -//! layer will be filtered by *both* the inner filter and the outer filter. -//! Only spans and events that are enabled by *both* filters will be -//! observed by that layer. This can be used to implement complex filtering -//! trees. -//! -//! As an example, consider the following constraints: -//! - Suppose that a particular [target] is used to indicate events that -//! should be counted as part of a metrics system, which should be only -//! observed by a layer that collects metrics. -//! - A log of high-priority events ([`INFO`] and above) should be logged -//! to stdout, while more verbose events should be logged to a debugging log file. -//! - Metrics-focused events should *not* be included in either log output. -//! -//! In that case, it is possible to apply a filter to both logging layers to -//! exclude the metrics events, while additionally adding a [`LevelFilter`] -//! to the stdout log: -//! -//! ``` -//! # // wrap this in a function so we don't actually create `debug.log` when -//! # // running the doctests.. -//! # fn docs() -> Result<(), Box> { -//! use tracing_subscriber::{filter, prelude::*}; -//! use std::{fs::File, sync::Arc}; -//! -//! // A layer that logs events to stdout using the human-readable "pretty" -//! // format. -//! let stdout_log = tracing_subscriber::fmt::layer() -//! .pretty(); -//! -//! // A layer that logs events to a file. -//! let file = File::create("debug.log")?; -//! let debug_log = tracing_subscriber::fmt::layer() -//! .with_writer(Arc::new(file)); -//! -//! // A layer that collects metrics using specific events. -//! let metrics_layer = /* ... */ filter::LevelFilter::INFO; -//! -//! tracing_subscriber::registry() -//! .with( -//! stdout_log -//! // Add an `INFO` filter to the stdout logging layer -//! .with_filter(filter::LevelFilter::INFO) -//! // Combine the filtered `stdout_log` layer with the -//! // `debug_log` layer, producing a new `Layered` layer. -//! .and_then(debug_log) -//! // Add a filter to *both* layers that rejects spans and -//! // events whose targets start with `metrics`. -//! .with_filter(filter::filter_fn(|metadata| { -//! !metadata.target().starts_with("metrics") -//! })) -//! ) -//! .with( -//! // Add a filter to the metrics label that *only* enables -//! // events whose targets start with `metrics`. -//! metrics_layer.with_filter(filter::filter_fn(|metadata| { -//! metadata.target().starts_with("metrics") -//! })) -//! ) -//! .init(); -//! -//! // This event will *only* be recorded by the metrics layer. -//! tracing::info!(target: "metrics::cool_stuff_count", value = 42); -//! -//! // This event will only be seen by the debug log file layer: -//! tracing::debug!("this is a message, and part of a system of messages"); -//! -//! // This event will be seen by both the stdout log layer *and* -//! // the debug log file layer, but not by the metrics layer. -//! tracing::warn!("the message is a warning about danger!"); -//! # Ok(()) } -//! ``` -//! -//! [`Subscriber`]: tracing_core::subscriber::Subscriber -//! [span IDs]: tracing_core::span::Id -//! [the current span]: Context::current_span -//! [`register_callsite`]: Layer::register_callsite -//! [`enabled`]: Layer::enabled -//! [`event_enabled`]: Layer::event_enabled -//! [`on_enter`]: Layer::on_enter -//! [`Layer::register_callsite`]: Layer::register_callsite -//! [`Layer::enabled`]: Layer::enabled -//! [`Interest::never()`]: tracing_core::subscriber::Interest::never() -//! [`Filtered`]: crate::filter::Filtered -//! [`filter`]: crate::filter -//! [`Targets`]: crate::filter::Targets -//! [`FilterFn`]: crate::filter::FilterFn -//! [`DynFilterFn`]: crate::filter::DynFilterFn -//! [level]: tracing_core::Level -//! [`INFO`]: tracing_core::Level::INFO -//! [`DEBUG`]: tracing_core::Level::DEBUG -//! [target]: tracing_core::Metadata::target -//! [`LevelFilter`]: crate::filter::LevelFilter -//! [feat]: crate#feature-flags -use crate::filter; - -use tracing_core::{ - metadata::Metadata, - span, - subscriber::{Interest, Subscriber}, - Event, LevelFilter, -}; - -use core::any::TypeId; - -feature! { - #![feature = "alloc"] - use alloc::boxed::Box; - use core::ops::{Deref, DerefMut}; -} - -mod context; -mod layered; -pub use self::{context::*, layered::*}; - -// The `tests` module is `pub(crate)` because it contains test utilities used by -// other modules. -#[cfg(test)] -pub(crate) mod tests; - -/// A composable handler for `tracing` events. -/// -/// A `Layer` implements a behavior for recording or collecting traces that can -/// be composed together with other `Layer`s to build a [`Subscriber`]. See the -/// [module-level documentation](crate::layer) for details. -/// -/// [`Subscriber`]: tracing_core::Subscriber -#[cfg_attr(docsrs, doc(notable_trait))] -pub trait Layer -where - S: Subscriber, - Self: 'static, -{ - /// Performs late initialization when attaching a `Layer` to a - /// [`Subscriber`]. - /// - /// This is a callback that is called when the `Layer` is added to a - /// [`Subscriber`] (e.g. in [`Layer::with_subscriber`] and - /// [`SubscriberExt::with`]). Since this can only occur before the - /// [`Subscriber`] has been set as the default, both the `Layer` and - /// [`Subscriber`] are passed to this method _mutably_. This gives the - /// `Layer` the opportunity to set any of its own fields with values - /// recieved by method calls on the [`Subscriber`]. - /// - /// For example, [`Filtered`] layers implement `on_layer` to call the - /// [`Subscriber`]'s [`register_filter`] method, and store the returned - /// [`FilterId`] as a field. - /// - /// **Note** In most cases, `Layer` implementations will not need to - /// implement this method. However, in cases where a type implementing - /// `Layer` wraps one or more other types that implement `Layer`, like the - /// [`Layered`] and [`Filtered`] types in this crate, that type MUST ensure - /// that the inner `Layer`s' `on_layer` methods are called. Otherwise, - /// functionality that relies on `on_layer`, such as [per-layer filtering], - /// may not work correctly. - /// - /// [`Filtered`]: crate::filter::Filtered - /// [`register_filter`]: crate::registry::LookupSpan::register_filter - /// [per-layer filtering]: #per-layer-filtering - /// [`FilterId`]: crate::filter::FilterId - fn on_layer(&mut self, subscriber: &mut S) { - let _ = subscriber; - } - - /// Registers a new callsite with this layer, returning whether or not - /// the layer is interested in being notified about the callsite, similarly - /// to [`Subscriber::register_callsite`]. - /// - /// By default, this returns [`Interest::always()`] if [`self.enabled`] returns - /// true, or [`Interest::never()`] if it returns false. - /// - ///
-    /// Note: This method (and 
-    /// Layer::enabled) determine whether a span or event is
-    /// globally enabled, not whether the individual layer will be
-    /// notified about that span or event. This is intended to be used
-    /// by layers that implement filtering for the entire stack. Layers which do
-    /// not wish to be notified about certain spans or events but do not wish to
-    /// globally disable them should ignore those spans or events in their
-    /// on_event,
-    /// on_enter,
-    /// on_exit, and other notification
-    /// methods.
-    /// 
- /// - /// See [the trait-level documentation] for more information on filtering - /// with `Layer`s. - /// - /// Layers may also implement this method to perform any behaviour that - /// should be run once per callsite. If the layer wishes to use - /// `register_callsite` for per-callsite behaviour, but does not want to - /// globally enable or disable those callsites, it should always return - /// [`Interest::always()`]. - /// - /// [`Interest`]: tracing_core::Interest - /// [`Subscriber::register_callsite`]: tracing_core::Subscriber::register_callsite() - /// [`Interest::never()`]: tracing_core::subscriber::Interest::never() - /// [`Interest::always()`]: tracing_core::subscriber::Interest::always() - /// [`self.enabled`]: Layer::enabled() - /// [`Layer::enabled`]: Layer::enabled() - /// [`on_event`]: Layer::on_event() - /// [`on_enter`]: Layer::on_enter() - /// [`on_exit`]: Layer::on_exit() - /// [the trait-level documentation]: #filtering-with-layers - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - if self.enabled(metadata, Context::none()) { - Interest::always() - } else { - Interest::never() - } - } - - /// Returns `true` if this layer is interested in a span or event with the - /// given `metadata` in the current [`Context`], similarly to - /// [`Subscriber::enabled`]. - /// - /// By default, this always returns `true`, allowing the wrapped subscriber - /// to choose to disable the span. - /// - ///
-    /// Note: This method (and 
-    /// Layer::register_callsite) determine whether a span or event is
-    /// globally enabled, not whether the individual layer will be
-    /// notified about that span or event. This is intended to be used
-    /// by layers that implement filtering for the entire stack. Layers which do
-    /// not wish to be notified about certain spans or events but do not wish to
-    /// globally disable them should ignore those spans or events in their
-    /// on_event,
-    /// on_enter,
-    /// on_exit, and other notification
-    /// methods.
-    /// 
- /// - /// - /// See [the trait-level documentation] for more information on filtering - /// with `Layer`s. - /// - /// [`Interest`]: tracing_core::Interest - /// [`Subscriber::enabled`]: tracing_core::Subscriber::enabled() - /// [`Layer::register_callsite`]: Layer::register_callsite() - /// [`on_event`]: Layer::on_event() - /// [`on_enter`]: Layer::on_enter() - /// [`on_exit`]: Layer::on_exit() - /// [the trait-level documentation]: #filtering-with-layers - fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { - let _ = (metadata, ctx); - true - } - - /// Notifies this layer that a new span was constructed with the given - /// `Attributes` and `Id`. - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - let _ = (attrs, id, ctx); - } - - // TODO(eliza): do we want this to be a public API? If we end up moving - // filtering layers to a separate trait, we may no longer want `Layer`s to - // be able to participate in max level hinting... - #[doc(hidden)] - fn max_level_hint(&self) -> Option { - None - } - - /// Notifies this layer that a span with the given `Id` recorded the given - /// `values`. - // Note: it's unclear to me why we'd need the current span in `record` (the - // only thing the `Context` type currently provides), but passing it in anyway - // seems like a good future-proofing measure as it may grow other methods later... - fn on_record(&self, _span: &span::Id, _values: &span::Record<'_>, _ctx: Context<'_, S>) {} - - /// Notifies this layer that a span with the ID `span` recorded that it - /// follows from the span with the ID `follows`. - // Note: it's unclear to me why we'd need the current span in `record` (the - // only thing the `Context` type currently provides), but passing it in anyway - // seems like a good future-proofing measure as it may grow other methods later... - fn on_follows_from(&self, _span: &span::Id, _follows: &span::Id, _ctx: Context<'_, S>) {} - - /// Called before [`on_event`], to determine if `on_event` should be called. - /// - ///
- ///
-    ///
-    /// **Note**: This method determines whether an event is globally enabled,
-    /// *not* whether the individual `Layer` will be notified about the
-    /// event. This is intended to be used by `Layer`s that implement
-    /// filtering for the entire stack. `Layer`s which do not wish to be
-    /// notified about certain events but do not wish to globally disable them
-    /// should ignore those events in their [on_event][Self::on_event].
-    ///
-    /// 
- /// - /// See [the trait-level documentation] for more information on filtering - /// with `Layer`s. - /// - /// [`on_event`]: Self::on_event - /// [`Interest`]: tracing_core::Interest - /// [the trait-level documentation]: #filtering-with-layers - #[inline] // collapse this to a constant please mrs optimizer - fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, S>) -> bool { - true - } - - /// Notifies this layer that an event has occurred. - fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, S>) {} - - /// Notifies this layer that a span with the given ID was entered. - fn on_enter(&self, _id: &span::Id, _ctx: Context<'_, S>) {} - - /// Notifies this layer that the span with the given ID was exited. - fn on_exit(&self, _id: &span::Id, _ctx: Context<'_, S>) {} - - /// Notifies this layer that the span with the given ID has been closed. - fn on_close(&self, _id: span::Id, _ctx: Context<'_, S>) {} - - /// Notifies this layer that a span ID has been cloned, and that the - /// subscriber returned a different ID. - fn on_id_change(&self, _old: &span::Id, _new: &span::Id, _ctx: Context<'_, S>) {} - - /// Composes this layer around the given `Layer`, returning a `Layered` - /// struct implementing `Layer`. - /// - /// The returned `Layer` will call the methods on this `Layer` and then - /// those of the new `Layer`, before calling the methods on the subscriber - /// it wraps. For example: - /// - /// ```rust - /// # use tracing_subscriber::layer::Layer; - /// # use tracing_core::Subscriber; - /// pub struct FooLayer { - /// // ... - /// } - /// - /// pub struct BarLayer { - /// // ... - /// } - /// - /// pub struct MySubscriber { - /// // ... - /// } - /// - /// impl Layer for FooLayer { - /// // ... - /// } - /// - /// impl Layer for BarLayer { - /// // ... - /// } - /// - /// # impl FooLayer { - /// # fn new() -> Self { Self {} } - /// # } - /// # impl BarLayer { - /// # fn new() -> Self { Self { }} - /// # } - /// # impl MySubscriber { - /// # fn new() -> Self { Self { }} - /// # } - /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; - /// # impl tracing_core::Subscriber for MySubscriber { - /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } - /// # fn record(&self, _: &Id, _: &Record) {} - /// # fn event(&self, _: &Event) {} - /// # fn record_follows_from(&self, _: &Id, _: &Id) {} - /// # fn enabled(&self, _: &Metadata) -> bool { false } - /// # fn enter(&self, _: &Id) {} - /// # fn exit(&self, _: &Id) {} - /// # } - /// let subscriber = FooLayer::new() - /// .and_then(BarLayer::new()) - /// .with_subscriber(MySubscriber::new()); - /// ``` - /// - /// Multiple layers may be composed in this manner: - /// - /// ```rust - /// # use tracing_subscriber::layer::Layer; - /// # use tracing_core::Subscriber; - /// # pub struct FooLayer {} - /// # pub struct BarLayer {} - /// # pub struct MySubscriber {} - /// # impl Layer for FooLayer {} - /// # impl Layer for BarLayer {} - /// # impl FooLayer { - /// # fn new() -> Self { Self {} } - /// # } - /// # impl BarLayer { - /// # fn new() -> Self { Self { }} - /// # } - /// # impl MySubscriber { - /// # fn new() -> Self { Self { }} - /// # } - /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; - /// # impl tracing_core::Subscriber for MySubscriber { - /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) } - /// # fn record(&self, _: &Id, _: &Record) {} - /// # fn event(&self, _: &Event) {} - /// # fn record_follows_from(&self, _: &Id, _: &Id) {} - /// # fn enabled(&self, _: &Metadata) -> bool { false } - /// # fn enter(&self, _: &Id) {} - /// # fn exit(&self, _: &Id) {} - /// # } - /// pub struct BazLayer { - /// // ... - /// } - /// - /// impl Layer for BazLayer { - /// // ... - /// } - /// # impl BazLayer { fn new() -> Self { BazLayer {} } } - /// - /// let subscriber = FooLayer::new() - /// .and_then(BarLayer::new()) - /// .and_then(BazLayer::new()) - /// .with_subscriber(MySubscriber::new()); - /// ``` - fn and_then(self, layer: L) -> Layered - where - L: Layer, - Self: Sized, - { - let inner_has_layer_filter = filter::layer_has_plf(&self); - Layered::new(layer, self, inner_has_layer_filter) - } - - /// Composes this `Layer` with the given [`Subscriber`], returning a - /// `Layered` struct that implements [`Subscriber`]. - /// - /// The returned `Layered` subscriber will call the methods on this `Layer` - /// and then those of the wrapped subscriber. - /// - /// For example: - /// ```rust - /// # use tracing_subscriber::layer::Layer; - /// # use tracing_core::Subscriber; - /// pub struct FooLayer { - /// // ... - /// } - /// - /// pub struct MySubscriber { - /// // ... - /// } - /// - /// impl Layer for FooLayer { - /// // ... - /// } - /// - /// # impl FooLayer { - /// # fn new() -> Self { Self {} } - /// # } - /// # impl MySubscriber { - /// # fn new() -> Self { Self { }} - /// # } - /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata}; - /// # impl tracing_core::Subscriber for MySubscriber { - /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) } - /// # fn record(&self, _: &Id, _: &Record) {} - /// # fn event(&self, _: &tracing_core::Event) {} - /// # fn record_follows_from(&self, _: &Id, _: &Id) {} - /// # fn enabled(&self, _: &Metadata) -> bool { false } - /// # fn enter(&self, _: &Id) {} - /// # fn exit(&self, _: &Id) {} - /// # } - /// let subscriber = FooLayer::new() - /// .with_subscriber(MySubscriber::new()); - ///``` - /// - /// [`Subscriber`]: tracing_core::Subscriber - fn with_subscriber(mut self, mut inner: S) -> Layered - where - Self: Sized, - { - let inner_has_layer_filter = filter::subscriber_has_plf(&inner); - self.on_layer(&mut inner); - Layered::new(self, inner, inner_has_layer_filter) - } - - /// Combines `self` with a [`Filter`], returning a [`Filtered`] layer. - /// - /// The [`Filter`] will control which spans and events are enabled for - /// this layer. See [the trait-level documentation][plf] for details on - /// per-layer filtering. - /// - /// [`Filtered`]: crate::filter::Filtered - /// [plf]: crate::layer#per-layer-filtering - #[cfg(all(feature = "registry", feature = "std"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] - fn with_filter(self, filter: F) -> filter::Filtered - where - Self: Sized, - F: Filter, - { - filter::Filtered::new(self, filter) - } - - /// Erases the type of this [`Layer`], returning a [`Box`]ed `dyn - /// Layer` trait object. - /// - /// This can be used when a function returns a `Layer` which may be of - /// one of several types, or when a `Layer` subscriber has a very long type - /// signature. - /// - /// # Examples - /// - /// The following example will *not* compile, because the value assigned to - /// `log_layer` may have one of several different types: - /// - /// ```compile_fail - /// # fn main() -> Result<(), Box> { - /// use tracing_subscriber::{Layer, filter::LevelFilter, prelude::*}; - /// use std::{path::PathBuf, fs::File, io}; - /// - /// /// Configures whether logs are emitted to a file, to stdout, or to stderr. - /// pub enum LogConfig { - /// File(PathBuf), - /// Stdout, - /// Stderr, - /// } - /// - /// let config = // ... - /// # LogConfig::Stdout; - /// - /// // Depending on the config, construct a layer of one of several types. - /// let log_layer = match config { - /// // If logging to a file, use a maximally-verbose configuration. - /// LogConfig::File(path) => { - /// let file = File::create(path)?; - /// tracing_subscriber::fmt::layer() - /// .with_thread_ids(true) - /// .with_thread_names(true) - /// // Selecting the JSON logging format changes the layer's - /// // type. - /// .json() - /// .with_span_list(true) - /// // Setting the writer to use our log file changes the - /// // layer's type again. - /// .with_writer(file) - /// }, - /// - /// // If logging to stdout, use a pretty, human-readable configuration. - /// LogConfig::Stdout => tracing_subscriber::fmt::layer() - /// // Selecting the "pretty" logging format changes the - /// // layer's type! - /// .pretty() - /// .with_writer(io::stdout) - /// // Add a filter based on the RUST_LOG environment variable; - /// // this changes the type too! - /// .and_then(tracing_subscriber::EnvFilter::from_default_env()), - /// - /// // If logging to stdout, only log errors and warnings. - /// LogConfig::Stderr => tracing_subscriber::fmt::layer() - /// // Changing the writer changes the layer's type - /// .with_writer(io::stderr) - /// // Only log the `WARN` and `ERROR` levels. Adding a filter - /// // changes the layer's type to `Filtered`. - /// .with_filter(LevelFilter::WARN), - /// }; - /// - /// tracing_subscriber::registry() - /// .with(log_layer) - /// .init(); - /// # Ok(()) } - /// ``` - /// - /// However, adding a call to `.boxed()` after each match arm erases the - /// layer's type, so this code *does* compile: - /// - /// ``` - /// # fn main() -> Result<(), Box> { - /// # use tracing_subscriber::{Layer, filter::LevelFilter, prelude::*}; - /// # use std::{path::PathBuf, fs::File, io}; - /// # pub enum LogConfig { - /// # File(PathBuf), - /// # Stdout, - /// # Stderr, - /// # } - /// # let config = LogConfig::Stdout; - /// let log_layer = match config { - /// LogConfig::File(path) => { - /// let file = File::create(path)?; - /// tracing_subscriber::fmt::layer() - /// .with_thread_ids(true) - /// .with_thread_names(true) - /// .json() - /// .with_span_list(true) - /// .with_writer(file) - /// // Erase the type by boxing the layer - /// .boxed() - /// }, - /// - /// LogConfig::Stdout => tracing_subscriber::fmt::layer() - /// .pretty() - /// .with_writer(io::stdout) - /// .and_then(tracing_subscriber::EnvFilter::from_default_env()) - /// // Erase the type by boxing the layer - /// .boxed(), - /// - /// LogConfig::Stderr => tracing_subscriber::fmt::layer() - /// .with_writer(io::stderr) - /// .with_filter(LevelFilter::WARN) - /// // Erase the type by boxing the layer - /// .boxed(), - /// }; - /// - /// tracing_subscriber::registry() - /// .with(log_layer) - /// .init(); - /// # Ok(()) } - /// ``` - #[cfg(any(feature = "alloc", feature = "std"))] - #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] - fn boxed(self) -> Box + Send + Sync + 'static> - where - Self: Sized, - Self: Layer + Send + Sync + 'static, - S: Subscriber, - { - Box::new(self) - } - - #[doc(hidden)] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - if id == TypeId::of::() { - Some(self as *const _ as *const ()) - } else { - None - } - } -} - -feature! { - #![all(feature = "registry", feature = "std")] - - /// A per-[`Layer`] filter that determines whether a span or event is enabled - /// for an individual layer. - /// - /// See [the module-level documentation][plf] for details on using [`Filter`]s. - /// - /// [plf]: crate::layer#per-layer-filtering - #[cfg_attr(docsrs, doc(notable_trait))] - pub trait Filter { - /// Returns `true` if this layer is interested in a span or event with the - /// given [`Metadata`] in the current [`Context`], similarly to - /// [`Subscriber::enabled`]. - /// - /// If this returns `false`, the span or event will be disabled _for the - /// wrapped [`Layer`]_. Unlike [`Layer::enabled`], the span or event will - /// still be recorded if any _other_ layers choose to enable it. However, - /// the layer [filtered] by this filter will skip recording that span or - /// event. - /// - /// If all layers indicate that they do not wish to see this span or event, - /// it will be disabled. - /// - /// [`metadata`]: tracing_core::Metadata - /// [`Subscriber::enabled`]: tracing_core::Subscriber::enabled - /// [filtered]: crate::filter::Filtered - fn enabled(&self, meta: &Metadata<'_>, cx: &Context<'_, S>) -> bool; - - /// Returns an [`Interest`] indicating whether this layer will [always], - /// [sometimes], or [never] be interested in the given [`Metadata`]. - /// - /// When a given callsite will [always] or [never] be enabled, the results - /// of evaluating the filter may be cached for improved performance. - /// Therefore, if a filter is capable of determining that it will always or - /// never enable a particular callsite, providing an implementation of this - /// function is recommended. - /// - ///
-        /// Note: If a Filter will perform
-        /// dynamic filtering that depends on the current context in which
-        /// a span or event was observered (e.g. only enabling an event when it
-        /// occurs within a particular span), it must return
-        /// Interest::sometimes() from this method. If it returns
-        /// Interest::always() or Interest::never(), the
-        /// enabled method may not be called when a particular instance
-        /// of that span or event is recorded.
-        /// 
- /// - /// This method is broadly similar to [`Subscriber::register_callsite`]; - /// however, since the returned value represents only the interest of - /// *this* layer, the resulting behavior is somewhat different. - /// - /// If a [`Subscriber`] returns [`Interest::always()`][always] or - /// [`Interest::never()`][never] for a given [`Metadata`], its [`enabled`] - /// method is then *guaranteed* to never be called for that callsite. On the - /// other hand, when a `Filter` returns [`Interest::always()`][always] or - /// [`Interest::never()`][never] for a callsite, _other_ [`Layer`]s may have - /// differing interests in that callsite. If this is the case, the callsite - /// will recieve [`Interest::sometimes()`][sometimes], and the [`enabled`] - /// method will still be called for that callsite when it records a span or - /// event. - /// - /// Returning [`Interest::always()`][always] or [`Interest::never()`][never] from - /// `Filter::callsite_enabled` will permanently enable or disable a - /// callsite (without requiring subsequent calls to [`enabled`]) if and only - /// if the following is true: - /// - /// - all [`Layer`]s that comprise the subscriber include `Filter`s - /// (this includes a tree of [`Layered`] layers that share the same - /// `Filter`) - /// - all those `Filter`s return the same [`Interest`]. - /// - /// For example, if a [`Subscriber`] consists of two [`Filtered`] layers, - /// and both of those layers return [`Interest::never()`][never], that - /// callsite *will* never be enabled, and the [`enabled`] methods of those - /// [`Filter`]s will not be called. - /// - /// ## Default Implementation - /// - /// The default implementation of this method assumes that the - /// `Filter`'s [`enabled`] method _may_ perform dynamic filtering, and - /// returns [`Interest::sometimes()`][sometimes], to ensure that [`enabled`] - /// is called to determine whether a particular _instance_ of the callsite - /// is enabled in the current context. If this is *not* the case, and the - /// `Filter`'s [`enabled`] method will always return the same result - /// for a particular [`Metadata`], this method can be overridden as - /// follows: - /// - /// ``` - /// use tracing_subscriber::layer; - /// use tracing_core::{Metadata, subscriber::Interest}; - /// - /// struct MyFilter { - /// // ... - /// } - /// - /// impl MyFilter { - /// // The actual logic for determining whether a `Metadata` is enabled - /// // must be factored out from the `enabled` method, so that it can be - /// // called without a `Context` (which is not provided to the - /// // `callsite_enabled` method). - /// fn is_enabled(&self, metadata: &Metadata<'_>) -> bool { - /// // ... - /// # drop(metadata); true - /// } - /// } - /// - /// impl layer::Filter for MyFilter { - /// fn enabled(&self, metadata: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool { - /// // Even though we are implementing `callsite_enabled`, we must still provide a - /// // working implementation of `enabled`, as returning `Interest::always()` or - /// // `Interest::never()` will *allow* caching, but will not *guarantee* it. - /// // Other filters may still return `Interest::sometimes()`, so we may be - /// // asked again in `enabled`. - /// self.is_enabled(metadata) - /// } - /// - /// fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - /// // The result of `self.enabled(metadata, ...)` will always be - /// // the same for any given `Metadata`, so we can convert it into - /// // an `Interest`: - /// if self.is_enabled(metadata) { - /// Interest::always() - /// } else { - /// Interest::never() - /// } - /// } - /// } - /// ``` - /// - /// [`Metadata`]: tracing_core::Metadata - /// [`Interest`]: tracing_core::Interest - /// [always]: tracing_core::Interest::always - /// [sometimes]: tracing_core::Interest::sometimes - /// [never]: tracing_core::Interest::never - /// [`Subscriber::register_callsite`]: tracing_core::Subscriber::register_callsite - /// [`Subscriber`]: tracing_core::Subscriber - /// [`enabled`]: Filter::enabled - /// [`Filtered`]: crate::filter::Filtered - fn callsite_enabled(&self, meta: &'static Metadata<'static>) -> Interest { - let _ = meta; - Interest::sometimes() - } - - /// Returns an optional hint of the highest [verbosity level][level] that - /// this `Filter` will enable. - /// - /// If this method returns a [`LevelFilter`], it will be used as a hint to - /// determine the most verbose level that will be enabled. This will allow - /// spans and events which are more verbose than that level to be skipped - /// more efficiently. An implementation of this method is optional, but - /// strongly encouraged. - /// - /// If the maximum level the `Filter` will enable can change over the - /// course of its lifetime, it is free to return a different value from - /// multiple invocations of this method. However, note that changes in the - /// maximum level will **only** be reflected after the callsite [`Interest`] - /// cache is rebuilt, by calling the - /// [`tracing_core::callsite::rebuild_interest_cache`][rebuild] function. - /// Therefore, if the `Filter will change the value returned by this - /// method, it is responsible for ensuring that - /// [`rebuild_interest_cache`][rebuild] is called after the value of the max - /// level changes. - /// - /// ## Default Implementation - /// - /// By default, this method returns `None`, indicating that the maximum - /// level is unknown. - /// - /// [level]: tracing_core::metadata::Level - /// [`LevelFilter`]: crate::filter::LevelFilter - /// [`Interest`]: tracing_core::subscriber::Interest - /// [rebuild]: tracing_core::callsite::rebuild_interest_cache - fn max_level_hint(&self) -> Option { - None - } - - /// Notifies this filter that a new span was constructed with the given - /// `Attributes` and `Id`. - /// - /// By default, this method does nothing. `Filter` implementations that - /// need to be notified when new spans are created can override this - /// method. - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - let _ = (attrs, id, ctx); - } - - - /// Notifies this filter that a span with the given `Id` recorded the given - /// `values`. - /// - /// By default, this method does nothing. `Filter` implementations that - /// need to be notified when new spans are created can override this - /// method. - fn on_record(&self, id: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - let _ = (id, values, ctx); - } - - /// Notifies this filter that a span with the given ID was entered. - /// - /// By default, this method does nothing. `Filter` implementations that - /// need to be notified when a span is entered can override this method. - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - let _ = (id, ctx); - } - - /// Notifies this filter that a span with the given ID was exited. - /// - /// By default, this method does nothing. `Filter` implementations that - /// need to be notified when a span is exited can override this method. - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - let _ = (id, ctx); - } - - /// Notifies this filter that a span with the given ID has been closed. - /// - /// By default, this method does nothing. `Filter` implementations that - /// need to be notified when a span is closed can override this method. - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - let _ = (id, ctx); - } - } -} - -/// Extension trait adding a `with(Layer)` combinator to `Subscriber`s. -pub trait SubscriberExt: Subscriber + crate::sealed::Sealed { - /// Wraps `self` with the provided `layer`. - fn with(self, layer: L) -> Layered - where - L: Layer, - Self: Sized, - { - layer.with_subscriber(self) - } -} - -/// A layer that does nothing. -#[derive(Clone, Debug, Default)] -pub struct Identity { - _p: (), -} - -// === impl Layer === - -impl Layer for Option -where - L: Layer, - S: Subscriber, -{ - fn on_layer(&mut self, subscriber: &mut S) { - if let Some(ref mut layer) = self { - layer.on_layer(subscriber) - } - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_new_span(attrs, id, ctx) - } - } - - #[inline] - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - match self { - Some(ref inner) => inner.register_callsite(metadata), - None => Interest::always(), - } - } - - #[inline] - fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { - match self { - Some(ref inner) => inner.enabled(metadata, ctx), - None => true, - } - } - - #[inline] - fn max_level_hint(&self) -> Option { - match self { - Some(ref inner) => inner.max_level_hint(), - None => { - // There is no inner layer, so this layer will - // never enable anything. - Some(LevelFilter::OFF) - } - } - } - - #[inline] - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_record(span, values, ctx); - } - } - - #[inline] - fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_follows_from(span, follows, ctx); - } - } - - #[inline] - fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool { - match self { - Some(ref inner) => inner.event_enabled(event, ctx), - None => true, - } - } - - #[inline] - fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_event(event, ctx); - } - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_enter(id, ctx); - } - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_exit(id, ctx); - } - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_close(id, ctx); - } - } - - #[inline] - fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { - if let Some(ref inner) = self { - inner.on_id_change(old, new, ctx) - } - } - - #[doc(hidden)] - #[inline] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - if id == TypeId::of::() { - Some(self as *const _ as *const ()) - } else { - self.as_ref().and_then(|inner| inner.downcast_raw(id)) - } - } -} - -feature! { - #![any(feature = "std", feature = "alloc")] - #[cfg(not(feature = "std"))] - use alloc::vec::Vec; - - macro_rules! layer_impl_body { - () => { - #[inline] - fn on_layer(&mut self, subscriber: &mut S) { - self.deref_mut().on_layer(subscriber); - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - self.deref().on_new_span(attrs, id, ctx) - } - - #[inline] - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - self.deref().register_callsite(metadata) - } - - #[inline] - fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { - self.deref().enabled(metadata, ctx) - } - - #[inline] - fn max_level_hint(&self) -> Option { - self.deref().max_level_hint() - } - - #[inline] - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - self.deref().on_record(span, values, ctx) - } - - #[inline] - fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { - self.deref().on_follows_from(span, follows, ctx) - } - - #[inline] - fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool { - self.deref().event_enabled(event, ctx) - } - - #[inline] - fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { - self.deref().on_event(event, ctx) - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - self.deref().on_enter(id, ctx) - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - self.deref().on_exit(id, ctx) - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - self.deref().on_close(id, ctx) - } - - #[inline] - fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { - self.deref().on_id_change(old, new, ctx) - } - - #[doc(hidden)] - #[inline] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - self.deref().downcast_raw(id) - } - }; - } - - impl Layer for Box - where - L: Layer, - S: Subscriber, - { - layer_impl_body! {} - } - - impl Layer for Box + Send + Sync> - where - S: Subscriber, - { - layer_impl_body! {} - } - - - - impl Layer for Vec - where - L: Layer, - S: Subscriber, - { - - fn on_layer(&mut self, subscriber: &mut S) { - for l in self { - l.on_layer(subscriber); - } - } - - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - // Return highest level of interest. - let mut interest = Interest::never(); - for l in self { - let new_interest = l.register_callsite(metadata); - if (interest.is_sometimes() && new_interest.is_always()) - || (interest.is_never() && !new_interest.is_never()) - { - interest = new_interest; - } - } - - interest - } - - fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { - self.iter().all(|l| l.enabled(metadata, ctx.clone())) - } - - fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool { - self.iter().all(|l| l.event_enabled(event, ctx.clone())) - } - - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { - for l in self { - l.on_new_span(attrs, id, ctx.clone()); - } - } - - fn max_level_hint(&self) -> Option { - // Default to `OFF` if there are no inner layers. - let mut max_level = LevelFilter::OFF; - for l in self { - // NOTE(eliza): this is slightly subtle: if *any* layer - // returns `None`, we have to return `None`, assuming there is - // no max level hint, since that particular layer cannot - // provide a hint. - let hint = l.max_level_hint()?; - max_level = core::cmp::max(hint, max_level); - } - Some(max_level) - } - - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { - for l in self { - l.on_record(span, values, ctx.clone()) - } - } - - fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { - for l in self { - l.on_follows_from(span, follows, ctx.clone()); - } - } - - fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { - for l in self { - l.on_event(event, ctx.clone()); - } - } - - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - for l in self { - l.on_enter(id, ctx.clone()); - } - } - - fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { - for l in self { - l.on_exit(id, ctx.clone()); - } - } - - fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { - for l in self { - l.on_close(id.clone(), ctx.clone()); - } - } - - #[doc(hidden)] - unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { - // If downcasting to `Self`, return a pointer to `self`. - if id == TypeId::of::() { - return Some(self as *const _ as *const ()); - } - - // Someone is looking for per-layer filters. But, this `Vec` - // might contain layers with per-layer filters *and* - // layers without filters. It should only be treated as a - // per-layer-filtered layer if *all* its layers have - // per-layer filters. - // XXX(eliza): it's a bummer we have to do this linear search every - // time. It would be nice if this could be cached, but that would - // require replacing the `Vec` impl with an impl for a newtype... - if filter::is_plf_downcast_marker(id) && self.iter().any(|s| s.downcast_raw(id).is_none()) { - return None; - } - - // Otherwise, return the first child of `self` that downcaasts to - // the selected type, if any. - // XXX(eliza): hope this is reasonable lol - self.iter().find_map(|l| l.downcast_raw(id)) - } - } -} - -// === impl SubscriberExt === - -impl crate::sealed::Sealed for S {} -impl SubscriberExt for S {} - -// === impl Identity === - -impl Layer for Identity {} - -impl Identity { - /// Returns a new `Identity` layer. - pub fn new() -> Self { - Self { _p: () } - } -} diff --git a/vendor/tracing-subscriber/src/layer/tests.rs b/vendor/tracing-subscriber/src/layer/tests.rs deleted file mode 100644 index d7ad61769..000000000 --- a/vendor/tracing-subscriber/src/layer/tests.rs +++ /dev/null @@ -1,308 +0,0 @@ -use super::*; -use tracing_core::subscriber::NoSubscriber; - -#[derive(Debug)] -pub(crate) struct NopLayer; -impl Layer for NopLayer {} - -#[allow(dead_code)] -struct NopLayer2; -impl Layer for NopLayer2 {} - -/// A layer that holds a string. -/// -/// Used to test that pointers returned by downcasting are actually valid. -struct StringLayer(&'static str); -impl Layer for StringLayer {} -struct StringLayer2(&'static str); -impl Layer for StringLayer2 {} - -struct StringLayer3(&'static str); -impl Layer for StringLayer3 {} - -pub(crate) struct StringSubscriber(&'static str); - -impl Subscriber for StringSubscriber { - fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { - Interest::never() - } - - fn enabled(&self, _: &Metadata<'_>) -> bool { - false - } - - fn new_span(&self, _: &span::Attributes<'_>) -> span::Id { - span::Id::from_u64(1) - } - - fn record(&self, _: &span::Id, _: &span::Record<'_>) {} - fn record_follows_from(&self, _: &span::Id, _: &span::Id) {} - fn event(&self, _: &Event<'_>) {} - fn enter(&self, _: &span::Id) {} - fn exit(&self, _: &span::Id) {} -} - -fn assert_subscriber(_s: impl Subscriber) {} -fn assert_layer(_l: &impl Layer) {} - -#[test] -fn layer_is_subscriber() { - let s = NopLayer.with_subscriber(NoSubscriber::default()); - assert_subscriber(s) -} - -#[test] -fn two_layers_are_subscriber() { - let s = NopLayer - .and_then(NopLayer) - .with_subscriber(NoSubscriber::default()); - assert_subscriber(s) -} - -#[test] -fn three_layers_are_subscriber() { - let s = NopLayer - .and_then(NopLayer) - .and_then(NopLayer) - .with_subscriber(NoSubscriber::default()); - assert_subscriber(s) -} - -#[test] -fn three_layers_are_layer() { - let layers = NopLayer.and_then(NopLayer).and_then(NopLayer); - assert_layer(&layers); - let _ = layers.with_subscriber(NoSubscriber::default()); -} - -#[test] -#[cfg(feature = "alloc")] -fn box_layer_is_layer() { - use alloc::boxed::Box; - let l: Box + Send + Sync> = Box::new(NopLayer); - assert_layer(&l); - l.with_subscriber(NoSubscriber::default()); -} - -#[test] -fn downcasts_to_subscriber() { - let s = NopLayer - .and_then(NopLayer) - .and_then(NopLayer) - .with_subscriber(StringSubscriber("subscriber")); - let subscriber = - ::downcast_ref::(&s).expect("subscriber should downcast"); - assert_eq!(subscriber.0, "subscriber"); -} - -#[test] -fn downcasts_to_layer() { - let s = StringLayer("layer_1") - .and_then(StringLayer2("layer_2")) - .and_then(StringLayer3("layer_3")) - .with_subscriber(NoSubscriber::default()); - let layer = ::downcast_ref::(&s).expect("layer 1 should downcast"); - assert_eq!(layer.0, "layer_1"); - let layer = - ::downcast_ref::(&s).expect("layer 2 should downcast"); - assert_eq!(layer.0, "layer_2"); - let layer = - ::downcast_ref::(&s).expect("layer 3 should downcast"); - assert_eq!(layer.0, "layer_3"); -} - -#[cfg(all(feature = "registry", feature = "std"))] -mod registry_tests { - use super::*; - use crate::registry::LookupSpan; - - #[test] - fn context_event_span() { - use std::sync::{Arc, Mutex}; - let last_event_span = Arc::new(Mutex::new(None)); - - struct RecordingLayer { - last_event_span: Arc>>, - } - - impl Layer for RecordingLayer - where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - { - fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { - let span = ctx.event_span(event); - *self.last_event_span.lock().unwrap() = span.map(|s| s.name()); - } - } - - tracing::subscriber::with_default( - crate::registry().with(RecordingLayer { - last_event_span: last_event_span.clone(), - }), - || { - tracing::info!("no span"); - assert_eq!(*last_event_span.lock().unwrap(), None); - - let parent = tracing::info_span!("explicit"); - tracing::info!(parent: &parent, "explicit span"); - assert_eq!(*last_event_span.lock().unwrap(), Some("explicit")); - - let _guard = tracing::info_span!("contextual").entered(); - tracing::info!("contextual span"); - assert_eq!(*last_event_span.lock().unwrap(), Some("contextual")); - }, - ); - } - - /// Tests for how max-level hints are calculated when combining layers - /// with and without per-layer filtering. - mod max_level_hints { - - use super::*; - use crate::filter::*; - - #[test] - fn mixed_with_unfiltered() { - let subscriber = crate::registry() - .with(NopLayer) - .with(NopLayer.with_filter(LevelFilter::INFO)); - assert_eq!(subscriber.max_level_hint(), None); - } - - #[test] - fn mixed_with_unfiltered_layered() { - let subscriber = crate::registry().with(NopLayer).with( - NopLayer - .with_filter(LevelFilter::INFO) - .and_then(NopLayer.with_filter(LevelFilter::TRACE)), - ); - assert_eq!(dbg!(subscriber).max_level_hint(), None); - } - - #[test] - fn mixed_interleaved() { - let subscriber = crate::registry() - .with(NopLayer) - .with(NopLayer.with_filter(LevelFilter::INFO)) - .with(NopLayer) - .with(NopLayer.with_filter(LevelFilter::INFO)); - assert_eq!(dbg!(subscriber).max_level_hint(), None); - } - - #[test] - fn mixed_layered() { - let subscriber = crate::registry() - .with(NopLayer.with_filter(LevelFilter::INFO).and_then(NopLayer)) - .with(NopLayer.and_then(NopLayer.with_filter(LevelFilter::INFO))); - assert_eq!(dbg!(subscriber).max_level_hint(), None); - } - - #[test] - fn plf_only_unhinted() { - let subscriber = crate::registry() - .with(NopLayer.with_filter(LevelFilter::INFO)) - .with(NopLayer.with_filter(filter_fn(|_| true))); - assert_eq!(dbg!(subscriber).max_level_hint(), None); - } - - #[test] - fn plf_only_unhinted_nested_outer() { - // if a nested tree of per-layer filters has an _outer_ filter with - // no max level hint, it should return `None`. - let subscriber = crate::registry() - .with( - NopLayer - .with_filter(LevelFilter::INFO) - .and_then(NopLayer.with_filter(LevelFilter::WARN)), - ) - .with( - NopLayer - .with_filter(filter_fn(|_| true)) - .and_then(NopLayer.with_filter(LevelFilter::DEBUG)), - ); - assert_eq!(dbg!(subscriber).max_level_hint(), None); - } - - #[test] - fn plf_only_unhinted_nested_inner() { - // If a nested tree of per-layer filters has an _inner_ filter with - // no max-level hint, but the _outer_ filter has a max level hint, - // it should pick the outer hint. This is because the outer filter - // will disable the spans/events before they make it to the inner - // filter. - let subscriber = dbg!(crate::registry().with( - NopLayer - .with_filter(filter_fn(|_| true)) - .and_then(NopLayer.with_filter(filter_fn(|_| true))) - .with_filter(LevelFilter::INFO), - )); - assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::INFO)); - } - - #[test] - fn unhinted_nested_inner() { - let subscriber = dbg!(crate::registry() - .with(NopLayer.and_then(NopLayer).with_filter(LevelFilter::INFO)) - .with( - NopLayer - .with_filter(filter_fn(|_| true)) - .and_then(NopLayer.with_filter(filter_fn(|_| true))) - .with_filter(LevelFilter::WARN), - )); - assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::INFO)); - } - - #[test] - fn unhinted_nested_inner_mixed() { - let subscriber = dbg!(crate::registry() - .with( - NopLayer - .and_then(NopLayer.with_filter(filter_fn(|_| true))) - .with_filter(LevelFilter::INFO) - ) - .with( - NopLayer - .with_filter(filter_fn(|_| true)) - .and_then(NopLayer.with_filter(filter_fn(|_| true))) - .with_filter(LevelFilter::WARN), - )); - assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::INFO)); - } - - #[test] - fn plf_only_picks_max() { - let subscriber = crate::registry() - .with(NopLayer.with_filter(LevelFilter::WARN)) - .with(NopLayer.with_filter(LevelFilter::DEBUG)); - assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::DEBUG)); - } - - #[test] - fn many_plf_only_picks_max() { - let subscriber = crate::registry() - .with(NopLayer.with_filter(LevelFilter::WARN)) - .with(NopLayer.with_filter(LevelFilter::DEBUG)) - .with(NopLayer.with_filter(LevelFilter::INFO)) - .with(NopLayer.with_filter(LevelFilter::ERROR)); - assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::DEBUG)); - } - - #[test] - fn nested_plf_only_picks_max() { - let subscriber = crate::registry() - .with( - NopLayer.with_filter(LevelFilter::INFO).and_then( - NopLayer - .with_filter(LevelFilter::WARN) - .and_then(NopLayer.with_filter(LevelFilter::DEBUG)), - ), - ) - .with( - NopLayer - .with_filter(LevelFilter::INFO) - .and_then(NopLayer.with_filter(LevelFilter::ERROR)), - ); - assert_eq!(dbg!(subscriber).max_level_hint(), Some(LevelFilter::DEBUG)); - } - } -} diff --git a/vendor/tracing-subscriber/src/lib.rs b/vendor/tracing-subscriber/src/lib.rs deleted file mode 100644 index 9de70a90d..000000000 --- a/vendor/tracing-subscriber/src/lib.rs +++ /dev/null @@ -1,252 +0,0 @@ -//! Utilities for implementing and composing [`tracing`] subscribers. -//! -//! [`tracing`] is a framework for instrumenting Rust programs to collect -//! scoped, structured, and async-aware diagnostics. The [`Subscriber`] trait -//! represents the functionality necessary to collect this trace data. This -//! crate contains tools for composing subscribers out of smaller units of -//! behaviour, and batteries-included implementations of common subscriber -//! functionality. -//! -//! `tracing-subscriber` is intended for use by both `Subscriber` authors and -//! application authors using `tracing` to instrument their applications. -//! -//! *Compiler support: [requires `rustc` 1.49+][msrv]* -//! -//! [msrv]: #supported-rust-versions -//! -//! ## `Layer`s and `Filter`s -//! -//! The most important component of the `tracing-subscriber` API is the -//! [`Layer`] trait, which provides a composable abstraction for building -//! [`Subscriber`]s. Like the [`Subscriber`] trait, a [`Layer`] defines a -//! particular behavior for collecting trace data. Unlike [`Subscriber`]s, -//! which implement a *complete* strategy for how trace data is collected, -//! [`Layer`]s provide *modular* implementations of specific behaviors. -//! Therefore, they can be [composed together] to form a [`Subscriber`] which is -//! capable of recording traces in a variety of ways. See the [`layer` module's -//! documentation][layer] for details on using [`Layer`]s. -//! -//! In addition, the [`Filter`] trait defines an interface for filtering what -//! spans and events are recorded by a particular layer. This allows different -//! [`Layer`]s to handle separate subsets of the trace data emitted by a -//! program. See the [documentation on per-layer filtering][plf] for more -//! information on using [`Filter`]s. -//! -//! [`Layer`]: crate::layer::Layer -//! [composed together]: crate::layer#composing-layers -//! [layer]: crate::layer -//! [`Filter`]: crate::layer::Filter -//! [plf]: crate::layer#per-layer-filtering -//! -//! ## Included Subscribers -//! -//! The following `Subscriber`s are provided for application authors: -//! -//! - [`fmt`] - Formats and logs tracing data (requires the `fmt` feature flag) -//! -//! ## Feature Flags -//! -//! - `std`: Enables APIs that depend on the on the Rust standard library -//! (enabled by default). -//! - `alloc`: Depend on [`liballoc`] (enabled by "std"). -//! - `env-filter`: Enables the [`EnvFilter`] type, which implements filtering -//! similar to the [`env_logger` crate]. **Requires "std"**. -//! - `fmt`: Enables the [`fmt`] module, which provides a subscriber -//! implementation for printing formatted representations of trace events. -//! Enabled by default. **Requires "std"**. -//! - `ansi`: Enables `fmt` support for ANSI terminal colors. Enabled by -//! default. -//! - `registry`: enables the [`registry`] module. Enabled by default. -//! **Requires "std"**. -//! - `json`: Enables `fmt` support for JSON output. In JSON output, the ANSI -//! feature does nothing. **Requires "fmt" and "std"**. -//! - `local-time`: Enables local time formatting when using the [`time` -//! crate]'s timestamp formatters with the `fmt` subscriber. -//! -//! [`registry`]: mod@registry -//! -//! ### Optional Dependencies -//! -//! - [`tracing-log`]: Enables better formatting for events emitted by `log` -//! macros in the `fmt` subscriber. Enabled by default. -//! - [`time`][`time` crate]: Enables support for using the [`time` crate] for timestamp -//! formatting in the `fmt` subscriber. -//! - [`smallvec`]: Causes the `EnvFilter` type to use the `smallvec` crate (rather -//! than `Vec`) as a performance optimization. Enabled by default. -//! - [`parking_lot`]: Use the `parking_lot` crate's `RwLock` implementation -//! rather than the Rust standard library's implementation. -//! -//! ### `no_std` Support -//! -//! In embedded systems and other bare-metal applications, `tracing` can be -//! used without requiring the Rust standard library, although some features are -//! disabled. Although most of the APIs provided by `tracing-subscriber`, such -//! as [`fmt`] and [`EnvFilter`], require the standard library, some -//! functionality, such as the [`Layer`] trait, can still be used in -//! `no_std` environments. -//! -//! The dependency on the standard library is controlled by two crate feature -//! flags, "std", which enables the dependency on [`libstd`], and "alloc", which -//! enables the dependency on [`liballoc`] (and is enabled by the "std" -//! feature). These features are enabled by default, but `no_std` users can -//! disable them using: -//! -//! ```toml -//! # Cargo.toml -//! tracing-subscriber = { version = "0.3", default-features = false } -//! ``` -//! -//! Additional APIs are available when [`liballoc`] is available. To enable -//! `liballoc` but not `std`, use: -//! -//! ```toml -//! # Cargo.toml -//! tracing-subscriber = { version = "0.3", default-features = false, features = ["alloc"] } -//! ``` -//! -//! ### Unstable Features -//! -//! These feature flags enable **unstable** features. The public API may break in 0.1.x -//! releases. To enable these features, the `--cfg tracing_unstable` must be passed to -//! `rustc` when compiling. -//! -//! The following unstable feature flags are currently available: -//! -//! * `valuable`: Enables support for serializing values recorded using the -//! [`valuable`] crate as structured JSON in the [`format::Json`] formatter. -//! -//! #### Enabling Unstable Features -//! -//! The easiest way to set the `tracing_unstable` cfg is to use the `RUSTFLAGS` -//! env variable when running `cargo` commands: -//! -//! ```shell -//! RUSTFLAGS="--cfg tracing_unstable" cargo build -//! ``` -//! Alternatively, the following can be added to the `.cargo/config` file in a -//! project to automatically enable the cfg flag for that project: -//! -//! ```toml -//! [build] -//! rustflags = ["--cfg", "tracing_unstable"] -//! ``` -//! -//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section -//! [`valuable`]: https://crates.io/crates/valuable -//! [`format::Json`]: crate::fmt::format::Json -//! -//! ## Supported Rust Versions -//! -//! Tracing is built against the latest stable release. The minimum supported -//! version is 1.49. The current Tracing version is not guaranteed to build on -//! Rust versions earlier than the minimum supported version. -//! -//! Tracing follows the same compiler support policies as the rest of the Tokio -//! project. The current stable Rust compiler and the three most recent minor -//! versions before it will always be supported. For example, if the current -//! stable compiler version is 1.45, the minimum supported version will not be -//! increased past 1.42, three minor versions prior. Increasing the minimum -//! supported compiler version is not considered a semver breaking change as -//! long as doing so complies with this policy. -//! -//! [`Subscriber`]: tracing_core::subscriber::Subscriber -//! [`tracing`]: https://docs.rs/tracing/latest/tracing -//! [`EnvFilter`]: filter::EnvFilter -//! [`fmt`]: mod@fmt -//! [`tracing-log`]: https://crates.io/crates/tracing-log -//! [`smallvec`]: https://crates.io/crates/smallvec -//! [`env_logger` crate]: https://crates.io/crates/env_logger -//! [`parking_lot`]: https://crates.io/crates/parking_lot -//! [`time` crate]: https://crates.io/crates/time -//! [`libstd`]: std -//! [`liballoc`]: alloc -#![doc(html_root_url = "https://docs.rs/tracing-subscriber/0.3.15")] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png", - issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/" -)] -#![cfg_attr( - docsrs, - // Allows displaying cfgs/feature flags in the documentation. - feature(doc_cfg), - // Allows adding traits to RustDoc's list of "notable traits" - feature(doc_notable_trait), - // Fail the docs build if any intra-docs links are broken - deny(rustdoc::broken_intra_doc_links), -)] -#![warn( - missing_debug_implementations, - missing_docs, - rust_2018_idioms, - unreachable_pub, - bad_style, - const_err, - dead_code, - improper_ctypes, - non_shorthand_field_patterns, - no_mangle_generic_items, - overflowing_literals, - path_statements, - patterns_in_fns_without_body, - private_in_public, - unconditional_recursion, - unused, - unused_allocation, - unused_comparisons, - unused_parens, - while_true -)] -// Using struct update syntax when a struct has no additional fields avoids -// a potential source change if additional fields are added to the struct in the -// future, reducing diff noise. Allow this even though clippy considers it -// "needless". -#![allow(clippy::needless_update)] -#![cfg_attr(not(feature = "std"), no_std)] - -#[cfg(feature = "alloc")] -extern crate alloc; - -#[macro_use] -mod macros; - -pub mod field; -pub mod filter; -pub mod prelude; -pub mod registry; - -pub mod layer; -pub mod util; - -feature! { - #![feature = "std"] - pub mod reload; - pub(crate) mod sync; -} - -feature! { - #![all(feature = "fmt", feature = "std")] - pub mod fmt; - pub use fmt::fmt; - pub use fmt::Subscriber as FmtSubscriber; -} - -feature! { - #![all(feature = "env-filter", feature = "std")] - pub use filter::EnvFilter; -} - -pub use layer::Layer; - -feature! { - #![all(feature = "registry", feature = "std")] - pub use registry::Registry; - - /// - pub fn registry() -> Registry { - Registry::default() - } -} - -mod sealed { - pub trait Sealed {} -} diff --git a/vendor/tracing-subscriber/src/macros.rs b/vendor/tracing-subscriber/src/macros.rs deleted file mode 100644 index 81351132f..000000000 --- a/vendor/tracing-subscriber/src/macros.rs +++ /dev/null @@ -1,28 +0,0 @@ -#[cfg(feature = "std")] -macro_rules! try_lock { - ($lock:expr) => { - try_lock!($lock, else return) - }; - ($lock:expr, else $els:expr) => { - if let Ok(l) = $lock { - l - } else if std::thread::panicking() { - $els - } else { - panic!("lock poisoned") - } - }; -} - -macro_rules! feature { - ( - #![$meta:meta] - $($item:item)* - ) => { - $( - #[cfg($meta)] - #[cfg_attr(docsrs, doc(cfg($meta)))] - $item - )* - } -} diff --git a/vendor/tracing-subscriber/src/prelude.rs b/vendor/tracing-subscriber/src/prelude.rs deleted file mode 100644 index c2230907b..000000000 --- a/vendor/tracing-subscriber/src/prelude.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! The `tracing-subscriber` prelude. -//! -//! This brings into scope a number of extension traits that define methods on -//! types defined here and in other crates. - -pub use crate::field::{ - MakeExt as __tracing_subscriber_field_MakeExt, - RecordFields as __tracing_subscriber_field_RecordFields, -}; -pub use crate::layer::{ - Layer as __tracing_subscriber_Layer, SubscriberExt as __tracing_subscriber_SubscriberExt, -}; - -pub use crate::util::SubscriberInitExt as _; - -feature! { - #![all(feature = "fmt", feature = "std")] - pub use crate::fmt::writer::MakeWriterExt as _; -} diff --git a/vendor/tracing-subscriber/src/registry/extensions.rs b/vendor/tracing-subscriber/src/registry/extensions.rs deleted file mode 100644 index ff76fb599..000000000 --- a/vendor/tracing-subscriber/src/registry/extensions.rs +++ /dev/null @@ -1,274 +0,0 @@ -// taken from https://github.com/hyperium/http/blob/master/src/extensions.rs. - -use crate::sync::{RwLockReadGuard, RwLockWriteGuard}; -use std::{ - any::{Any, TypeId}, - collections::HashMap, - fmt, - hash::{BuildHasherDefault, Hasher}, -}; - -#[allow(warnings)] -type AnyMap = HashMap, BuildHasherDefault>; - -/// With TypeIds as keys, there's no need to hash them. They are already hashes -/// themselves, coming from the compiler. The IdHasher holds the u64 of -/// the TypeId, and then returns it, instead of doing any bit fiddling. -#[derive(Default, Debug)] -struct IdHasher(u64); - -impl Hasher for IdHasher { - fn write(&mut self, _: &[u8]) { - unreachable!("TypeId calls write_u64"); - } - - #[inline] - fn write_u64(&mut self, id: u64) { - self.0 = id; - } - - #[inline] - fn finish(&self) -> u64 { - self.0 - } -} - -/// An immutable, read-only reference to a Span's extensions. -#[derive(Debug)] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub struct Extensions<'a> { - inner: RwLockReadGuard<'a, ExtensionsInner>, -} - -impl<'a> Extensions<'a> { - #[cfg(feature = "registry")] - pub(crate) fn new(inner: RwLockReadGuard<'a, ExtensionsInner>) -> Self { - Self { inner } - } - - /// Immutably borrows a type previously inserted into this `Extensions`. - pub fn get(&self) -> Option<&T> { - self.inner.get::() - } -} - -/// An mutable reference to a Span's extensions. -#[derive(Debug)] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub struct ExtensionsMut<'a> { - inner: RwLockWriteGuard<'a, ExtensionsInner>, -} - -impl<'a> ExtensionsMut<'a> { - #[cfg(feature = "registry")] - pub(crate) fn new(inner: RwLockWriteGuard<'a, ExtensionsInner>) -> Self { - Self { inner } - } - - /// Insert a type into this `Extensions`. - /// - /// Note that extensions are _not_ - /// `Layer`-specific—they are _span_-specific. This means that - /// other layers can access and mutate extensions that - /// a different Layer recorded. For example, an application might - /// have a layer that records execution timings, alongside a layer - /// that reports spans and events to a distributed - /// tracing system that requires timestamps for spans. - /// Ideally, if one layer records a timestamp _x_, the other layer - /// should be able to reuse timestamp _x_. - /// - /// Therefore, extensions should generally be newtypes, rather than common - /// types like [`String`](std::string::String), to avoid accidental - /// cross-`Layer` clobbering. - /// - /// ## Panics - /// - /// If `T` is already present in `Extensions`, then this method will panic. - pub fn insert(&mut self, val: T) { - assert!(self.replace(val).is_none()) - } - - /// Replaces an existing `T` into this extensions. - /// - /// If `T` is not present, `Option::None` will be returned. - pub fn replace(&mut self, val: T) -> Option { - self.inner.insert(val) - } - - /// Get a mutable reference to a type previously inserted on this `ExtensionsMut`. - pub fn get_mut(&mut self) -> Option<&mut T> { - self.inner.get_mut::() - } - - /// Remove a type from this `Extensions`. - /// - /// If a extension of this type existed, it will be returned. - pub fn remove(&mut self) -> Option { - self.inner.remove::() - } -} - -/// A type map of span extensions. -/// -/// [ExtensionsInner] is used by `SpanData` to store and -/// span-specific data. A given `Layer` can read and write -/// data that it is interested in recording and emitting. -#[derive(Default)] -pub(crate) struct ExtensionsInner { - map: AnyMap, -} - -impl ExtensionsInner { - /// Create an empty `Extensions`. - #[cfg(any(test, feature = "registry"))] - #[inline] - #[cfg(any(test, feature = "registry"))] - pub(crate) fn new() -> ExtensionsInner { - ExtensionsInner { - map: AnyMap::default(), - } - } - - /// Insert a type into this `Extensions`. - /// - /// If a extension of this type already existed, it will - /// be returned. - pub(crate) fn insert(&mut self, val: T) -> Option { - self.map - .insert(TypeId::of::(), Box::new(val)) - .and_then(|boxed| { - #[allow(warnings)] - { - (boxed as Box) - .downcast() - .ok() - .map(|boxed| *boxed) - } - }) - } - - /// Get a reference to a type previously inserted on this `Extensions`. - pub(crate) fn get(&self) -> Option<&T> { - self.map - .get(&TypeId::of::()) - .and_then(|boxed| (&**boxed as &(dyn Any + 'static)).downcast_ref()) - } - - /// Get a mutable reference to a type previously inserted on this `Extensions`. - pub(crate) fn get_mut(&mut self) -> Option<&mut T> { - self.map - .get_mut(&TypeId::of::()) - .and_then(|boxed| (&mut **boxed as &mut (dyn Any + 'static)).downcast_mut()) - } - - /// Remove a type from this `Extensions`. - /// - /// If a extension of this type existed, it will be returned. - pub(crate) fn remove(&mut self) -> Option { - self.map.remove(&TypeId::of::()).and_then(|boxed| { - #[allow(warnings)] - { - (boxed as Box) - .downcast() - .ok() - .map(|boxed| *boxed) - } - }) - } - - /// Clear the `ExtensionsInner` in-place, dropping any elements in the map but - /// retaining allocated capacity. - /// - /// This permits the hash map allocation to be pooled by the registry so - /// that future spans will not need to allocate new hashmaps. - #[cfg(any(test, feature = "registry"))] - pub(crate) fn clear(&mut self) { - self.map.clear(); - } -} - -impl fmt::Debug for ExtensionsInner { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Extensions") - .field("len", &self.map.len()) - .field("capacity", &self.map.capacity()) - .finish() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[derive(Debug, PartialEq)] - struct MyType(i32); - - #[test] - fn test_extensions() { - let mut extensions = ExtensionsInner::new(); - - extensions.insert(5i32); - extensions.insert(MyType(10)); - - assert_eq!(extensions.get(), Some(&5i32)); - assert_eq!(extensions.get_mut(), Some(&mut 5i32)); - - assert_eq!(extensions.remove::(), Some(5i32)); - assert!(extensions.get::().is_none()); - - assert_eq!(extensions.get::(), None); - assert_eq!(extensions.get(), Some(&MyType(10))); - } - - #[test] - fn clear_retains_capacity() { - let mut extensions = ExtensionsInner::new(); - extensions.insert(5i32); - extensions.insert(MyType(10)); - extensions.insert(true); - - assert_eq!(extensions.map.len(), 3); - let prev_capacity = extensions.map.capacity(); - extensions.clear(); - - assert_eq!( - extensions.map.len(), - 0, - "after clear(), extensions map should have length 0" - ); - assert_eq!( - extensions.map.capacity(), - prev_capacity, - "after clear(), extensions map should retain prior capacity" - ); - } - - #[test] - fn clear_drops_elements() { - use std::sync::Arc; - struct DropMePlease(Arc<()>); - struct DropMeTooPlease(Arc<()>); - - let mut extensions = ExtensionsInner::new(); - let val1 = DropMePlease(Arc::new(())); - let val2 = DropMeTooPlease(Arc::new(())); - - let val1_dropped = Arc::downgrade(&val1.0); - let val2_dropped = Arc::downgrade(&val2.0); - extensions.insert(val1); - extensions.insert(val2); - - assert!(val1_dropped.upgrade().is_some()); - assert!(val2_dropped.upgrade().is_some()); - - extensions.clear(); - assert!( - val1_dropped.upgrade().is_none(), - "after clear(), val1 should be dropped" - ); - assert!( - val2_dropped.upgrade().is_none(), - "after clear(), val2 should be dropped" - ); - } -} diff --git a/vendor/tracing-subscriber/src/registry/mod.rs b/vendor/tracing-subscriber/src/registry/mod.rs deleted file mode 100644 index 38af53e8a..000000000 --- a/vendor/tracing-subscriber/src/registry/mod.rs +++ /dev/null @@ -1,600 +0,0 @@ -//! Storage for span data shared by multiple [`Layer`]s. -//! -//! ## Using the Span Registry -//! -//! This module provides the [`Registry`] type, a [`Subscriber`] implementation -//! which tracks per-span data and exposes it to [`Layer`]s. When a `Registry` -//! is used as the base `Subscriber` of a `Layer` stack, the -//! [`layer::Context`][ctx] type will provide methods allowing `Layer`s to -//! [look up span data][lookup] stored in the registry. While [`Registry`] is a -//! reasonable default for storing spans and events, other stores that implement -//! [`LookupSpan`] and [`Subscriber`] themselves (with [`SpanData`] implemented -//! by the per-span data they store) can be used as a drop-in replacement. -//! -//! For example, we might create a `Registry` and add multiple `Layer`s like so: -//! ```rust -//! use tracing_subscriber::{registry::Registry, Layer, prelude::*}; -//! # use tracing_core::Subscriber; -//! # pub struct FooLayer {} -//! # pub struct BarLayer {} -//! # impl Layer for FooLayer {} -//! # impl Layer for BarLayer {} -//! # impl FooLayer { -//! # fn new() -> Self { Self {} } -//! # } -//! # impl BarLayer { -//! # fn new() -> Self { Self {} } -//! # } -//! -//! let subscriber = Registry::default() -//! .with(FooLayer::new()) -//! .with(BarLayer::new()); -//! ``` -//! -//! If a type implementing `Layer` depends on the functionality of a `Registry` -//! implementation, it should bound its `Subscriber` type parameter with the -//! [`LookupSpan`] trait, like so: -//! -//! ```rust -//! use tracing_subscriber::{registry, Layer}; -//! use tracing_core::Subscriber; -//! -//! pub struct MyLayer { -//! // ... -//! } -//! -//! impl Layer for MyLayer -//! where -//! S: Subscriber + for<'a> registry::LookupSpan<'a>, -//! { -//! // ... -//! } -//! ``` -//! When this bound is added, the `Layer` implementation will be guaranteed -//! access to the [`Context`][ctx] methods, such as [`Context::span`][lookup], that -//! require the root subscriber to be a registry. -//! -//! [`Layer`]: crate::layer::Layer -//! [`Subscriber`]: tracing_core::Subscriber -//! [ctx]: crate::layer::Context -//! [lookup]: crate::layer::Context::span() -use tracing_core::{field::FieldSet, span::Id, Metadata}; - -feature! { - #![feature = "std"] - /// A module containing a type map of span extensions. - mod extensions; - pub use extensions::{Extensions, ExtensionsMut}; - -} - -feature! { - #![all(feature = "registry", feature = "std")] - - mod sharded; - mod stack; - - pub use sharded::Data; - pub use sharded::Registry; - - use crate::filter::FilterId; -} - -/// Provides access to stored span data. -/// -/// Subscribers which store span data and associate it with span IDs should -/// implement this trait; if they do, any [`Layer`]s wrapping them can look up -/// metadata via the [`Context`] type's [`span()`] method. -/// -/// [`Layer`]: super::layer::Layer -/// [`Context`]: super::layer::Context -/// [`span()`]: super::layer::Context::span -pub trait LookupSpan<'a> { - /// The type of span data stored in this registry. - type Data: SpanData<'a>; - - /// Returns the [`SpanData`] for a given `Id`, if it exists. - /// - ///
-    /// Note: users of the LookupSpan trait should
-    /// typically call the span method rather
-    /// than this method. The span method is implemented by
-    /// calling span_data, but returns a reference which is
-    /// capable of performing more sophisiticated queries.
-    /// 
- /// - fn span_data(&'a self, id: &Id) -> Option; - - /// Returns a [`SpanRef`] for the span with the given `Id`, if it exists. - /// - /// A `SpanRef` is similar to [`SpanData`], but it allows performing - /// additional lookups against the registryr that stores the wrapped data. - /// - /// In general, _users_ of the `LookupSpan` trait should use this method - /// rather than the [`span_data`] method; while _implementors_ of this trait - /// should only implement `span_data`. - /// - /// [`span_data`]: LookupSpan::span_data() - fn span(&'a self, id: &Id) -> Option> - where - Self: Sized, - { - let data = self.span_data(id)?; - Some(SpanRef { - registry: self, - data, - #[cfg(feature = "registry")] - filter: FilterId::none(), - }) - } - - /// Registers a [`Filter`] for [per-layer filtering] with this - /// [`Subscriber`]. - /// - /// The [`Filter`] can then use the returned [`FilterId`] to - /// [check if it previously enabled a span][check]. - /// - /// # Panics - /// - /// If this `Subscriber` does not support [per-layer filtering]. - /// - /// [`Filter`]: crate::layer::Filter - /// [per-layer filtering]: crate::layer::Layer#per-layer-filtering - /// [`Subscriber`]: tracing_core::Subscriber - /// [`FilterId`]: crate::filter::FilterId - /// [check]: SpanData::is_enabled_for - #[cfg(feature = "registry")] - #[cfg_attr(docsrs, doc(cfg(feature = "registry")))] - fn register_filter(&mut self) -> FilterId { - panic!( - "{} does not currently support filters", - std::any::type_name::() - ) - } -} - -/// A stored representation of data associated with a span. -pub trait SpanData<'a> { - /// Returns this span's ID. - fn id(&self) -> Id; - - /// Returns a reference to the span's `Metadata`. - fn metadata(&self) -> &'static Metadata<'static>; - - /// Returns a reference to the ID - fn parent(&self) -> Option<&Id>; - - /// Returns a reference to this span's `Extensions`. - /// - /// The extensions may be used by `Layer`s to store additional data - /// describing the span. - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - fn extensions(&self) -> Extensions<'_>; - - /// Returns a mutable reference to this span's `Extensions`. - /// - /// The extensions may be used by `Layer`s to store additional data - /// describing the span. - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - fn extensions_mut(&self) -> ExtensionsMut<'_>; - - /// Returns `true` if this span is enabled for the [per-layer filter][plf] - /// corresponding to the provided [`FilterId`]. - /// - /// ## Default Implementation - /// - /// By default, this method assumes that the [`LookupSpan`] implementation - /// does not support [per-layer filtering][plf], and always returns `true`. - /// - /// [plf]: crate::layer::Layer#per-layer-filtering - /// [`FilterId`]: crate::filter::FilterId - #[cfg(feature = "registry")] - #[cfg_attr(docsrs, doc(cfg(feature = "registry")))] - fn is_enabled_for(&self, filter: FilterId) -> bool { - let _ = filter; - true - } -} - -/// A reference to [span data] and the associated [registry]. -/// -/// This type implements all the same methods as [`SpanData`][span data], and -/// provides additional methods for querying the registry based on values from -/// the span. -/// -/// [span data]: SpanData -/// [registry]: LookupSpan -#[derive(Debug)] -pub struct SpanRef<'a, R: LookupSpan<'a>> { - registry: &'a R, - data: R::Data, - - #[cfg(feature = "registry")] - filter: FilterId, -} - -/// An iterator over the parents of a span, ordered from leaf to root. -/// -/// This is returned by the [`SpanRef::scope`] method. -#[derive(Debug)] -pub struct Scope<'a, R> { - registry: &'a R, - next: Option, - - #[cfg(all(feature = "registry", feature = "std"))] - filter: FilterId, -} - -feature! { - #![any(feature = "alloc", feature = "std")] - - #[cfg(not(feature = "smallvec"))] - use alloc::vec::{self, Vec}; - - use core::{fmt,iter}; - - /// An iterator over the parents of a span, ordered from root to leaf. - /// - /// This is returned by the [`Scope::from_root`] method. - pub struct ScopeFromRoot<'a, R> - where - R: LookupSpan<'a>, - { - #[cfg(feature = "smallvec")] - spans: iter::Rev>>, - #[cfg(not(feature = "smallvec"))] - spans: iter::Rev>>, - } - - #[cfg(feature = "smallvec")] - type SpanRefVecArray<'span, L> = [SpanRef<'span, L>; 16]; - - impl<'a, R> Scope<'a, R> - where - R: LookupSpan<'a>, - { - /// Flips the order of the iterator, so that it is ordered from root to leaf. - /// - /// The iterator will first return the root span, then that span's immediate child, - /// and so on until it finally returns the span that [`SpanRef::scope`] was called on. - /// - /// If any items were consumed from the [`Scope`] before calling this method then they - /// will *not* be returned from the [`ScopeFromRoot`]. - /// - /// **Note**: this will allocate if there are many spans remaining, or if the - /// "smallvec" feature flag is not enabled. - #[allow(clippy::wrong_self_convention)] - pub fn from_root(self) -> ScopeFromRoot<'a, R> { - #[cfg(feature = "smallvec")] - type Buf = smallvec::SmallVec; - #[cfg(not(feature = "smallvec"))] - type Buf = Vec; - ScopeFromRoot { - spans: self.collect::>().into_iter().rev(), - } - } - } - - impl<'a, R> Iterator for ScopeFromRoot<'a, R> - where - R: LookupSpan<'a>, - { - type Item = SpanRef<'a, R>; - - #[inline] - fn next(&mut self) -> Option { - self.spans.next() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.spans.size_hint() - } - } - - impl<'a, R> fmt::Debug for ScopeFromRoot<'a, R> - where - R: LookupSpan<'a>, - { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad("ScopeFromRoot { .. }") - } - } -} - -impl<'a, R> Iterator for Scope<'a, R> -where - R: LookupSpan<'a>, -{ - type Item = SpanRef<'a, R>; - - fn next(&mut self) -> Option { - loop { - let curr = self.registry.span(self.next.as_ref()?)?; - - #[cfg(all(feature = "registry", feature = "std"))] - let curr = curr.with_filter(self.filter); - self.next = curr.data.parent().cloned(); - - // If the `Scope` is filtered, check if the current span is enabled - // by the selected filter ID. - - #[cfg(all(feature = "registry", feature = "std"))] - { - if !curr.is_enabled_for(self.filter) { - // The current span in the chain is disabled for this - // filter. Try its parent. - continue; - } - } - - return Some(curr); - } - } -} - -impl<'a, R> SpanRef<'a, R> -where - R: LookupSpan<'a>, -{ - /// Returns this span's ID. - pub fn id(&self) -> Id { - self.data.id() - } - - /// Returns a static reference to the span's metadata. - pub fn metadata(&self) -> &'static Metadata<'static> { - self.data.metadata() - } - - /// Returns the span's name, - pub fn name(&self) -> &'static str { - self.data.metadata().name() - } - - /// Returns a list of [fields] defined by the span. - /// - /// [fields]: tracing_core::field - pub fn fields(&self) -> &FieldSet { - self.data.metadata().fields() - } - - /// Returns a `SpanRef` describing this span's parent, or `None` if this - /// span is the root of its trace tree. - pub fn parent(&self) -> Option { - let id = self.data.parent()?; - let data = self.registry.span_data(id)?; - - #[cfg(all(feature = "registry", feature = "std"))] - { - // move these into mut bindings if the registry feature is enabled, - // since they may be mutated in the loop. - let mut data = data; - loop { - // Is this parent enabled by our filter? - if data.is_enabled_for(self.filter) { - return Some(Self { - registry: self.registry, - filter: self.filter, - data, - }); - } - - // It's not enabled. If the disabled span has a parent, try that! - let id = data.parent()?; - data = self.registry.span_data(id)?; - } - } - - #[cfg(not(all(feature = "registry", feature = "std")))] - Some(Self { - registry: self.registry, - data, - }) - } - - /// Returns an iterator over all parents of this span, starting with this span, - /// ordered from leaf to root. - /// - /// The iterator will first return the span, then the span's immediate parent, - /// followed by that span's parent, and so on, until it reaches a root span. - /// - /// ```rust - /// use tracing::{span, Subscriber}; - /// use tracing_subscriber::{ - /// layer::{Context, Layer}, - /// prelude::*, - /// registry::LookupSpan, - /// }; - /// - /// struct PrintingLayer; - /// impl Layer for PrintingLayer - /// where - /// S: Subscriber + for<'lookup> LookupSpan<'lookup>, - /// { - /// fn on_enter(&self, id: &span::Id, ctx: Context) { - /// let span = ctx.span(id).unwrap(); - /// let scope = span.scope().map(|span| span.name()).collect::>(); - /// println!("Entering span: {:?}", scope); - /// } - /// } - /// - /// tracing::subscriber::with_default(tracing_subscriber::registry().with(PrintingLayer), || { - /// let _root = tracing::info_span!("root").entered(); - /// // Prints: Entering span: ["root"] - /// let _child = tracing::info_span!("child").entered(); - /// // Prints: Entering span: ["child", "root"] - /// let _leaf = tracing::info_span!("leaf").entered(); - /// // Prints: Entering span: ["leaf", "child", "root"] - /// }); - /// ``` - /// - /// If the opposite order (from the root to this span) is desired, calling [`Scope::from_root`] on - /// the returned iterator reverses the order. - /// - /// ```rust - /// # use tracing::{span, Subscriber}; - /// # use tracing_subscriber::{ - /// # layer::{Context, Layer}, - /// # prelude::*, - /// # registry::LookupSpan, - /// # }; - /// # struct PrintingLayer; - /// impl Layer for PrintingLayer - /// where - /// S: Subscriber + for<'lookup> LookupSpan<'lookup>, - /// { - /// fn on_enter(&self, id: &span::Id, ctx: Context) { - /// let span = ctx.span(id).unwrap(); - /// let scope = span.scope().from_root().map(|span| span.name()).collect::>(); - /// println!("Entering span: {:?}", scope); - /// } - /// } - /// - /// tracing::subscriber::with_default(tracing_subscriber::registry().with(PrintingLayer), || { - /// let _root = tracing::info_span!("root").entered(); - /// // Prints: Entering span: ["root"] - /// let _child = tracing::info_span!("child").entered(); - /// // Prints: Entering span: ["root", "child"] - /// let _leaf = tracing::info_span!("leaf").entered(); - /// // Prints: Entering span: ["root", "child", "leaf"] - /// }); - /// ``` - pub fn scope(&self) -> Scope<'a, R> { - Scope { - registry: self.registry, - next: Some(self.id()), - - #[cfg(feature = "registry")] - filter: self.filter, - } - } - - /// Returns a reference to this span's `Extensions`. - /// - /// The extensions may be used by `Layer`s to store additional data - /// describing the span. - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - pub fn extensions(&self) -> Extensions<'_> { - self.data.extensions() - } - - /// Returns a mutable reference to this span's `Extensions`. - /// - /// The extensions may be used by `Layer`s to store additional data - /// describing the span. - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - pub fn extensions_mut(&self) -> ExtensionsMut<'_> { - self.data.extensions_mut() - } - - #[cfg(all(feature = "registry", feature = "std"))] - pub(crate) fn try_with_filter(self, filter: FilterId) -> Option { - if self.is_enabled_for(filter) { - return Some(self.with_filter(filter)); - } - - None - } - - #[inline] - #[cfg(all(feature = "registry", feature = "std"))] - pub(crate) fn is_enabled_for(&self, filter: FilterId) -> bool { - self.data.is_enabled_for(filter) - } - - #[inline] - #[cfg(all(feature = "registry", feature = "std"))] - fn with_filter(self, filter: FilterId) -> Self { - Self { filter, ..self } - } -} - -#[cfg(all(test, feature = "registry", feature = "std"))] -mod tests { - use crate::{ - layer::{Context, Layer}, - prelude::*, - registry::LookupSpan, - }; - use std::sync::{Arc, Mutex}; - use tracing::{span, Subscriber}; - - #[test] - fn spanref_scope_iteration_order() { - let last_entered_scope = Arc::new(Mutex::new(Vec::new())); - - #[derive(Default)] - struct PrintingLayer { - last_entered_scope: Arc>>, - } - - impl Layer for PrintingLayer - where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - { - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - let span = ctx.span(id).unwrap(); - let scope = span.scope().map(|span| span.name()).collect::>(); - *self.last_entered_scope.lock().unwrap() = scope; - } - } - - let _guard = tracing::subscriber::set_default(crate::registry().with(PrintingLayer { - last_entered_scope: last_entered_scope.clone(), - })); - - let _root = tracing::info_span!("root").entered(); - assert_eq!(&*last_entered_scope.lock().unwrap(), &["root"]); - let _child = tracing::info_span!("child").entered(); - assert_eq!(&*last_entered_scope.lock().unwrap(), &["child", "root"]); - let _leaf = tracing::info_span!("leaf").entered(); - assert_eq!( - &*last_entered_scope.lock().unwrap(), - &["leaf", "child", "root"] - ); - } - - #[test] - fn spanref_scope_fromroot_iteration_order() { - let last_entered_scope = Arc::new(Mutex::new(Vec::new())); - - #[derive(Default)] - struct PrintingLayer { - last_entered_scope: Arc>>, - } - - impl Layer for PrintingLayer - where - S: Subscriber + for<'lookup> LookupSpan<'lookup>, - { - fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { - let span = ctx.span(id).unwrap(); - let scope = span - .scope() - .from_root() - .map(|span| span.name()) - .collect::>(); - *self.last_entered_scope.lock().unwrap() = scope; - } - } - - let _guard = tracing::subscriber::set_default(crate::registry().with(PrintingLayer { - last_entered_scope: last_entered_scope.clone(), - })); - - let _root = tracing::info_span!("root").entered(); - assert_eq!(&*last_entered_scope.lock().unwrap(), &["root"]); - let _child = tracing::info_span!("child").entered(); - assert_eq!(&*last_entered_scope.lock().unwrap(), &["root", "child",]); - let _leaf = tracing::info_span!("leaf").entered(); - assert_eq!( - &*last_entered_scope.lock().unwrap(), - &["root", "child", "leaf"] - ); - } -} diff --git a/vendor/tracing-subscriber/src/registry/sharded.rs b/vendor/tracing-subscriber/src/registry/sharded.rs deleted file mode 100644 index b81d5fef8..000000000 --- a/vendor/tracing-subscriber/src/registry/sharded.rs +++ /dev/null @@ -1,901 +0,0 @@ -use sharded_slab::{pool::Ref, Clear, Pool}; -use thread_local::ThreadLocal; - -use super::stack::SpanStack; -use crate::{ - filter::{FilterId, FilterMap, FilterState}, - registry::{ - extensions::{Extensions, ExtensionsInner, ExtensionsMut}, - LookupSpan, SpanData, - }, - sync::RwLock, -}; -use std::{ - cell::{self, Cell, RefCell}, - sync::atomic::{fence, AtomicUsize, Ordering}, -}; -use tracing_core::{ - dispatcher::{self, Dispatch}, - span::{self, Current, Id}, - Event, Interest, Metadata, Subscriber, -}; - -/// A shared, reusable store for spans. -/// -/// A `Registry` is a [`Subscriber`] around which multiple [`Layer`]s -/// implementing various behaviors may be [added]. Unlike other types -/// implementing `Subscriber`, `Registry` does not actually record traces itself: -/// instead, it collects and stores span data that is exposed to any [`Layer`]s -/// wrapping it through implementations of the [`LookupSpan`] trait. -/// The `Registry` is responsible for storing span metadata, recording -/// relationships between spans, and tracking which spans are active and which -/// are closed. In addition, it provides a mechanism for [`Layer`]s to store -/// user-defined per-span data, called [extensions], in the registry. This -/// allows [`Layer`]-specific data to benefit from the `Registry`'s -/// high-performance concurrent storage. -/// -/// This registry is implemented using a [lock-free sharded slab][slab], and is -/// highly optimized for concurrent access. -/// -/// # Span ID Generation -/// -/// Span IDs are not globally unique, but the registry ensures that -/// no two currently active spans have the same ID within a process. -/// -/// One of the primary responsibilities of the registry is to generate [span -/// IDs]. Therefore, it's important for other code that interacts with the -/// registry, such as [`Layer`]s, to understand the guarantees of the -/// span IDs that are generated. -/// -/// The registry's span IDs are guaranteed to be unique **at a given point -/// in time**. This means that an active span will never be assigned the -/// same ID as another **currently active** span. However, the registry -/// **will** eventually reuse the IDs of [closed] spans, although an ID -/// will never be reassigned immediately after a span has closed. -/// -/// Spans are not [considered closed] by the `Registry` until *every* -/// [`Span`] reference with that ID has been dropped. -/// -/// Thus: span IDs generated by the registry should be considered unique -/// only at a given point in time, and only relative to other spans -/// generated by the same process. Two spans with the same ID will not exist -/// in the same process concurrently. However, if historical span data is -/// being stored, the same ID may occur for multiple spans times in that -/// data. If spans must be uniquely identified in historical data, the user -/// code storing this data must assign its own unique identifiers to those -/// spans. A counter is generally sufficient for this. -/// -/// Similarly, span IDs generated by the registry are not unique outside of -/// a given process. Distributed tracing systems may require identifiers -/// that are unique across multiple processes on multiple machines (for -/// example, [OpenTelemetry's `SpanId`s and `TraceId`s][ot]). `tracing` span -/// IDs generated by the registry should **not** be used for this purpose. -/// Instead, code which integrates with a distributed tracing system should -/// generate and propagate its own IDs according to the rules specified by -/// the distributed tracing system. These IDs can be associated with -/// `tracing` spans using [fields] and/or [stored span data]. -/// -/// [span IDs]: tracing_core::span::Id -/// [slab]: sharded_slab -/// [`Layer`]: crate::Layer -/// [added]: crate::layer::Layer#composing-layers -/// [extensions]: super::Extensions -/// [closed]: https://docs.rs/tracing/latest/tracing/span/index.html#closing-spans -/// [considered closed]: tracing_core::subscriber::Subscriber::try_close() -/// [`Span`]: https://docs.rs/tracing/latest/tracing/span/struct.Span.html -/// [ot]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spancontext -/// [fields]: tracing_core::field -/// [stored span data]: crate::registry::SpanData::extensions_mut -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] -#[derive(Debug)] -pub struct Registry { - spans: Pool, - current_spans: ThreadLocal>, - next_filter_id: u8, -} - -/// Span data stored in a [`Registry`]. -/// -/// The registry stores well-known data defined by tracing: span relationships, -/// metadata and reference counts. Additional user-defined data provided by -/// [`Layer`s], such as formatted fields, metrics, or distributed traces should -/// be stored in the [extensions] typemap. -/// -/// [`Layer`s]: crate::layer::Layer -/// [extensions]: Extensions -#[cfg(feature = "registry")] -#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] -#[derive(Debug)] -pub struct Data<'a> { - /// Immutable reference to the pooled `DataInner` entry. - inner: Ref<'a, DataInner>, -} - -/// Stored data associated with a span. -/// -/// This type is pooled using [`sharded_slab::Pool`]; when a span is -/// dropped, the `DataInner` entry at that span's slab index is cleared -/// in place and reused by a future span. Thus, the `Default` and -/// [`sharded_slab::Clear`] implementations for this type are -/// load-bearing. -#[derive(Debug)] -struct DataInner { - filter_map: FilterMap, - metadata: &'static Metadata<'static>, - parent: Option, - ref_count: AtomicUsize, - // The span's `Extensions` typemap. Allocations for the `HashMap` backing - // this are pooled and reused in place. - pub(crate) extensions: RwLock, -} - -// === impl Registry === - -impl Default for Registry { - fn default() -> Self { - Self { - spans: Pool::new(), - current_spans: ThreadLocal::new(), - next_filter_id: 0, - } - } -} - -#[inline] -fn idx_to_id(idx: usize) -> Id { - Id::from_u64(idx as u64 + 1) -} - -#[inline] -fn id_to_idx(id: &Id) -> usize { - id.into_u64() as usize - 1 -} - -/// A guard that tracks how many [`Registry`]-backed `Layer`s have -/// processed an `on_close` event. -/// -/// This is needed to enable a [`Registry`]-backed Layer to access span -/// data after the `Layer` has recieved the `on_close` callback. -/// -/// Once all `Layer`s have processed this event, the [`Registry`] knows -/// that is able to safely remove the span tracked by `id`. `CloseGuard` -/// accomplishes this through a two-step process: -/// 1. Whenever a [`Registry`]-backed `Layer::on_close` method is -/// called, `Registry::start_close` is closed. -/// `Registry::start_close` increments a thread-local `CLOSE_COUNT` -/// by 1 and returns a `CloseGuard`. -/// 2. The `CloseGuard` is dropped at the end of `Layer::on_close`. On -/// drop, `CloseGuard` checks thread-local `CLOSE_COUNT`. If -/// `CLOSE_COUNT` is 0, the `CloseGuard` removes the span with the -/// `id` from the registry, as all `Layers` that might have seen the -/// `on_close` notification have processed it. If `CLOSE_COUNT` is -/// greater than 0, `CloseGuard` decrements the counter by one and -/// _does not_ remove the span from the [`Registry`]. -/// -pub(crate) struct CloseGuard<'a> { - id: Id, - registry: &'a Registry, - is_closing: bool, -} - -impl Registry { - fn get(&self, id: &Id) -> Option> { - self.spans.get(id_to_idx(id)) - } - - /// Returns a guard which tracks how many `Layer`s have - /// processed an `on_close` notification via the `CLOSE_COUNT` thread-local. - /// For additional details, see [`CloseGuard`]. - /// - pub(crate) fn start_close(&self, id: Id) -> CloseGuard<'_> { - CLOSE_COUNT.with(|count| { - let c = count.get(); - count.set(c + 1); - }); - CloseGuard { - id, - registry: self, - is_closing: false, - } - } - - pub(crate) fn has_per_layer_filters(&self) -> bool { - self.next_filter_id > 0 - } - - pub(crate) fn span_stack(&self) -> cell::Ref<'_, SpanStack> { - self.current_spans.get_or_default().borrow() - } -} - -thread_local! { - /// `CLOSE_COUNT` is the thread-local counter used by `CloseGuard` to - /// track how many layers have processed the close. - /// For additional details, see [`CloseGuard`]. - /// - static CLOSE_COUNT: Cell = Cell::new(0); -} - -impl Subscriber for Registry { - fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { - if self.has_per_layer_filters() { - return FilterState::take_interest().unwrap_or_else(Interest::always); - } - - Interest::always() - } - - fn enabled(&self, _: &Metadata<'_>) -> bool { - if self.has_per_layer_filters() { - return FilterState::event_enabled(); - } - true - } - - #[inline] - fn new_span(&self, attrs: &span::Attributes<'_>) -> span::Id { - let parent = if attrs.is_root() { - None - } else if attrs.is_contextual() { - self.current_span().id().map(|id| self.clone_span(id)) - } else { - attrs.parent().map(|id| self.clone_span(id)) - }; - - let id = self - .spans - // Check out a `DataInner` entry from the pool for the new span. If - // there are free entries already allocated in the pool, this will - // preferentially reuse one; otherwise, a new `DataInner` is - // allocated and added to the pool. - .create_with(|data| { - data.metadata = attrs.metadata(); - data.parent = parent; - data.filter_map = crate::filter::FILTERING.with(|filtering| filtering.filter_map()); - #[cfg(debug_assertions)] - { - if data.filter_map != FilterMap::default() { - debug_assert!(self.has_per_layer_filters()); - } - } - - let refs = data.ref_count.get_mut(); - debug_assert_eq!(*refs, 0); - *refs = 1; - }) - .expect("Unable to allocate another span"); - idx_to_id(id) - } - - /// This is intentionally not implemented, as recording fields - /// on a span is the responsibility of layers atop of this registry. - #[inline] - fn record(&self, _: &span::Id, _: &span::Record<'_>) {} - - fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {} - - /// This is intentionally not implemented, as recording events - /// is the responsibility of layers atop of this registry. - fn event(&self, _: &Event<'_>) {} - - fn enter(&self, id: &span::Id) { - if self - .current_spans - .get_or_default() - .borrow_mut() - .push(id.clone()) - { - self.clone_span(id); - } - } - - fn exit(&self, id: &span::Id) { - if let Some(spans) = self.current_spans.get() { - if spans.borrow_mut().pop(id) { - dispatcher::get_default(|dispatch| dispatch.try_close(id.clone())); - } - } - } - - fn clone_span(&self, id: &span::Id) -> span::Id { - let span = self - .get(id) - .unwrap_or_else(|| panic!( - "tried to clone {:?}, but no span exists with that ID\n\ - This may be caused by consuming a parent span (`parent: span`) rather than borrowing it (`parent: &span`).", - id, - )); - // Like `std::sync::Arc`, adds to the ref count (on clone) don't require - // a strong ordering; if we call` clone_span`, the reference count must - // always at least 1. The only synchronization necessary is between - // calls to `try_close`: we have to ensure that all threads have - // dropped their refs to the span before the span is closed. - let refs = span.ref_count.fetch_add(1, Ordering::Relaxed); - assert_ne!( - refs, 0, - "tried to clone a span ({:?}) that already closed", - id - ); - id.clone() - } - - fn current_span(&self) -> Current { - self.current_spans - .get() - .and_then(|spans| { - let spans = spans.borrow(); - let id = spans.current()?; - let span = self.get(id)?; - Some(Current::new(id.clone(), span.metadata)) - }) - .unwrap_or_else(Current::none) - } - - /// Decrements the reference count of the span with the given `id`, and - /// removes the span if it is zero. - /// - /// The allocated span slot will be reused when a new span is created. - fn try_close(&self, id: span::Id) -> bool { - let span = match self.get(&id) { - Some(span) => span, - None if std::thread::panicking() => return false, - None => panic!("tried to drop a ref to {:?}, but no such span exists!", id), - }; - - let refs = span.ref_count.fetch_sub(1, Ordering::Release); - if !std::thread::panicking() { - assert!(refs < std::usize::MAX, "reference count overflow!"); - } - if refs > 1 { - return false; - } - - // Synchronize if we are actually removing the span (stolen - // from std::Arc); this ensures that all other `try_close` calls on - // other threads happen-before we actually remove the span. - fence(Ordering::Acquire); - true - } -} - -impl<'a> LookupSpan<'a> for Registry { - type Data = Data<'a>; - - fn span_data(&'a self, id: &Id) -> Option { - let inner = self.get(id)?; - Some(Data { inner }) - } - - fn register_filter(&mut self) -> FilterId { - let id = FilterId::new(self.next_filter_id); - self.next_filter_id += 1; - id - } -} - -// === impl CloseGuard === - -impl<'a> CloseGuard<'a> { - pub(crate) fn set_closing(&mut self) { - self.is_closing = true; - } -} - -impl<'a> Drop for CloseGuard<'a> { - fn drop(&mut self) { - // If this returns with an error, we are already panicking. At - // this point, there's nothing we can really do to recover - // except by avoiding a double-panic. - let _ = CLOSE_COUNT.try_with(|count| { - let c = count.get(); - // Decrement the count to indicate that _this_ guard's - // `on_close` callback has completed. - // - // Note that we *must* do this before we actually remove the span - // from the registry, since dropping the `DataInner` may trigger a - // new close, if this span is the last reference to a parent span. - count.set(c - 1); - - // If the current close count is 1, this stack frame is the last - // `on_close` call. If the span is closing, it's okay to remove the - // span. - if c == 1 && self.is_closing { - self.registry.spans.clear(id_to_idx(&self.id)); - } - }); - } -} - -// === impl Data === - -impl<'a> SpanData<'a> for Data<'a> { - fn id(&self) -> Id { - idx_to_id(self.inner.key()) - } - - fn metadata(&self) -> &'static Metadata<'static> { - (*self).inner.metadata - } - - fn parent(&self) -> Option<&Id> { - self.inner.parent.as_ref() - } - - fn extensions(&self) -> Extensions<'_> { - Extensions::new(self.inner.extensions.read().expect("Mutex poisoned")) - } - - fn extensions_mut(&self) -> ExtensionsMut<'_> { - ExtensionsMut::new(self.inner.extensions.write().expect("Mutex poisoned")) - } - - #[inline] - fn is_enabled_for(&self, filter: FilterId) -> bool { - self.inner.filter_map.is_enabled(filter) - } -} - -// === impl DataInner === - -impl Default for DataInner { - fn default() -> Self { - // Since `DataInner` owns a `&'static Callsite` pointer, we need - // something to use as the initial default value for that callsite. - // Since we can't access a `DataInner` until it has had actual span data - // inserted into it, the null metadata will never actually be accessed. - struct NullCallsite; - impl tracing_core::callsite::Callsite for NullCallsite { - fn set_interest(&self, _: Interest) { - unreachable!( - "/!\\ Tried to register the null callsite /!\\\n \ - This should never have happened and is definitely a bug. \ - A `tracing` bug report would be appreciated." - ) - } - - fn metadata(&self) -> &Metadata<'_> { - unreachable!( - "/!\\ Tried to access the null callsite's metadata /!\\\n \ - This should never have happened and is definitely a bug. \ - A `tracing` bug report would be appreciated." - ) - } - } - - static NULL_CALLSITE: NullCallsite = NullCallsite; - static NULL_METADATA: Metadata<'static> = tracing_core::metadata! { - name: "", - target: "", - level: tracing_core::Level::TRACE, - fields: &[], - callsite: &NULL_CALLSITE, - kind: tracing_core::metadata::Kind::SPAN, - }; - - Self { - filter_map: FilterMap::default(), - metadata: &NULL_METADATA, - parent: None, - ref_count: AtomicUsize::new(0), - extensions: RwLock::new(ExtensionsInner::new()), - } - } -} - -impl Clear for DataInner { - /// Clears the span's data in place, dropping the parent's reference count. - fn clear(&mut self) { - // A span is not considered closed until all of its children have closed. - // Therefore, each span's `DataInner` holds a "reference" to the parent - // span, keeping the parent span open until all its children have closed. - // When we close a span, we must then decrement the parent's ref count - // (potentially, allowing it to close, if this child is the last reference - // to that span). - // We have to actually unpack the option inside the `get_default` - // closure, since it is a `FnMut`, but testing that there _is_ a value - // here lets us avoid the thread-local access if we don't need the - // dispatcher at all. - if self.parent.is_some() { - // Note that --- because `Layered::try_close` works by calling - // `try_close` on the inner subscriber and using the return value to - // determine whether to call the `Layer`'s `on_close` callback --- - // we must call `try_close` on the entire subscriber stack, rather - // than just on the registry. If the registry called `try_close` on - // itself directly, the layers wouldn't see the close notification. - let subscriber = dispatcher::get_default(Dispatch::clone); - if let Some(parent) = self.parent.take() { - let _ = subscriber.try_close(parent); - } - } - - // Clear (but do not deallocate!) the pooled `HashMap` for the span's extensions. - self.extensions - .get_mut() - .unwrap_or_else(|l| { - // This function can be called in a `Drop` impl, such as while - // panicking, so ignore lock poisoning. - l.into_inner() - }) - .clear(); - - self.filter_map = FilterMap::default(); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{layer::Context, registry::LookupSpan, Layer}; - use std::{ - collections::HashMap, - sync::{Arc, Mutex, Weak}, - }; - use tracing::{self, subscriber::with_default}; - use tracing_core::{ - dispatcher, - span::{Attributes, Id}, - Subscriber, - }; - - #[derive(Debug)] - struct DoesNothing; - impl Layer for DoesNothing {} - - struct AssertionLayer; - impl Layer for AssertionLayer - where - S: Subscriber + for<'a> LookupSpan<'a>, - { - fn on_close(&self, id: Id, ctx: Context<'_, S>) { - dbg!(format_args!("closing {:?}", id)); - assert!(&ctx.span(&id).is_some()); - } - } - - #[test] - fn single_layer_can_access_closed_span() { - let subscriber = AssertionLayer.with_subscriber(Registry::default()); - - with_default(subscriber, || { - let span = tracing::debug_span!("span"); - drop(span); - }); - } - - #[test] - fn multiple_layers_can_access_closed_span() { - let subscriber = AssertionLayer - .and_then(AssertionLayer) - .with_subscriber(Registry::default()); - - with_default(subscriber, || { - let span = tracing::debug_span!("span"); - drop(span); - }); - } - - struct CloseLayer { - inner: Arc>, - } - - struct CloseHandle { - state: Arc>, - } - - #[derive(Default)] - struct CloseState { - open: HashMap<&'static str, Weak<()>>, - closed: Vec<(&'static str, Weak<()>)>, - } - - struct SetRemoved(Arc<()>); - - impl Layer for CloseLayer - where - S: Subscriber + for<'a> LookupSpan<'a>, - { - fn on_new_span(&self, _: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { - let span = ctx.span(id).expect("Missing span; this is a bug"); - let mut lock = self.inner.lock().unwrap(); - let is_removed = Arc::new(()); - assert!( - lock.open - .insert(span.name(), Arc::downgrade(&is_removed)) - .is_none(), - "test layer saw multiple spans with the same name, the test is probably messed up" - ); - let mut extensions = span.extensions_mut(); - extensions.insert(SetRemoved(is_removed)); - } - - fn on_close(&self, id: Id, ctx: Context<'_, S>) { - let span = if let Some(span) = ctx.span(&id) { - span - } else { - println!( - "span {:?} did not exist in `on_close`, are we panicking?", - id - ); - return; - }; - let name = span.name(); - println!("close {} ({:?})", name, id); - if let Ok(mut lock) = self.inner.lock() { - if let Some(is_removed) = lock.open.remove(name) { - assert!(is_removed.upgrade().is_some()); - lock.closed.push((name, is_removed)); - } - } - } - } - - impl CloseLayer { - fn new() -> (Self, CloseHandle) { - let state = Arc::new(Mutex::new(CloseState::default())); - ( - Self { - inner: state.clone(), - }, - CloseHandle { state }, - ) - } - } - - impl CloseState { - fn is_open(&self, span: &str) -> bool { - self.open.contains_key(span) - } - - fn is_closed(&self, span: &str) -> bool { - self.closed.iter().any(|(name, _)| name == &span) - } - } - - impl CloseHandle { - fn assert_closed(&self, span: &str) { - let lock = self.state.lock().unwrap(); - assert!( - lock.is_closed(span), - "expected {} to be closed{}", - span, - if lock.is_open(span) { - " (it was still open)" - } else { - ", but it never existed (is there a problem with the test?)" - } - ) - } - - fn assert_open(&self, span: &str) { - let lock = self.state.lock().unwrap(); - assert!( - lock.is_open(span), - "expected {} to be open{}", - span, - if lock.is_closed(span) { - " (it was still open)" - } else { - ", but it never existed (is there a problem with the test?)" - } - ) - } - - fn assert_removed(&self, span: &str) { - let lock = self.state.lock().unwrap(); - let is_removed = match lock.closed.iter().find(|(name, _)| name == &span) { - Some((_, is_removed)) => is_removed, - None => panic!( - "expected {} to be removed from the registry, but it was not closed {}", - span, - if lock.is_closed(span) { - " (it was still open)" - } else { - ", but it never existed (is there a problem with the test?)" - } - ), - }; - assert!( - is_removed.upgrade().is_none(), - "expected {} to have been removed from the registry", - span - ) - } - - fn assert_not_removed(&self, span: &str) { - let lock = self.state.lock().unwrap(); - let is_removed = match lock.closed.iter().find(|(name, _)| name == &span) { - Some((_, is_removed)) => is_removed, - None if lock.is_open(span) => return, - None => unreachable!(), - }; - assert!( - is_removed.upgrade().is_some(), - "expected {} to have been removed from the registry", - span - ) - } - - #[allow(unused)] // may want this for future tests - fn assert_last_closed(&self, span: Option<&str>) { - let lock = self.state.lock().unwrap(); - let last = lock.closed.last().map(|(span, _)| span); - assert_eq!( - last, - span.as_ref(), - "expected {:?} to have closed last", - span - ); - } - - fn assert_closed_in_order(&self, order: impl AsRef<[&'static str]>) { - let lock = self.state.lock().unwrap(); - let order = order.as_ref(); - for (i, name) in order.iter().enumerate() { - assert_eq!( - lock.closed.get(i).map(|(span, _)| span), - Some(name), - "expected close order: {:?}, actual: {:?}", - order, - lock.closed.iter().map(|(name, _)| name).collect::>() - ); - } - } - } - - #[test] - fn spans_are_removed_from_registry() { - let (close_layer, state) = CloseLayer::new(); - let subscriber = AssertionLayer - .and_then(close_layer) - .with_subscriber(Registry::default()); - - // Create a `Dispatch` (which is internally reference counted) so that - // the subscriber lives to the end of the test. Otherwise, if we just - // passed the subscriber itself to `with_default`, we could see the span - // be dropped when the subscriber itself is dropped, destroying the - // registry. - let dispatch = dispatcher::Dispatch::new(subscriber); - - dispatcher::with_default(&dispatch, || { - let span = tracing::debug_span!("span1"); - drop(span); - let span = tracing::info_span!("span2"); - drop(span); - }); - - state.assert_removed("span1"); - state.assert_removed("span2"); - - // Ensure the registry itself outlives the span. - drop(dispatch); - } - - #[test] - fn spans_are_only_closed_when_the_last_ref_drops() { - let (close_layer, state) = CloseLayer::new(); - let subscriber = AssertionLayer - .and_then(close_layer) - .with_subscriber(Registry::default()); - - // Create a `Dispatch` (which is internally reference counted) so that - // the subscriber lives to the end of the test. Otherwise, if we just - // passed the subscriber itself to `with_default`, we could see the span - // be dropped when the subscriber itself is dropped, destroying the - // registry. - let dispatch = dispatcher::Dispatch::new(subscriber); - - let span2 = dispatcher::with_default(&dispatch, || { - let span = tracing::debug_span!("span1"); - drop(span); - let span2 = tracing::info_span!("span2"); - let span2_clone = span2.clone(); - drop(span2); - span2_clone - }); - - state.assert_removed("span1"); - state.assert_not_removed("span2"); - - drop(span2); - state.assert_removed("span1"); - - // Ensure the registry itself outlives the span. - drop(dispatch); - } - - #[test] - fn span_enter_guards_are_dropped_out_of_order() { - let (close_layer, state) = CloseLayer::new(); - let subscriber = AssertionLayer - .and_then(close_layer) - .with_subscriber(Registry::default()); - - // Create a `Dispatch` (which is internally reference counted) so that - // the subscriber lives to the end of the test. Otherwise, if we just - // passed the subscriber itself to `with_default`, we could see the span - // be dropped when the subscriber itself is dropped, destroying the - // registry. - let dispatch = dispatcher::Dispatch::new(subscriber); - - dispatcher::with_default(&dispatch, || { - let span1 = tracing::debug_span!("span1"); - let span2 = tracing::info_span!("span2"); - - let enter1 = span1.enter(); - let enter2 = span2.enter(); - - drop(enter1); - drop(span1); - - state.assert_removed("span1"); - state.assert_not_removed("span2"); - - drop(enter2); - state.assert_not_removed("span2"); - - drop(span2); - state.assert_removed("span1"); - state.assert_removed("span2"); - }); - } - - #[test] - fn child_closes_parent() { - // This test asserts that if a parent span's handle is dropped before - // a child span's handle, the parent will remain open until child - // closes, and will then be closed. - - let (close_layer, state) = CloseLayer::new(); - let subscriber = close_layer.with_subscriber(Registry::default()); - - let dispatch = dispatcher::Dispatch::new(subscriber); - - dispatcher::with_default(&dispatch, || { - let span1 = tracing::info_span!("parent"); - let span2 = tracing::info_span!(parent: &span1, "child"); - - state.assert_open("parent"); - state.assert_open("child"); - - drop(span1); - state.assert_open("parent"); - state.assert_open("child"); - - drop(span2); - state.assert_closed("parent"); - state.assert_closed("child"); - }); - } - - #[test] - fn child_closes_grandparent() { - // This test asserts that, when a span is kept open by a child which - // is *itself* kept open by a child, closing the grandchild will close - // both the parent *and* the grandparent. - let (close_layer, state) = CloseLayer::new(); - let subscriber = close_layer.with_subscriber(Registry::default()); - - let dispatch = dispatcher::Dispatch::new(subscriber); - - dispatcher::with_default(&dispatch, || { - let span1 = tracing::info_span!("grandparent"); - let span2 = tracing::info_span!(parent: &span1, "parent"); - let span3 = tracing::info_span!(parent: &span2, "child"); - - state.assert_open("grandparent"); - state.assert_open("parent"); - state.assert_open("child"); - - drop(span1); - drop(span2); - state.assert_open("grandparent"); - state.assert_open("parent"); - state.assert_open("child"); - - drop(span3); - - state.assert_closed_in_order(&["child", "parent", "grandparent"]); - }); - } -} diff --git a/vendor/tracing-subscriber/src/registry/stack.rs b/vendor/tracing-subscriber/src/registry/stack.rs deleted file mode 100644 index 4a3f7e59d..000000000 --- a/vendor/tracing-subscriber/src/registry/stack.rs +++ /dev/null @@ -1,77 +0,0 @@ -pub(crate) use tracing_core::span::Id; - -#[derive(Debug)] -struct ContextId { - id: Id, - duplicate: bool, -} - -/// `SpanStack` tracks what spans are currently executing on a thread-local basis. -/// -/// A "separate current span" for each thread is a semantic choice, as each span -/// can be executing in a different thread. -#[derive(Debug, Default)] -pub(crate) struct SpanStack { - stack: Vec, -} - -impl SpanStack { - #[inline] - pub(super) fn push(&mut self, id: Id) -> bool { - let duplicate = self.stack.iter().any(|i| i.id == id); - self.stack.push(ContextId { id, duplicate }); - !duplicate - } - - #[inline] - pub(super) fn pop(&mut self, expected_id: &Id) -> bool { - if let Some((idx, _)) = self - .stack - .iter() - .enumerate() - .rev() - .find(|(_, ctx_id)| ctx_id.id == *expected_id) - { - let ContextId { id: _, duplicate } = self.stack.remove(idx); - return !duplicate; - } - false - } - - #[inline] - pub(crate) fn iter(&self) -> impl Iterator { - self.stack - .iter() - .rev() - .filter_map(|ContextId { id, duplicate }| if !*duplicate { Some(id) } else { None }) - } - - #[inline] - pub(crate) fn current(&self) -> Option<&Id> { - self.iter().next() - } -} - -#[cfg(test)] -mod tests { - use super::{Id, SpanStack}; - - #[test] - fn pop_last_span() { - let mut stack = SpanStack::default(); - let id = Id::from_u64(1); - stack.push(id.clone()); - - assert!(stack.pop(&id)); - } - - #[test] - fn pop_first_span() { - let mut stack = SpanStack::default(); - stack.push(Id::from_u64(1)); - stack.push(Id::from_u64(2)); - - let id = Id::from_u64(1); - assert!(stack.pop(&id)); - } -} diff --git a/vendor/tracing-subscriber/src/reload.rs b/vendor/tracing-subscriber/src/reload.rs deleted file mode 100644 index 0c6c1c45c..000000000 --- a/vendor/tracing-subscriber/src/reload.rs +++ /dev/null @@ -1,360 +0,0 @@ -//! Wrapper for a `Layer` to allow it to be dynamically reloaded. -//! -//! This module provides a [`Layer` type] implementing the [`Layer` trait] or [`Filter` trait] -//! which wraps another type implementing the corresponding trait. This -//! allows the wrapped type to be replaced with another -//! instance of that type at runtime. -//! -//! This can be used in cases where a subset of `Layer` or `Filter` functionality -//! should be dynamically reconfigured, such as when filtering directives may -//! change at runtime. Note that this layer introduces a (relatively small) -//! amount of overhead, and should thus only be used as needed. -//! -//! # Examples -//! -//! Reloading a [global filtering](crate::layer#global-filtering) layer: -//! -//! ```rust -//! # use tracing::info; -//! use tracing_subscriber::{filter, fmt, reload, prelude::*}; -//! let filter = filter::LevelFilter::WARN; -//! let (filter, reload_handle) = reload::Layer::new(filter); -//! tracing_subscriber::registry() -//! .with(filter) -//! .with(fmt::Layer::default()) -//! .init(); -//! # -//! # // specifying the Registry type is required -//! # let _: &reload::Handle = &reload_handle; -//! # -//! info!("This will be ignored"); -//! reload_handle.modify(|filter| *filter = filter::LevelFilter::INFO); -//! info!("This will be logged"); -//! ``` -//! -//! Reloading a [`Filtered`](crate::filter::Filtered) layer: -//! -//! ```rust -//! # use tracing::info; -//! use tracing_subscriber::{filter, fmt, reload, prelude::*}; -//! let filtered_layer = fmt::Layer::default().with_filter(filter::LevelFilter::WARN); -//! let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer); -//! # -//! # // specifying the Registry type is required -//! # let _: &reload::Handle, -//! # filter::LevelFilter, tracing_subscriber::Registry>,tracing_subscriber::Registry> -//! # = &reload_handle; -//! # -//! tracing_subscriber::registry() -//! .with(filtered_layer) -//! .init(); -//! info!("This will be ignored"); -//! reload_handle.modify(|layer| *layer.filter_mut() = filter::LevelFilter::INFO); -//! info!("This will be logged"); -//! ``` -//! -//! ## Note -//! -//! The [`Layer`] implementation is unable to implement downcasting functionality, -//! so certain [`Layer`] will fail to downcast if wrapped in a `reload::Layer`. -//! -//! If you only want to be able to dynamically change the -//! `Filter` on a layer, prefer wrapping that `Filter` in the `reload::Layer`. -//! -//! [`Filter` trait]: crate::layer::Filter -//! [`Layer` type]: Layer -//! [`Layer` trait]: super::layer::Layer -use crate::layer; -use crate::sync::RwLock; - -use std::{ - error, fmt, - marker::PhantomData, - sync::{Arc, Weak}, -}; -use tracing_core::{ - callsite, span, - subscriber::{Interest, Subscriber}, - Event, LevelFilter, Metadata, -}; - -/// Wraps a `Layer` or `Filter`, allowing it to be reloaded dynamically at runtime. -#[derive(Debug)] -pub struct Layer { - // TODO(eliza): this once used a `crossbeam_util::ShardedRwLock`. We may - // eventually wish to replace it with a sharded lock implementation on top - // of our internal `RwLock` wrapper type. If possible, we should profile - // this first to determine if it's necessary. - inner: Arc>, - _s: PhantomData, -} - -/// Allows reloading the state of an associated [`Layer`](crate::layer::Layer). -#[derive(Debug)] -pub struct Handle { - inner: Weak>, - _s: PhantomData, -} - -/// Indicates that an error occurred when reloading a layer. -#[derive(Debug)] -pub struct Error { - kind: ErrorKind, -} - -#[derive(Debug)] -enum ErrorKind { - SubscriberGone, - Poisoned, -} - -// ===== impl Layer ===== - -impl crate::Layer for Layer -where - L: crate::Layer + 'static, - S: Subscriber, -{ - fn on_layer(&mut self, subscriber: &mut S) { - try_lock!(self.inner.write(), else return).on_layer(subscriber); - } - - #[inline] - fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { - try_lock!(self.inner.read(), else return Interest::sometimes()).register_callsite(metadata) - } - - #[inline] - fn enabled(&self, metadata: &Metadata<'_>, ctx: layer::Context<'_, S>) -> bool { - try_lock!(self.inner.read(), else return false).enabled(metadata, ctx) - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_new_span(attrs, id, ctx) - } - - #[inline] - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_record(span, values, ctx) - } - - #[inline] - fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_follows_from(span, follows, ctx) - } - - #[inline] - fn event_enabled(&self, event: &Event<'_>, ctx: layer::Context<'_, S>) -> bool { - try_lock!(self.inner.read(), else return false).event_enabled(event, ctx) - } - - #[inline] - fn on_event(&self, event: &Event<'_>, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_event(event, ctx) - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_enter(id, ctx) - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_exit(id, ctx) - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_close(id, ctx) - } - - #[inline] - fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_id_change(old, new, ctx) - } - - #[inline] - fn max_level_hint(&self) -> Option { - try_lock!(self.inner.read(), else return None).max_level_hint() - } -} - -// ===== impl Filter ===== - -#[cfg(all(feature = "registry", feature = "std"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] -impl crate::layer::Filter for Layer -where - L: crate::layer::Filter + 'static, - S: Subscriber, -{ - #[inline] - fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest { - try_lock!(self.inner.read(), else return Interest::sometimes()).callsite_enabled(metadata) - } - - #[inline] - fn enabled(&self, metadata: &Metadata<'_>, ctx: &layer::Context<'_, S>) -> bool { - try_lock!(self.inner.read(), else return false).enabled(metadata, ctx) - } - - #[inline] - fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_new_span(attrs, id, ctx) - } - - #[inline] - fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_record(span, values, ctx) - } - - #[inline] - fn on_enter(&self, id: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_enter(id, ctx) - } - - #[inline] - fn on_exit(&self, id: &span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_exit(id, ctx) - } - - #[inline] - fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) { - try_lock!(self.inner.read()).on_close(id, ctx) - } - - #[inline] - fn max_level_hint(&self) -> Option { - try_lock!(self.inner.read(), else return None).max_level_hint() - } -} - -impl Layer { - /// Wraps the given [`Layer`] or [`Filter`], returning a `reload::Layer` - /// and a `Handle` that allows the inner value to be modified at runtime. - /// - /// [`Layer`]: crate::layer::Layer - /// [`Filter`]: crate::layer::Filter - pub fn new(inner: L) -> (Self, Handle) { - let this = Self { - inner: Arc::new(RwLock::new(inner)), - _s: PhantomData, - }; - let handle = this.handle(); - (this, handle) - } - - /// Returns a `Handle` that can be used to reload the wrapped [`Layer`] or [`Filter`]. - /// - /// [`Layer`]: crate::layer::Layer - /// [`Filter`]: crate::filter::Filter - pub fn handle(&self) -> Handle { - Handle { - inner: Arc::downgrade(&self.inner), - _s: PhantomData, - } - } -} - -// ===== impl Handle ===== - -impl Handle { - /// Replace the current [`Layer`] or [`Filter`] with the provided `new_value`. - /// - /// [`Handle::reload`] cannot be used with the [`Filtered`] layer; use - /// [`Handle::modify`] instead (see [this issue] for additional details). - /// - /// However, if the _only_ the [`Filter`] needs to be modified, use - /// `reload::Layer` to wrap the `Filter` directly. - /// - /// [`Layer`]: crate::layer::Layer - /// [`Filter`]: crate::layer::Filter - /// [`Filtered`]: crate::filter::Filtered - /// - /// [this issue]: https://github.com/tokio-rs/tracing/issues/1629 - pub fn reload(&self, new_value: impl Into) -> Result<(), Error> { - self.modify(|layer| { - *layer = new_value.into(); - }) - } - - /// Invokes a closure with a mutable reference to the current layer or filter, - /// allowing it to be modified in place. - pub fn modify(&self, f: impl FnOnce(&mut L)) -> Result<(), Error> { - let inner = self.inner.upgrade().ok_or(Error { - kind: ErrorKind::SubscriberGone, - })?; - - let mut lock = try_lock!(inner.write(), else return Err(Error::poisoned())); - f(&mut *lock); - // Release the lock before rebuilding the interest cache, as that - // function will lock the new layer. - drop(lock); - - callsite::rebuild_interest_cache(); - Ok(()) - } - - /// Returns a clone of the layer or filter's current value if it still exists. - /// Otherwise, if the subscriber has been dropped, returns `None`. - pub fn clone_current(&self) -> Option - where - L: Clone, - { - self.with_current(L::clone).ok() - } - - /// Invokes a closure with a borrowed reference to the current layer or filter, - /// returning the result (or an error if the subscriber no longer exists). - pub fn with_current(&self, f: impl FnOnce(&L) -> T) -> Result { - let inner = self.inner.upgrade().ok_or(Error { - kind: ErrorKind::SubscriberGone, - })?; - let inner = try_lock!(inner.read(), else return Err(Error::poisoned())); - Ok(f(&*inner)) - } -} - -impl Clone for Handle { - fn clone(&self) -> Self { - Handle { - inner: self.inner.clone(), - _s: PhantomData, - } - } -} - -// ===== impl Error ===== - -impl Error { - fn poisoned() -> Self { - Self { - kind: ErrorKind::Poisoned, - } - } - - /// Returns `true` if this error occurred because the layer was poisoned by - /// a panic on another thread. - pub fn is_poisoned(&self) -> bool { - matches!(self.kind, ErrorKind::Poisoned) - } - - /// Returns `true` if this error occurred because the `Subscriber` - /// containing the reloadable layer was dropped. - pub fn is_dropped(&self) -> bool { - matches!(self.kind, ErrorKind::SubscriberGone) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let msg = match self.kind { - ErrorKind::SubscriberGone => "subscriber no longer exists", - ErrorKind::Poisoned => "lock poisoned", - }; - f.pad(msg) - } -} - -impl error::Error for Error {} diff --git a/vendor/tracing-subscriber/src/sync.rs b/vendor/tracing-subscriber/src/sync.rs deleted file mode 100644 index ec42b834a..000000000 --- a/vendor/tracing-subscriber/src/sync.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! Abstracts over sync primitive implementations. -//! -//! Optionally, we allow the Rust standard library's `RwLock` to be replaced -//! with the `parking_lot` crate's implementation. This may provide improved -//! performance in some cases. However, the `parking_lot` dependency is an -//! opt-in feature flag. Because `parking_lot::RwLock` has a slightly different -//! API than `std::sync::RwLock` (it does not support poisoning on panics), we -//! wrap it with a type that provides the same method signatures. This allows us -//! to transparently swap `parking_lot` in without changing code at the callsite. -#[allow(unused_imports)] // may be used later; -pub(crate) use std::sync::{LockResult, PoisonError, TryLockResult}; - -#[cfg(not(feature = "parking_lot"))] -pub(crate) use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; - -#[cfg(feature = "parking_lot")] -pub(crate) use self::parking_lot_impl::*; - -#[cfg(feature = "parking_lot")] -mod parking_lot_impl { - pub(crate) use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; - use std::sync::{LockResult, TryLockError, TryLockResult}; - - #[derive(Debug)] - pub(crate) struct RwLock { - inner: parking_lot::RwLock, - } - - impl RwLock { - pub(crate) fn new(val: T) -> Self { - Self { - inner: parking_lot::RwLock::new(val), - } - } - - #[inline] - pub(crate) fn get_mut(&mut self) -> LockResult<&mut T> { - Ok(self.inner.get_mut()) - } - - #[inline] - pub(crate) fn read(&self) -> LockResult> { - Ok(self.inner.read()) - } - - #[inline] - #[allow(dead_code)] // may be used later; - pub(crate) fn try_read(&self) -> TryLockResult> { - self.inner.try_read().ok_or(TryLockError::WouldBlock) - } - - #[inline] - pub(crate) fn write(&self) -> LockResult> { - Ok(self.inner.write()) - } - } -} diff --git a/vendor/tracing-subscriber/src/util.rs b/vendor/tracing-subscriber/src/util.rs deleted file mode 100644 index 1c98aa4d2..000000000 --- a/vendor/tracing-subscriber/src/util.rs +++ /dev/null @@ -1,153 +0,0 @@ -//! Extension traits and other utilities to make working with subscribers more -//! ergonomic. -use core::fmt; -#[cfg(feature = "std")] -use std::error::Error; -use tracing_core::dispatcher::{self, Dispatch}; -#[cfg(feature = "tracing-log")] -use tracing_log::AsLog; - -/// Extension trait adding utility methods for subscriber initialization. -/// -/// This trait provides extension methods to make configuring and setting a -/// [default subscriber] more ergonomic. It is automatically implemented for all -/// types that can be converted into a [trace dispatcher]. Since `Dispatch` -/// implements `From` for all `T: Subscriber`, all `Subscriber` -/// implementations will implement this extension trait as well. Types which -/// can be converted into `Subscriber`s, such as builders that construct a -/// `Subscriber`, may implement `Into`, and will also receive an -/// implementation of this trait. -/// -/// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber -/// [trace dispatcher]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html -pub trait SubscriberInitExt -where - Self: Into, -{ - /// Sets `self` as the [default subscriber] in the current scope, returning a - /// guard that will unset it when dropped. - /// - /// If the "tracing-log" feature flag is enabled, this will also initialize - /// a [`log`] compatibility layer. This allows the subscriber to consume - /// `log::Record`s as though they were `tracing` `Event`s. - /// - /// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber - /// [`log`]: https://crates.io/log - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - fn set_default(self) -> dispatcher::DefaultGuard { - #[cfg(feature = "tracing-log")] - let _ = tracing_log::LogTracer::init(); - - dispatcher::set_default(&self.into()) - } - - /// Attempts to set `self` as the [global default subscriber] in the current - /// scope, returning an error if one is already set. - /// - /// If the "tracing-log" feature flag is enabled, this will also attempt to - /// initialize a [`log`] compatibility layer. This allows the subscriber to - /// consume `log::Record`s as though they were `tracing` `Event`s. - /// - /// This method returns an error if a global default subscriber has already - /// been set, or if a `log` logger has already been set (when the - /// "tracing-log" feature is enabled). - /// - /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber - /// [`log`]: https://crates.io/log - fn try_init(self) -> Result<(), TryInitError> { - dispatcher::set_global_default(self.into()).map_err(TryInitError::new)?; - - // Since we are setting the global default subscriber, we can - // opportunistically go ahead and set its global max level hint as - // the max level for the `log` crate as well. This should make - // skipping `log` diagnostics much faster. - #[cfg(feature = "tracing-log")] - tracing_log::LogTracer::builder() - // Note that we must call this *after* setting the global default - // subscriber, so that we get its max level hint. - .with_max_level(tracing_core::LevelFilter::current().as_log()) - .init() - .map_err(TryInitError::new)?; - - Ok(()) - } - - /// Attempts to set `self` as the [global default subscriber] in the current - /// scope, panicking if this fails. - /// - /// If the "tracing-log" feature flag is enabled, this will also attempt to - /// initialize a [`log`] compatibility layer. This allows the subscriber to - /// consume `log::Record`s as though they were `tracing` `Event`s. - /// - /// This method panics if a global default subscriber has already been set, - /// or if a `log` logger has already been set (when the "tracing-log" - /// feature is enabled). - /// - /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber - /// [`log`]: https://crates.io/log - fn init(self) { - self.try_init() - .expect("failed to set global default subscriber") - } -} - -impl SubscriberInitExt for T where T: Into {} - -/// Error returned by [`try_init`](SubscriberInitExt::try_init) if a global default subscriber could not be initialized. -pub struct TryInitError { - #[cfg(feature = "std")] - inner: Box, - - #[cfg(not(feature = "std"))] - _p: (), -} - -// ==== impl TryInitError ==== - -impl TryInitError { - #[cfg(feature = "std")] - fn new(e: impl Into>) -> Self { - Self { inner: e.into() } - } - - #[cfg(not(feature = "std"))] - fn new(_: T) -> Self { - Self { _p: () } - } -} - -impl fmt::Debug for TryInitError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "std")] - { - fmt::Debug::fmt(&self.inner, f) - } - - #[cfg(not(feature = "std"))] - { - f.write_str("TryInitError(())") - } - } -} - -impl fmt::Display for TryInitError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "std")] - { - fmt::Display::fmt(&self.inner, f) - } - - #[cfg(not(feature = "std"))] - { - f.write_str("failed to set global default subscriber") - } - } -} - -#[cfg(feature = "std")] -impl Error for TryInitError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - self.inner.source() - } -} diff --git a/vendor/tracing-subscriber/tests/cached_layer_filters_dont_break_other_layers.rs b/vendor/tracing-subscriber/tests/cached_layer_filters_dont_break_other_layers.rs deleted file mode 100644 index 00e98a994..000000000 --- a/vendor/tracing-subscriber/tests/cached_layer_filters_dont_break_other_layers.rs +++ /dev/null @@ -1,123 +0,0 @@ -#![cfg(feature = "registry")] -mod support; -use self::support::*; -use tracing::Level; -use tracing_subscriber::{filter::LevelFilter, prelude::*}; - -#[test] -fn layer_filters() { - let (unfiltered, unfiltered_handle) = unfiltered("unfiltered"); - let (filtered, filtered_handle) = filtered("filtered"); - - let _subscriber = tracing_subscriber::registry() - .with(unfiltered) - .with(filtered.with_filter(filter())) - .set_default(); - - events(); - - unfiltered_handle.assert_finished(); - filtered_handle.assert_finished(); -} - -#[test] -fn layered_layer_filters() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - let unfiltered = unfiltered1.and_then(unfiltered2); - - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - let filtered = filtered1 - .with_filter(filter()) - .and_then(filtered2.with_filter(filter())); - - let _subscriber = tracing_subscriber::registry() - .with(unfiltered) - .with(filtered) - .set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -#[test] -fn out_of_order() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - - let _subscriber = tracing_subscriber::registry() - .with(unfiltered1) - .with(filtered1.with_filter(filter())) - .with(unfiltered2) - .with(filtered2.with_filter(filter())) - .set_default(); - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -#[test] -fn mixed_layered() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - - let layered1 = filtered1.with_filter(filter()).and_then(unfiltered1); - let layered2 = unfiltered2.and_then(filtered2.with_filter(filter())); - - let _subscriber = tracing_subscriber::registry() - .with(layered1) - .with(layered2) - .set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -fn events() { - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); -} - -fn filter() -> LevelFilter { - LevelFilter::INFO -} - -fn unfiltered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(name) - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle() -} - -fn filtered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(name) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle() -} diff --git a/vendor/tracing-subscriber/tests/duplicate_spans.rs b/vendor/tracing-subscriber/tests/duplicate_spans.rs deleted file mode 100644 index 5d4dc6a85..000000000 --- a/vendor/tracing-subscriber/tests/duplicate_spans.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![cfg(all(feature = "env-filter", feature = "fmt"))] -use tracing::{self, subscriber::with_default, Span}; -use tracing_subscriber::{filter::EnvFilter, FmtSubscriber}; - -#[test] -fn duplicate_spans() { - let subscriber = FmtSubscriber::builder() - .with_env_filter(EnvFilter::new("[root]=debug")) - .finish(); - - with_default(subscriber, || { - let root = tracing::debug_span!("root"); - root.in_scope(|| { - // root: - assert_eq!(root, Span::current(), "Current span must be 'root'"); - let leaf = tracing::debug_span!("leaf"); - leaf.in_scope(|| { - // root:leaf: - assert_eq!(leaf, Span::current(), "Current span must be 'leaf'"); - root.in_scope(|| { - // root:leaf: - assert_eq!( - leaf, - Span::current(), - "Current span must be 'leaf' after entering twice the 'root' span" - ); - }) - }); - // root: - assert_eq!( - root, - Span::current(), - "Current span must be root ('leaf' exited, nested 'root' exited)" - ); - - root.in_scope(|| { - assert_eq!(root, Span::current(), "Current span must be root"); - }); - // root: - assert_eq!( - root, - Span::current(), - "Current span must still be root after exiting nested 'root'" - ); - }); - }); -} diff --git a/vendor/tracing-subscriber/tests/env_filter/main.rs b/vendor/tracing-subscriber/tests/env_filter/main.rs deleted file mode 100644 index 3c3d4868b..000000000 --- a/vendor/tracing-subscriber/tests/env_filter/main.rs +++ /dev/null @@ -1,547 +0,0 @@ -#![cfg(feature = "env-filter")] - -#[path = "../support.rs"] -mod support; -use self::support::*; - -mod per_layer; - -use tracing::{self, subscriber::with_default, Level}; -use tracing_subscriber::{ - filter::{EnvFilter, LevelFilter}, - prelude::*, -}; - -#[test] -fn level_filter_event() { - let filter: EnvFilter = "info".parse().expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "foo", "this should also be disabled"); - tracing::warn!(target: "foo", "this should be enabled"); - tracing::error!("this should be enabled too"); - }); - - finished.assert_finished(); -} - -#[test] -fn same_name_spans() { - let filter: EnvFilter = "[foo{bar}]=trace,[foo{baz}]=trace" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("bar")), - ) - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("baz")), - ) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - with_default(subscriber, || { - tracing::trace_span!("foo", bar = 1); - tracing::trace_span!("foo", baz = 1); - }); - - finished.assert_finished(); -} - -#[test] -fn level_filter_event_with_target() { - let filter: EnvFilter = "info,stuff=debug".parse().expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) - .event(event::mock().at_level(Level::WARN).with_target("stuff")) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::ERROR).with_target("stuff")) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "stuff", "this should be enabled"); - tracing::debug!("but this shouldn't"); - tracing::trace!(target: "stuff", "and neither should this"); - tracing::warn!(target: "stuff", "this should be enabled"); - tracing::error!("this should be enabled too"); - tracing::error!(target: "stuff", "this should be enabled also"); - }); - - finished.assert_finished(); -} - -#[test] -fn level_filter_event_with_target_and_span_global() { - let filter: EnvFilter = "info,stuff[cool_span]=debug" - .parse() - .expect("filter should parse"); - - let cool_span = span::named("cool_span"); - let uncool_span = span::named("uncool_span"); - let (subscriber, handle) = subscriber::mock() - .enter(cool_span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![cool_span.clone()]), - ) - .exit(cool_span) - .enter(uncool_span.clone()) - .exit(uncool_span) - .done() - .run_with_handle(); - - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - { - let _span = tracing::info_span!(target: "stuff", "cool_span").entered(); - tracing::debug!("this should be enabled"); - } - - tracing::debug!("should also be disabled"); - - { - let _span = tracing::info_span!("uncool_span").entered(); - tracing::debug!("this should be disabled"); - } - }); - - handle.assert_finished(); -} - -#[test] -fn not_order_dependent() { - // this test reproduces tokio-rs/tracing#623 - - let filter: EnvFilter = "stuff=debug,info".parse().expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) - .event(event::mock().at_level(Level::WARN).with_target("stuff")) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::ERROR).with_target("stuff")) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "stuff", "this should be enabled"); - tracing::debug!("but this shouldn't"); - tracing::trace!(target: "stuff", "and neither should this"); - tracing::warn!(target: "stuff", "this should be enabled"); - tracing::error!("this should be enabled too"); - tracing::error!(target: "stuff", "this should be enabled also"); - }); - - finished.assert_finished(); -} - -#[test] -fn add_directive_enables_event() { - // this test reproduces tokio-rs/tracing#591 - - // by default, use info level - let mut filter = EnvFilter::new(LevelFilter::INFO.to_string()); - - // overwrite with a more specific directive - filter = filter.add_directive("hello=trace".parse().expect("directive should parse")); - - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::INFO).with_target("hello")) - .event(event::mock().at_level(Level::TRACE).with_target("hello")) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::info!(target: "hello", "hello info"); - tracing::trace!(target: "hello", "hello trace"); - }); - - finished.assert_finished(); -} - -#[test] -fn span_name_filter_is_dynamic() { - let filter: EnvFilter = "info,[cool_span]=debug" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::INFO)) - .enter(span::named("cool_span")) - .event(event::mock().at_level(Level::DEBUG)) - .enter(span::named("uncool_span")) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::DEBUG)) - .exit(span::named("uncool_span")) - .exit(span::named("cool_span")) - .enter(span::named("uncool_span")) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .exit(span::named("uncool_span")) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - let cool_span = tracing::info_span!("cool_span"); - let uncool_span = tracing::info_span!("uncool_span"); - - { - let _enter = cool_span.enter(); - tracing::debug!("i'm a cool event"); - tracing::trace!("i'm cool, but not cool enough"); - let _enter2 = uncool_span.enter(); - tracing::warn!("warning: extremely cool!"); - tracing::debug!("i'm still cool"); - } - - let _enter = uncool_span.enter(); - tracing::warn!("warning: not that cool"); - tracing::trace!("im not cool enough"); - tracing::error!("uncool error"); - }); - - finished.assert_finished(); -} - -#[test] -fn method_name_resolution() { - #[allow(unused_imports)] - use tracing_subscriber::layer::{Filter, Layer}; - - let filter = EnvFilter::new("hello_world=info"); - filter.max_level_hint(); -} - -// contains the same tests as the first half of this file -// but using EnvFilter as a `Filter`, not as a `Layer` -mod per_layer_filter { - use super::*; - - #[test] - fn level_filter_event() { - let filter: EnvFilter = "info".parse().expect("filter should parse"); - let (layer, handle) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "foo", "this should also be disabled"); - tracing::warn!(target: "foo", "this should be enabled"); - tracing::error!("this should be enabled too"); - - handle.assert_finished(); - } - - #[test] - fn same_name_spans() { - let filter: EnvFilter = "[foo{bar}]=trace,[foo{baz}]=trace" - .parse() - .expect("filter should parse"); - let (layer, handle) = layer::mock() - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("bar")), - ) - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("baz")), - ) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace_span!("foo", bar = 1); - tracing::trace_span!("foo", baz = 1); - - handle.assert_finished(); - } - - #[test] - fn level_filter_event_with_target() { - let filter: EnvFilter = "info,stuff=debug".parse().expect("filter should parse"); - let (layer, handle) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) - .event(event::mock().at_level(Level::WARN).with_target("stuff")) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::ERROR).with_target("stuff")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "stuff", "this should be enabled"); - tracing::debug!("but this shouldn't"); - tracing::trace!(target: "stuff", "and neither should this"); - tracing::warn!(target: "stuff", "this should be enabled"); - tracing::error!("this should be enabled too"); - tracing::error!(target: "stuff", "this should be enabled also"); - - handle.assert_finished(); - } - - #[test] - fn level_filter_event_with_target_and_span() { - let filter: EnvFilter = "stuff[cool_span]=debug" - .parse() - .expect("filter should parse"); - - let cool_span = span::named("cool_span"); - let (layer, handle) = layer::mock() - .enter(cool_span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![cool_span.clone()]), - ) - .exit(cool_span) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - { - let _span = tracing::info_span!(target: "stuff", "cool_span").entered(); - tracing::debug!("this should be enabled"); - } - - tracing::debug!("should also be disabled"); - - { - let _span = tracing::info_span!("uncool_span").entered(); - tracing::debug!("this should be disabled"); - } - - handle.assert_finished(); - } - - #[test] - fn not_order_dependent() { - // this test reproduces tokio-rs/tracing#623 - - let filter: EnvFilter = "stuff=debug,info".parse().expect("filter should parse"); - let (layer, finished) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) - .event(event::mock().at_level(Level::WARN).with_target("stuff")) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::ERROR).with_target("stuff")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "stuff", "this should be enabled"); - tracing::debug!("but this shouldn't"); - tracing::trace!(target: "stuff", "and neither should this"); - tracing::warn!(target: "stuff", "this should be enabled"); - tracing::error!("this should be enabled too"); - tracing::error!(target: "stuff", "this should be enabled also"); - - finished.assert_finished(); - } - - #[test] - fn add_directive_enables_event() { - // this test reproduces tokio-rs/tracing#591 - - // by default, use info level - let mut filter = EnvFilter::new(LevelFilter::INFO.to_string()); - - // overwrite with a more specific directive - filter = filter.add_directive("hello=trace".parse().expect("directive should parse")); - - let (layer, finished) = layer::mock() - .event(event::mock().at_level(Level::INFO).with_target("hello")) - .event(event::mock().at_level(Level::TRACE).with_target("hello")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::info!(target: "hello", "hello info"); - tracing::trace!(target: "hello", "hello trace"); - - finished.assert_finished(); - } - - #[test] - fn span_name_filter_is_dynamic() { - let filter: EnvFilter = "info,[cool_span]=debug" - .parse() - .expect("filter should parse"); - let cool_span = span::named("cool_span"); - let uncool_span = span::named("uncool_span"); - let (layer, finished) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .enter(cool_span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![cool_span.clone()]), - ) - .enter(uncool_span.clone()) - .event( - event::mock() - .at_level(Level::WARN) - .in_scope(vec![uncool_span.clone()]), - ) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![uncool_span.clone()]), - ) - .exit(uncool_span.clone()) - .exit(cool_span) - .enter(uncool_span.clone()) - .event( - event::mock() - .at_level(Level::WARN) - .in_scope(vec![uncool_span.clone()]), - ) - .event( - event::mock() - .at_level(Level::ERROR) - .in_scope(vec![uncool_span.clone()]), - ) - .exit(uncool_span) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - let cool_span = tracing::info_span!("cool_span"); - let uncool_span = tracing::info_span!("uncool_span"); - - { - let _enter = cool_span.enter(); - tracing::debug!("i'm a cool event"); - tracing::trace!("i'm cool, but not cool enough"); - let _enter2 = uncool_span.enter(); - tracing::warn!("warning: extremely cool!"); - tracing::debug!("i'm still cool"); - } - - { - let _enter = uncool_span.enter(); - tracing::warn!("warning: not that cool"); - tracing::trace!("im not cool enough"); - tracing::error!("uncool error"); - } - - finished.assert_finished(); - } - - #[test] - fn multiple_dynamic_filters() { - // Test that multiple dynamic (span) filters only apply to the layers - // they're attached to. - let (layer1, handle1) = { - let span = span::named("span1"); - let filter: EnvFilter = "[span1]=debug".parse().expect("filter 1 should parse"); - let (layer, handle) = layer::named("layer1") - .enter(span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![span.clone()]), - ) - .exit(span) - .done() - .run_with_handle(); - (layer.with_filter(filter), handle) - }; - - let (layer2, handle2) = { - let span = span::named("span2"); - let filter: EnvFilter = "[span2]=info".parse().expect("filter 2 should parse"); - let (layer, handle) = layer::named("layer2") - .enter(span.clone()) - .event( - event::mock() - .at_level(Level::INFO) - .in_scope(vec![span.clone()]), - ) - .exit(span) - .done() - .run_with_handle(); - (layer.with_filter(filter), handle) - }; - - let _subscriber = tracing_subscriber::registry() - .with(layer1) - .with(layer2) - .set_default(); - - tracing::info_span!("span1").in_scope(|| { - tracing::debug!("hello from span 1"); - tracing::trace!("not enabled"); - }); - - tracing::info_span!("span2").in_scope(|| { - tracing::info!("hello from span 2"); - tracing::debug!("not enabled"); - }); - - handle1.assert_finished(); - handle2.assert_finished(); - } -} diff --git a/vendor/tracing-subscriber/tests/env_filter/per_layer.rs b/vendor/tracing-subscriber/tests/env_filter/per_layer.rs deleted file mode 100644 index 8bf5698a4..000000000 --- a/vendor/tracing-subscriber/tests/env_filter/per_layer.rs +++ /dev/null @@ -1,305 +0,0 @@ -//! Tests for using `EnvFilter` as a per-layer filter (rather than a global -//! `Layer` filter). -#![cfg(feature = "registry")] -use super::*; - -#[test] -fn level_filter_event() { - let filter: EnvFilter = "info".parse().expect("filter should parse"); - let (layer, handle) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "foo", "this should also be disabled"); - tracing::warn!(target: "foo", "this should be enabled"); - tracing::error!("this should be enabled too"); - - handle.assert_finished(); -} - -#[test] -fn same_name_spans() { - let filter: EnvFilter = "[foo{bar}]=trace,[foo{baz}]=trace" - .parse() - .expect("filter should parse"); - let (layer, handle) = layer::mock() - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("bar")), - ) - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("baz")), - ) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace_span!("foo", bar = 1); - tracing::trace_span!("foo", baz = 1); - - handle.assert_finished(); -} - -#[test] -fn level_filter_event_with_target() { - let filter: EnvFilter = "info,stuff=debug".parse().expect("filter should parse"); - let (layer, handle) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) - .event(event::mock().at_level(Level::WARN).with_target("stuff")) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::ERROR).with_target("stuff")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "stuff", "this should be enabled"); - tracing::debug!("but this shouldn't"); - tracing::trace!(target: "stuff", "and neither should this"); - tracing::warn!(target: "stuff", "this should be enabled"); - tracing::error!("this should be enabled too"); - tracing::error!(target: "stuff", "this should be enabled also"); - - handle.assert_finished(); -} - -#[test] -fn level_filter_event_with_target_and_span() { - let filter: EnvFilter = "stuff[cool_span]=debug" - .parse() - .expect("filter should parse"); - - let cool_span = span::named("cool_span"); - let (layer, handle) = layer::mock() - .enter(cool_span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![cool_span.clone()]), - ) - .exit(cool_span) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - { - let _span = tracing::info_span!(target: "stuff", "cool_span").entered(); - tracing::debug!("this should be enabled"); - } - - tracing::debug!("should also be disabled"); - - { - let _span = tracing::info_span!("uncool_span").entered(); - tracing::debug!("this should be disabled"); - } - - handle.assert_finished(); -} - -#[test] -fn not_order_dependent() { - // this test reproduces tokio-rs/tracing#623 - - let filter: EnvFilter = "stuff=debug,info".parse().expect("filter should parse"); - let (layer, finished) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::DEBUG).with_target("stuff")) - .event(event::mock().at_level(Level::WARN).with_target("stuff")) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::ERROR).with_target("stuff")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - tracing::debug!(target: "stuff", "this should be enabled"); - tracing::debug!("but this shouldn't"); - tracing::trace!(target: "stuff", "and neither should this"); - tracing::warn!(target: "stuff", "this should be enabled"); - tracing::error!("this should be enabled too"); - tracing::error!(target: "stuff", "this should be enabled also"); - - finished.assert_finished(); -} - -#[test] -fn add_directive_enables_event() { - // this test reproduces tokio-rs/tracing#591 - - // by default, use info level - let mut filter = EnvFilter::new(LevelFilter::INFO.to_string()); - - // overwrite with a more specific directive - filter = filter.add_directive("hello=trace".parse().expect("directive should parse")); - - let (layer, finished) = layer::mock() - .event(event::mock().at_level(Level::INFO).with_target("hello")) - .event(event::mock().at_level(Level::TRACE).with_target("hello")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::info!(target: "hello", "hello info"); - tracing::trace!(target: "hello", "hello trace"); - - finished.assert_finished(); -} - -#[test] -fn span_name_filter_is_dynamic() { - let filter: EnvFilter = "info,[cool_span]=debug" - .parse() - .expect("filter should parse"); - let cool_span = span::named("cool_span"); - let uncool_span = span::named("uncool_span"); - let (layer, finished) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .enter(cool_span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![cool_span.clone()]), - ) - .enter(uncool_span.clone()) - .event( - event::mock() - .at_level(Level::WARN) - .in_scope(vec![uncool_span.clone()]), - ) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![uncool_span.clone()]), - ) - .exit(uncool_span.clone()) - .exit(cool_span) - .enter(uncool_span.clone()) - .event( - event::mock() - .at_level(Level::WARN) - .in_scope(vec![uncool_span.clone()]), - ) - .event( - event::mock() - .at_level(Level::ERROR) - .in_scope(vec![uncool_span.clone()]), - ) - .exit(uncool_span) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - tracing::trace!("this should be disabled"); - tracing::info!("this shouldn't be"); - let cool_span = tracing::info_span!("cool_span"); - let uncool_span = tracing::info_span!("uncool_span"); - - { - let _enter = cool_span.enter(); - tracing::debug!("i'm a cool event"); - tracing::trace!("i'm cool, but not cool enough"); - let _enter2 = uncool_span.enter(); - tracing::warn!("warning: extremely cool!"); - tracing::debug!("i'm still cool"); - } - - { - let _enter = uncool_span.enter(); - tracing::warn!("warning: not that cool"); - tracing::trace!("im not cool enough"); - tracing::error!("uncool error"); - } - - finished.assert_finished(); -} - -#[test] -fn multiple_dynamic_filters() { - // Test that multiple dynamic (span) filters only apply to the layers - // they're attached to. - let (layer1, handle1) = { - let span = span::named("span1"); - let filter: EnvFilter = "[span1]=debug".parse().expect("filter 1 should parse"); - let (layer, handle) = layer::named("layer1") - .enter(span.clone()) - .event( - event::mock() - .at_level(Level::DEBUG) - .in_scope(vec![span.clone()]), - ) - .exit(span) - .done() - .run_with_handle(); - (layer.with_filter(filter), handle) - }; - - let (layer2, handle2) = { - let span = span::named("span2"); - let filter: EnvFilter = "[span2]=info".parse().expect("filter 2 should parse"); - let (layer, handle) = layer::named("layer2") - .enter(span.clone()) - .event( - event::mock() - .at_level(Level::INFO) - .in_scope(vec![span.clone()]), - ) - .exit(span) - .done() - .run_with_handle(); - (layer.with_filter(filter), handle) - }; - - let _subscriber = tracing_subscriber::registry() - .with(layer1) - .with(layer2) - .set_default(); - - tracing::info_span!("span1").in_scope(|| { - tracing::debug!("hello from span 1"); - tracing::trace!("not enabled"); - }); - - tracing::info_span!("span2").in_scope(|| { - tracing::info!("hello from span 2"); - tracing::debug!("not enabled"); - }); - - handle1.assert_finished(); - handle2.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/event_enabling.rs b/vendor/tracing-subscriber/tests/event_enabling.rs deleted file mode 100644 index 8f67cfcba..000000000 --- a/vendor/tracing-subscriber/tests/event_enabling.rs +++ /dev/null @@ -1,81 +0,0 @@ -#![cfg(feature = "registry")] - -use std::sync::{Arc, Mutex}; -use tracing::{subscriber::with_default, Event, Metadata, Subscriber}; -use tracing_subscriber::{layer::Context, prelude::*, registry, Layer}; - -struct TrackingLayer { - enabled: bool, - event_enabled_count: Arc>, - event_enabled: bool, - on_event_count: Arc>, -} - -impl Layer for TrackingLayer -where - C: Subscriber + Send + Sync + 'static, -{ - fn enabled(&self, _metadata: &Metadata<'_>, _ctx: Context<'_, C>) -> bool { - self.enabled - } - - fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, C>) -> bool { - *self.event_enabled_count.lock().unwrap() += 1; - self.event_enabled - } - - fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, C>) { - *self.on_event_count.lock().unwrap() += 1; - } -} - -#[test] -fn event_enabled_is_only_called_once() { - let event_enabled_count = Arc::new(Mutex::default()); - let count = event_enabled_count.clone(); - let subscriber = registry().with(TrackingLayer { - enabled: true, - event_enabled_count, - event_enabled: true, - on_event_count: Arc::new(Mutex::default()), - }); - with_default(subscriber, || { - tracing::error!("hiya!"); - }); - - assert_eq!(1, *count.lock().unwrap()); -} - -#[test] -fn event_enabled_not_called_when_not_enabled() { - let event_enabled_count = Arc::new(Mutex::default()); - let count = event_enabled_count.clone(); - let subscriber = registry().with(TrackingLayer { - enabled: false, - event_enabled_count, - event_enabled: true, - on_event_count: Arc::new(Mutex::default()), - }); - with_default(subscriber, || { - tracing::error!("hiya!"); - }); - - assert_eq!(0, *count.lock().unwrap()); -} - -#[test] -fn event_disabled_does_disable_event() { - let on_event_count = Arc::new(Mutex::default()); - let count = on_event_count.clone(); - let subscriber = registry().with(TrackingLayer { - enabled: true, - event_enabled_count: Arc::new(Mutex::default()), - event_enabled: false, - on_event_count, - }); - with_default(subscriber, || { - tracing::error!("hiya!"); - }); - - assert_eq!(0, *count.lock().unwrap()); -} diff --git a/vendor/tracing-subscriber/tests/field_filter.rs b/vendor/tracing-subscriber/tests/field_filter.rs deleted file mode 100644 index f14a0626d..000000000 --- a/vendor/tracing-subscriber/tests/field_filter.rs +++ /dev/null @@ -1,115 +0,0 @@ -#![cfg(feature = "env-filter")] - -use tracing::{self, subscriber::with_default, Level}; -use tracing_mock::*; -use tracing_subscriber::{filter::EnvFilter, prelude::*}; - -#[test] -#[cfg_attr(not(flaky_tests), ignore)] -fn field_filter_events() { - let filter: EnvFilter = "[{thing}]=debug".parse().expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event( - event::mock() - .at_level(Level::INFO) - .with_fields(field::mock("thing")), - ) - .event( - event::mock() - .at_level(Level::DEBUG) - .with_fields(field::mock("thing")), - ) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!(disabled = true); - tracing::info!("also disabled"); - tracing::info!(thing = 1); - tracing::debug!(thing = 2); - tracing::trace!(thing = 3); - }); - - finished.assert_finished(); -} - -#[test] -#[cfg_attr(not(flaky_tests), ignore)] -fn field_filter_spans() { - let filter: EnvFilter = "[{enabled=true}]=debug" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .enter(span::mock().named("span1")) - .event( - event::mock() - .at_level(Level::INFO) - .with_fields(field::mock("something")), - ) - .exit(span::mock().named("span1")) - .enter(span::mock().named("span2")) - .exit(span::mock().named("span2")) - .enter(span::mock().named("span3")) - .event( - event::mock() - .at_level(Level::DEBUG) - .with_fields(field::mock("something")), - ) - .exit(span::mock().named("span3")) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!("disabled"); - tracing::info!("also disabled"); - tracing::info_span!("span1", enabled = true).in_scope(|| { - tracing::info!(something = 1); - }); - tracing::debug_span!("span2", enabled = false, foo = "hi").in_scope(|| { - tracing::warn!(something = 2); - }); - tracing::trace_span!("span3", enabled = true, answer = 42).in_scope(|| { - tracing::debug!(something = 2); - }); - }); - - finished.assert_finished(); -} - -#[test] -fn record_after_created() { - let filter: EnvFilter = "[{enabled=true}]=debug" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .enter(span::mock().named("span")) - .exit(span::mock().named("span")) - .record( - span::mock().named("span"), - field::mock("enabled").with_value(&true), - ) - .enter(span::mock().named("span")) - .event(event::mock().at_level(Level::DEBUG)) - .exit(span::mock().named("span")) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - let span = tracing::info_span!("span", enabled = false); - span.in_scope(|| { - tracing::debug!("i'm disabled!"); - }); - - span.record("enabled", &true); - span.in_scope(|| { - tracing::debug!("i'm enabled!"); - }); - - tracing::debug!("i'm also disabled"); - }); - - finished.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/filter_log.rs b/vendor/tracing-subscriber/tests/filter_log.rs deleted file mode 100644 index 8d57ed600..000000000 --- a/vendor/tracing-subscriber/tests/filter_log.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![cfg(all(feature = "env-filter", feature = "tracing-log"))] - -use tracing::{self, Level}; -use tracing_mock::*; -use tracing_subscriber::{filter::EnvFilter, prelude::*}; - -mod my_module { - pub(crate) fn test_records() { - log::trace!("this should be disabled"); - log::info!("this shouldn't be"); - log::debug!("this should be disabled"); - log::warn!("this should be enabled"); - log::warn!(target: "something else", "this shouldn't be enabled"); - log::error!("this should be enabled too"); - } - - pub(crate) fn test_log_enabled() { - assert!( - log::log_enabled!(log::Level::Info), - "info should be enabled inside `my_module`" - ); - assert!( - !log::log_enabled!(log::Level::Debug), - "debug should not be enabled inside `my_module`" - ); - assert!( - log::log_enabled!(log::Level::Warn), - "warn should be enabled inside `my_module`" - ); - } -} - -#[test] -fn log_is_enabled() { - let filter: EnvFilter = "filter_log::my_module=info" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - - // Note: we have to set the global default in order to set the `log` max - // level, which can only be set once. - subscriber.with(filter).init(); - - my_module::test_records(); - log::info!("this is disabled"); - - my_module::test_log_enabled(); - assert!( - !log::log_enabled!(log::Level::Info), - "info should not be enabled outside `my_module`" - ); - assert!( - !log::log_enabled!(log::Level::Warn), - "warn should not be enabled outside `my_module`" - ); - - finished.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/fmt_max_level_hint.rs b/vendor/tracing-subscriber/tests/fmt_max_level_hint.rs deleted file mode 100644 index 57a0f6e3f..000000000 --- a/vendor/tracing-subscriber/tests/fmt_max_level_hint.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![cfg(feature = "fmt")] -use tracing_subscriber::filter::LevelFilter; - -#[test] -fn fmt_sets_max_level_hint() { - tracing_subscriber::fmt() - .with_max_level(LevelFilter::DEBUG) - .init(); - assert_eq!(LevelFilter::current(), LevelFilter::DEBUG); -} diff --git a/vendor/tracing-subscriber/tests/hinted_layer_filters_dont_break_other_layers.rs b/vendor/tracing-subscriber/tests/hinted_layer_filters_dont_break_other_layers.rs deleted file mode 100644 index 897dae282..000000000 --- a/vendor/tracing-subscriber/tests/hinted_layer_filters_dont_break_other_layers.rs +++ /dev/null @@ -1,131 +0,0 @@ -#![cfg(feature = "registry")] -mod support; -use self::support::*; -use tracing::{Level, Metadata, Subscriber}; -use tracing_subscriber::{filter::DynFilterFn, layer::Context, prelude::*}; - -#[test] -fn layer_filters() { - let (unfiltered, unfiltered_handle) = unfiltered("unfiltered"); - let (filtered, filtered_handle) = filtered("filtered"); - - let subscriber = tracing_subscriber::registry() - .with(unfiltered) - .with(filtered.with_filter(filter())); - assert_eq!(subscriber.max_level_hint(), None); - let _subscriber = subscriber.set_default(); - - events(); - - unfiltered_handle.assert_finished(); - filtered_handle.assert_finished(); -} - -#[test] -fn layered_layer_filters() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - let unfiltered = unfiltered1.and_then(unfiltered2); - - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - let filtered = filtered1 - .with_filter(filter()) - .and_then(filtered2.with_filter(filter())); - - let subscriber = tracing_subscriber::registry() - .with(unfiltered) - .with(filtered); - assert_eq!(subscriber.max_level_hint(), None); - let _subscriber = subscriber.set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -#[test] -fn out_of_order() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - - let subscriber = tracing_subscriber::registry() - .with(unfiltered1) - .with(filtered1.with_filter(filter())) - .with(unfiltered2) - .with(filtered2.with_filter(filter())); - assert_eq!(subscriber.max_level_hint(), None); - let _subscriber = subscriber.set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -#[test] -fn mixed_layered() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - - let layered1 = filtered1.with_filter(filter()).and_then(unfiltered1); - let layered2 = unfiltered2.and_then(filtered2.with_filter(filter())); - - let subscriber = tracing_subscriber::registry().with(layered1).with(layered2); - assert_eq!(subscriber.max_level_hint(), None); - let _subscriber = subscriber.set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -fn events() { - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); -} - -fn filter() -> DynFilterFn { - DynFilterFn::new( - (|metadata: &Metadata<'_>, _: &tracing_subscriber::layer::Context<'_, S>| { - metadata.level() <= &Level::INFO - }) as fn(&Metadata<'_>, &Context<'_, S>) -> bool, - ) - .with_max_level_hint(Level::INFO) -} - -fn unfiltered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(name) - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle() -} - -fn filtered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(name) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle() -} diff --git a/vendor/tracing-subscriber/tests/layer_filter_interests_are_cached.rs b/vendor/tracing-subscriber/tests/layer_filter_interests_are_cached.rs deleted file mode 100644 index d89d3bf17..000000000 --- a/vendor/tracing-subscriber/tests/layer_filter_interests_are_cached.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![cfg(feature = "registry")] -mod support; -use self::support::*; - -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; -use tracing::{Level, Subscriber}; -use tracing_subscriber::{filter, prelude::*}; - -#[test] -fn layer_filter_interests_are_cached() { - let seen = Arc::new(Mutex::new(HashMap::new())); - let seen2 = seen.clone(); - let filter = filter::filter_fn(move |meta| { - *seen - .lock() - .unwrap() - .entry(meta.callsite()) - .or_insert(0usize) += 1; - meta.level() == &Level::INFO - }); - - let (expect, handle) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let subscriber = tracing_subscriber::registry().with(expect.with_filter(filter)); - assert!(subscriber.max_level_hint().is_none()); - - let _subscriber = subscriber.set_default(); - - fn events() { - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); - } - - events(); - { - let lock = seen2.lock().unwrap(); - for (callsite, &count) in lock.iter() { - assert_eq!( - count, 1, - "callsite {:?} should have been seen 1 time (after first set of events)", - callsite - ); - } - } - - events(); - { - let lock = seen2.lock().unwrap(); - for (callsite, &count) in lock.iter() { - assert_eq!( - count, 1, - "callsite {:?} should have been seen 1 time (after second set of events)", - callsite - ); - } - } - - handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/boxed.rs b/vendor/tracing-subscriber/tests/layer_filters/boxed.rs deleted file mode 100644 index 0fe37188e..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/boxed.rs +++ /dev/null @@ -1,42 +0,0 @@ -use super::*; -use tracing_subscriber::{filter, prelude::*, Layer}; - -fn layer() -> (ExpectLayer, subscriber::MockHandle) { - layer::mock().done().run_with_handle() -} - -fn filter() -> filter::DynFilterFn { - // Use dynamic filter fn to disable interest caching and max-level hints, - // allowing us to put all of these tests in the same file. - filter::dynamic_filter_fn(|_, _| false) -} - -/// reproduces https://github.com/tokio-rs/tracing/issues/1563#issuecomment-921363629 -#[test] -fn box_works() { - let (layer, handle) = layer(); - let layer = Box::new(layer.with_filter(filter())); - - let _guard = tracing_subscriber::registry().with(layer).set_default(); - - for i in 0..2 { - tracing::info!(i); - } - - handle.assert_finished(); -} - -/// the same as `box_works` but with a type-erased `Box`. -#[test] -fn dyn_box_works() { - let (layer, handle) = layer(); - let layer: Box + Send + Sync + 'static> = Box::new(layer.with_filter(filter())); - - let _guard = tracing_subscriber::registry().with(layer).set_default(); - - for i in 0..2 { - tracing::info!(i); - } - - handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/combinators.rs b/vendor/tracing-subscriber/tests/layer_filters/combinators.rs deleted file mode 100644 index 6052a2d00..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/combinators.rs +++ /dev/null @@ -1,42 +0,0 @@ -use super::*; -use tracing_subscriber::{ - filter::{filter_fn, FilterExt, LevelFilter}, - prelude::*, -}; - -#[test] -fn and() { - let (layer, handle) = layer::mock() - .event( - event::msg("a very interesting event") - .at_level(tracing::Level::INFO) - .with_target("interesting_target"), - ) - .done() - .run_with_handle(); - - // Enables spans and events with targets starting with `interesting_target`: - let target_filter = filter::filter_fn(|meta| meta.target().starts_with("interesting_target")); - - // Enables spans and events with levels `INFO` and below: - let level_filter = LevelFilter::INFO; - - // Combine the two filters together, returning a filter that only enables - // spans and events that *both* filters will enable: - let filter = target_filter.and(level_filter); - - let _subscriber = tracing_subscriber::registry() - .with(layer.with_filter(filter)) - .set_default(); - - // This event will *not* be enabled: - tracing::info!("an event with an uninteresting target"); - - // This event *will* be enabled: - tracing::info!(target: "interesting_target", "a very interesting event"); - - // This event will *not* be enabled: - tracing::debug!(target: "interesting_target", "interesting debug event..."); - - handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/downcast_raw.rs b/vendor/tracing-subscriber/tests/layer_filters/downcast_raw.rs deleted file mode 100644 index b5f7e35ce..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/downcast_raw.rs +++ /dev/null @@ -1,68 +0,0 @@ -use tracing::Subscriber; -use tracing_subscriber::filter::Targets; -use tracing_subscriber::prelude::*; -use tracing_subscriber::Layer; - -#[test] -fn downcast_ref_to_inner_layer_and_filter() { - // Test that a filtered layer gives downcast_ref access to - // both the layer and the filter. - - struct WrappedLayer; - - impl Layer for WrappedLayer - where - S: Subscriber, - S: for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>, - { - } - - let layer = WrappedLayer; - let filter = Targets::new().with_default(tracing::Level::INFO); - let registry = tracing_subscriber::registry().with(layer.with_filter(filter)); - let dispatch = tracing::dispatcher::Dispatch::new(registry); - - // The filter is available - assert!(dispatch.downcast_ref::().is_some()); - // The wrapped layer is available - assert!(dispatch.downcast_ref::().is_some()); -} - -#[test] -fn forward_downcast_raw_to_layer() { - // Test that a filtered layer still gives its wrapped layer a chance to - // return a custom struct from downcast_raw. - // https://github.com/tokio-rs/tracing/issues/1618 - - struct WrappedLayer { - with_context: WithContext, - } - - struct WithContext; - - impl Layer for WrappedLayer - where - S: Subscriber, - S: for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>, - { - unsafe fn downcast_raw(&self, id: std::any::TypeId) -> Option<*const ()> { - match id { - id if id == std::any::TypeId::of::() => Some(self as *const _ as *const ()), - id if id == std::any::TypeId::of::() => { - Some(&self.with_context as *const _ as *const ()) - } - _ => None, - } - } - } - - let layer = WrappedLayer { - with_context: WithContext, - }; - let filter = Targets::new().with_default(tracing::Level::INFO); - let registry = tracing_subscriber::registry().with(layer.with_filter(filter)); - let dispatch = tracing::dispatcher::Dispatch::new(registry); - - // Types from a custom implementation of `downcast_raw` are available - assert!(dispatch.downcast_ref::().is_some()); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/filter_scopes.rs b/vendor/tracing-subscriber/tests/layer_filters/filter_scopes.rs deleted file mode 100644 index 7fd7d843b..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/filter_scopes.rs +++ /dev/null @@ -1,131 +0,0 @@ -use super::*; - -#[test] -fn filters_span_scopes() { - let (debug_layer, debug_handle) = layer::named("debug") - .enter(span::mock().at_level(Level::DEBUG)) - .enter(span::mock().at_level(Level::INFO)) - .enter(span::mock().at_level(Level::WARN)) - .enter(span::mock().at_level(Level::ERROR)) - .event(event::msg("hello world").in_scope(vec![ - span::mock().at_level(Level::ERROR), - span::mock().at_level(Level::WARN), - span::mock().at_level(Level::INFO), - span::mock().at_level(Level::DEBUG), - ])) - .exit(span::mock().at_level(Level::ERROR)) - .exit(span::mock().at_level(Level::WARN)) - .exit(span::mock().at_level(Level::INFO)) - .exit(span::mock().at_level(Level::DEBUG)) - .done() - .run_with_handle(); - let (info_layer, info_handle) = layer::named("info") - .enter(span::mock().at_level(Level::INFO)) - .enter(span::mock().at_level(Level::WARN)) - .enter(span::mock().at_level(Level::ERROR)) - .event(event::msg("hello world").in_scope(vec![ - span::mock().at_level(Level::ERROR), - span::mock().at_level(Level::WARN), - span::mock().at_level(Level::INFO), - ])) - .exit(span::mock().at_level(Level::ERROR)) - .exit(span::mock().at_level(Level::WARN)) - .exit(span::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let (warn_layer, warn_handle) = layer::named("warn") - .enter(span::mock().at_level(Level::WARN)) - .enter(span::mock().at_level(Level::ERROR)) - .event(event::msg("hello world").in_scope(vec![ - span::mock().at_level(Level::ERROR), - span::mock().at_level(Level::WARN), - ])) - .exit(span::mock().at_level(Level::ERROR)) - .exit(span::mock().at_level(Level::WARN)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(debug_layer.with_filter(LevelFilter::DEBUG)) - .with(info_layer.with_filter(LevelFilter::INFO)) - .with(warn_layer.with_filter(LevelFilter::WARN)) - .set_default(); - - { - let _trace = tracing::trace_span!("my_span").entered(); - let _debug = tracing::debug_span!("my_span").entered(); - let _info = tracing::info_span!("my_span").entered(); - let _warn = tracing::warn_span!("my_span").entered(); - let _error = tracing::error_span!("my_span").entered(); - tracing::error!("hello world"); - } - - debug_handle.assert_finished(); - info_handle.assert_finished(); - warn_handle.assert_finished(); -} - -#[test] -fn filters_interleaved_span_scopes() { - fn target_layer(target: &'static str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(format!("target_{}", target)) - .enter(span::mock().with_target(target)) - .enter(span::mock().with_target(target)) - .event(event::msg("hello world").in_scope(vec![ - span::mock().with_target(target), - span::mock().with_target(target), - ])) - .event( - event::msg("hello to my target") - .in_scope(vec![ - span::mock().with_target(target), - span::mock().with_target(target), - ]) - .with_target(target), - ) - .exit(span::mock().with_target(target)) - .exit(span::mock().with_target(target)) - .done() - .run_with_handle() - } - - let (a_layer, a_handle) = target_layer("a"); - let (b_layer, b_handle) = target_layer("b"); - let (all_layer, all_handle) = layer::named("all") - .enter(span::mock().with_target("b")) - .enter(span::mock().with_target("a")) - .event(event::msg("hello world").in_scope(vec![ - span::mock().with_target("a"), - span::mock().with_target("b"), - ])) - .exit(span::mock().with_target("a")) - .exit(span::mock().with_target("b")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(all_layer.with_filter(LevelFilter::INFO)) - .with(a_layer.with_filter(filter::filter_fn(|meta| { - let target = meta.target(); - target == "a" || target == module_path!() - }))) - .with(b_layer.with_filter(filter::filter_fn(|meta| { - let target = meta.target(); - target == "b" || target == module_path!() - }))) - .set_default(); - - { - let _a1 = tracing::trace_span!(target: "a", "a/trace").entered(); - let _b1 = tracing::info_span!(target: "b", "b/info").entered(); - let _a2 = tracing::info_span!(target: "a", "a/info").entered(); - let _b2 = tracing::trace_span!(target: "b", "b/trace").entered(); - tracing::info!("hello world"); - tracing::debug!(target: "a", "hello to my target"); - tracing::debug!(target: "b", "hello to my target"); - } - - a_handle.assert_finished(); - b_handle.assert_finished(); - all_handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/main.rs b/vendor/tracing-subscriber/tests/layer_filters/main.rs deleted file mode 100644 index 0233f063b..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/main.rs +++ /dev/null @@ -1,189 +0,0 @@ -#![cfg(feature = "registry")] -#[path = "../support.rs"] -mod support; -use self::support::*; -mod boxed; -mod downcast_raw; -mod filter_scopes; -mod targets; -mod trees; -mod vec; - -use tracing::{level_filters::LevelFilter, Level}; -use tracing_subscriber::{filter, prelude::*, Layer}; - -#[test] -fn basic_layer_filters() { - let (trace_layer, trace_handle) = layer::named("trace") - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let (debug_layer, debug_handle) = layer::named("debug") - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let (info_layer, info_handle) = layer::named("info") - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(trace_layer.with_filter(LevelFilter::TRACE)) - .with(debug_layer.with_filter(LevelFilter::DEBUG)) - .with(info_layer.with_filter(LevelFilter::INFO)) - .set_default(); - - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - - trace_handle.assert_finished(); - debug_handle.assert_finished(); - info_handle.assert_finished(); -} - -#[test] -fn basic_layer_filters_spans() { - let (trace_layer, trace_handle) = layer::named("trace") - .new_span(span::mock().at_level(Level::TRACE)) - .new_span(span::mock().at_level(Level::DEBUG)) - .new_span(span::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let (debug_layer, debug_handle) = layer::named("debug") - .new_span(span::mock().at_level(Level::DEBUG)) - .new_span(span::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let (info_layer, info_handle) = layer::named("info") - .new_span(span::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(trace_layer.with_filter(LevelFilter::TRACE)) - .with(debug_layer.with_filter(LevelFilter::DEBUG)) - .with(info_layer.with_filter(LevelFilter::INFO)) - .set_default(); - - tracing::trace_span!("hello trace"); - tracing::debug_span!("hello debug"); - tracing::info_span!("hello info"); - - trace_handle.assert_finished(); - debug_handle.assert_finished(); - info_handle.assert_finished(); -} - -#[test] -fn global_filters_layers_still_work() { - let (expect, handle) = layer::mock() - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(expect) - .with(LevelFilter::INFO) - .set_default(); - - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); - - handle.assert_finished(); -} - -#[test] -fn global_filter_interests_are_cached() { - let (expect, handle) = layer::mock() - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(expect.with_filter(filter::filter_fn(|meta| { - assert!( - meta.level() <= &Level::INFO, - "enabled should not be called for callsites disabled by the global filter" - ); - meta.level() <= &Level::WARN - }))) - .with(LevelFilter::INFO) - .set_default(); - - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); - - handle.assert_finished(); -} - -#[test] -fn global_filters_affect_layer_filters() { - let (expect, handle) = layer::named("debug") - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(expect.with_filter(LevelFilter::DEBUG)) - .with(LevelFilter::INFO) - .set_default(); - - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); - - handle.assert_finished(); -} - -#[test] -fn filter_fn() { - let (all, all_handle) = layer::named("all_targets") - .event(event::msg("hello foo")) - .event(event::msg("hello bar")) - .done() - .run_with_handle(); - - let (foo, foo_handle) = layer::named("foo_target") - .event(event::msg("hello foo")) - .done() - .run_with_handle(); - - let (bar, bar_handle) = layer::named("bar_target") - .event(event::msg("hello bar")) - .done() - .run_with_handle(); - - let _subscriber = tracing_subscriber::registry() - .with(all) - .with(foo.with_filter(filter::filter_fn(|meta| meta.target().starts_with("foo")))) - .with(bar.with_filter(filter::filter_fn(|meta| meta.target().starts_with("bar")))) - .set_default(); - - tracing::trace!(target: "foo", "hello foo"); - tracing::trace!(target: "bar", "hello bar"); - - foo_handle.assert_finished(); - bar_handle.assert_finished(); - all_handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/targets.rs b/vendor/tracing-subscriber/tests/layer_filters/targets.rs deleted file mode 100644 index c8133044b..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/targets.rs +++ /dev/null @@ -1,59 +0,0 @@ -use super::*; -use tracing_subscriber::{ - filter::{filter_fn, Targets}, - prelude::*, -}; - -#[test] -#[cfg_attr(not(feature = "tracing-log"), ignore)] -fn log_events() { - // Reproduces https://github.com/tokio-rs/tracing/issues/1563 - mod inner { - pub(super) const MODULE_PATH: &str = module_path!(); - - #[tracing::instrument] - pub(super) fn logs() { - log::debug!("inner"); - } - } - - let filter = Targets::new() - .with_default(LevelFilter::DEBUG) - .with_target(inner::MODULE_PATH, LevelFilter::WARN); - - let layer = - tracing_subscriber::layer::Identity::new().with_filter(filter_fn(move |_meta| true)); - - let _guard = tracing_subscriber::registry() - .with(filter) - .with(layer) - .set_default(); - - inner::logs(); -} - -#[test] -fn inner_layer_short_circuits() { - // This test ensures that when a global filter short-circuits `Interest` - // evaluation, we aren't left with a "dirty" per-layer filter state. - - let (layer, handle) = layer::mock() - .event(event::msg("hello world")) - .done() - .run_with_handle(); - - let filter = Targets::new().with_target("magic_target", LevelFilter::DEBUG); - - let _guard = tracing_subscriber::registry() - // Note: we don't just use a `LevelFilter` for the global filter here, - // because it will just return a max level filter, and the chain of - // `register_callsite` calls that would trigger the bug never happens... - .with(filter::filter_fn(|meta| meta.level() <= &Level::INFO)) - .with(layer.with_filter(filter)) - .set_default(); - - tracing::debug!("skip me please!"); - tracing::info!(target: "magic_target", "hello world"); - - handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/trees.rs b/vendor/tracing-subscriber/tests/layer_filters/trees.rs deleted file mode 100644 index 18cdd8ccc..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/trees.rs +++ /dev/null @@ -1,146 +0,0 @@ -use super::*; - -#[test] -fn basic_trees() { - let (with_target, with_target_handle) = layer::named("info_with_target") - .event(event::mock().at_level(Level::INFO).with_target("my_target")) - .done() - .run_with_handle(); - - let (info, info_handle) = layer::named("info") - .event( - event::mock() - .at_level(Level::INFO) - .with_target(module_path!()), - ) - .event(event::mock().at_level(Level::INFO).with_target("my_target")) - .done() - .run_with_handle(); - - let (all, all_handle) = layer::named("all") - .event( - event::mock() - .at_level(Level::INFO) - .with_target(module_path!()), - ) - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::INFO).with_target("my_target")) - .event( - event::mock() - .at_level(Level::TRACE) - .with_target("my_target"), - ) - .done() - .run_with_handle(); - - let info_tree = info - .and_then( - with_target.with_filter(filter::filter_fn(|meta| dbg!(meta.target()) == "my_target")), - ) - .with_filter(LevelFilter::INFO); - - let subscriber = tracing_subscriber::registry().with(info_tree).with(all); - let _guard = dbg!(subscriber).set_default(); - - tracing::info!("hello world"); - tracing::trace!("hello trace"); - tracing::info!(target: "my_target", "hi to my target"); - tracing::trace!(target: "my_target", "hi to my target at trace"); - - all_handle.assert_finished(); - info_handle.assert_finished(); - with_target_handle.assert_finished(); -} - -#[test] -fn filter_span_scopes() { - fn target_layer(target: &'static str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(format!("target_{}", target)) - .enter(span::mock().with_target(target).at_level(Level::INFO)) - .event( - event::msg("hello world") - .in_scope(vec![span::mock().with_target(target).at_level(Level::INFO)]), - ) - .exit(span::mock().with_target(target).at_level(Level::INFO)) - .done() - .run_with_handle() - } - - let (a_layer, a_handle) = target_layer("a"); - let (b_layer, b_handle) = target_layer("b"); - let (info_layer, info_handle) = layer::named("info") - .enter(span::mock().with_target("b").at_level(Level::INFO)) - .enter(span::mock().with_target("a").at_level(Level::INFO)) - .event(event::msg("hello world").in_scope(vec![ - span::mock().with_target("a").at_level(Level::INFO), - span::mock().with_target("b").at_level(Level::INFO), - ])) - .exit(span::mock().with_target("a").at_level(Level::INFO)) - .exit(span::mock().with_target("b").at_level(Level::INFO)) - .done() - .run_with_handle(); - - let full_scope = vec![ - span::mock().with_target("b").at_level(Level::TRACE), - span::mock().with_target("a").at_level(Level::INFO), - span::mock().with_target("b").at_level(Level::INFO), - span::mock().with_target("a").at_level(Level::TRACE), - ]; - let (all_layer, all_handle) = layer::named("all") - .enter(span::mock().with_target("a").at_level(Level::TRACE)) - .enter(span::mock().with_target("b").at_level(Level::INFO)) - .enter(span::mock().with_target("a").at_level(Level::INFO)) - .enter(span::mock().with_target("b").at_level(Level::TRACE)) - .event(event::msg("hello world").in_scope(full_scope.clone())) - .event( - event::msg("hello to my target") - .with_target("a") - .in_scope(full_scope.clone()), - ) - .event( - event::msg("hello to my target") - .with_target("b") - .in_scope(full_scope), - ) - .exit(span::mock().with_target("b").at_level(Level::TRACE)) - .exit(span::mock().with_target("a").at_level(Level::INFO)) - .exit(span::mock().with_target("b").at_level(Level::INFO)) - .exit(span::mock().with_target("a").at_level(Level::TRACE)) - .done() - .run_with_handle(); - - let a_layer = a_layer.with_filter(filter::filter_fn(|meta| { - let target = meta.target(); - target == "a" || target == module_path!() - })); - - let b_layer = b_layer.with_filter(filter::filter_fn(|meta| { - let target = meta.target(); - target == "b" || target == module_path!() - })); - - let info_tree = info_layer - .and_then(a_layer) - .and_then(b_layer) - .with_filter(LevelFilter::INFO); - - let subscriber = tracing_subscriber::registry() - .with(info_tree) - .with(all_layer); - let _guard = dbg!(subscriber).set_default(); - - { - let _a1 = tracing::trace_span!(target: "a", "a/trace").entered(); - let _b1 = tracing::info_span!(target: "b", "b/info").entered(); - let _a2 = tracing::info_span!(target: "a", "a/info").entered(); - let _b2 = tracing::trace_span!(target: "b", "b/trace").entered(); - tracing::info!("hello world"); - tracing::debug!(target: "a", "hello to my target"); - tracing::debug!(target: "b", "hello to my target"); - } - - all_handle.assert_finished(); - info_handle.assert_finished(); - a_handle.assert_finished(); - b_handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/layer_filters/vec.rs b/vendor/tracing-subscriber/tests/layer_filters/vec.rs deleted file mode 100644 index 87244e4ab..000000000 --- a/vendor/tracing-subscriber/tests/layer_filters/vec.rs +++ /dev/null @@ -1,120 +0,0 @@ -use super::*; -use tracing::Subscriber; - -#[test] -fn with_filters_unboxed() { - let (trace_layer, trace_handle) = layer::named("trace") - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let trace_layer = trace_layer.with_filter(LevelFilter::TRACE); - - let (debug_layer, debug_handle) = layer::named("debug") - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let debug_layer = debug_layer.with_filter(LevelFilter::DEBUG); - - let (info_layer, info_handle) = layer::named("info") - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let info_layer = info_layer.with_filter(LevelFilter::INFO); - - let _subscriber = tracing_subscriber::registry() - .with(vec![trace_layer, debug_layer, info_layer]) - .set_default(); - - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - - trace_handle.assert_finished(); - debug_handle.assert_finished(); - info_handle.assert_finished(); -} - -#[test] -fn with_filters_boxed() { - let (unfiltered_layer, unfiltered_handle) = layer::named("unfiltered") - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let unfiltered_layer = unfiltered_layer.boxed(); - - let (debug_layer, debug_handle) = layer::named("debug") - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let debug_layer = debug_layer.with_filter(LevelFilter::DEBUG).boxed(); - - let (target_layer, target_handle) = layer::named("target") - .event(event::mock().at_level(Level::INFO)) - .done() - .run_with_handle(); - let target_layer = target_layer - .with_filter(filter::filter_fn(|meta| meta.target() == "my_target")) - .boxed(); - - let _subscriber = tracing_subscriber::registry() - .with(vec![unfiltered_layer, debug_layer, target_layer]) - .set_default(); - - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!(target: "my_target", "hello my target"); - - unfiltered_handle.assert_finished(); - debug_handle.assert_finished(); - target_handle.assert_finished(); -} - -#[test] -fn mixed_max_level_hint() { - let unfiltered = layer::named("unfiltered").run().boxed(); - let info = layer::named("info") - .run() - .with_filter(LevelFilter::INFO) - .boxed(); - let debug = layer::named("debug") - .run() - .with_filter(LevelFilter::DEBUG) - .boxed(); - - let subscriber = tracing_subscriber::registry().with(vec![unfiltered, info, debug]); - - assert_eq!(subscriber.max_level_hint(), None); -} - -#[test] -fn all_filtered_max_level_hint() { - let warn = layer::named("warn") - .run() - .with_filter(LevelFilter::WARN) - .boxed(); - let info = layer::named("info") - .run() - .with_filter(LevelFilter::INFO) - .boxed(); - let debug = layer::named("debug") - .run() - .with_filter(LevelFilter::DEBUG) - .boxed(); - - let subscriber = tracing_subscriber::registry().with(vec![warn, info, debug]); - - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); -} - -#[test] -fn empty_vec() { - // Just a None means everything is off - let subscriber = tracing_subscriber::registry().with(Vec::::new()); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::OFF)); -} diff --git a/vendor/tracing-subscriber/tests/multiple_layer_filter_interests_cached.rs b/vendor/tracing-subscriber/tests/multiple_layer_filter_interests_cached.rs deleted file mode 100644 index 5c25e7f03..000000000 --- a/vendor/tracing-subscriber/tests/multiple_layer_filter_interests_cached.rs +++ /dev/null @@ -1,131 +0,0 @@ -#![cfg(feature = "registry")] -mod support; -use self::support::*; - -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; -use tracing::{Level, Subscriber}; -use tracing_subscriber::{filter, prelude::*}; - -#[test] -fn multiple_layer_filter_interests_are_cached() { - // This layer will return Interest::always for INFO and lower. - let seen_info = Arc::new(Mutex::new(HashMap::new())); - let seen_info2 = seen_info.clone(); - let filter = filter::filter_fn(move |meta| { - *seen_info - .lock() - .unwrap() - .entry(*meta.level()) - .or_insert(0usize) += 1; - meta.level() <= &Level::INFO - }); - let seen_info = seen_info2; - - let (info_layer, info_handle) = layer::named("info") - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - let info_layer = info_layer.with_filter(filter); - - // This layer will return Interest::always for WARN and lower. - let seen_warn = Arc::new(Mutex::new(HashMap::new())); - let seen_warn2 = seen_warn.clone(); - let filter = filter::filter_fn(move |meta| { - *seen_warn - .lock() - .unwrap() - .entry(*meta.level()) - .or_insert(0usize) += 1; - meta.level() <= &Level::WARN - }); - let seen_warn = seen_warn2; - - let (warn_layer, warn_handle) = layer::named("warn") - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - let warn_layer = warn_layer.with_filter(filter); - - let subscriber = tracing_subscriber::registry() - .with(warn_layer) - .with(info_layer); - assert!(subscriber.max_level_hint().is_none()); - - let _subscriber = subscriber.set_default(); - - fn events() { - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); - } - - events(); - { - let lock = seen_info.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the INFO layer (after first set of events)", - level - ); - } - - let lock = seen_warn.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the WARN layer (after first set of events)", - level - ); - } - } - - events(); - { - let lock = seen_info.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the INFO layer (after second set of events)", - level - ); - } - - let lock = seen_warn.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the WARN layer (after second set of events)", - level - ); - } - } - - info_handle.assert_finished(); - warn_handle.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/option.rs b/vendor/tracing-subscriber/tests/option.rs deleted file mode 100644 index 738cc0a6c..000000000 --- a/vendor/tracing-subscriber/tests/option.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![cfg(feature = "registry")] -use tracing::level_filters::LevelFilter; -use tracing::Subscriber; -use tracing_subscriber::prelude::*; - -// This test is just used to compare to the tests below -#[test] -fn just_layer() { - let subscriber = tracing_subscriber::registry().with(LevelFilter::INFO); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::INFO)); -} - -#[test] -fn subscriber_and_option_some_layer() { - let subscriber = tracing_subscriber::registry() - .with(LevelFilter::INFO) - .with(Some(LevelFilter::DEBUG)); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); -} - -#[test] -fn subscriber_and_option_none_layer() { - // None means the other layer takes control - let subscriber = tracing_subscriber::registry() - .with(LevelFilter::ERROR) - .with(None::); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::ERROR)); -} - -#[test] -fn just_option_some_layer() { - // Just a None means everything is off - let subscriber = tracing_subscriber::registry().with(None::); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::OFF)); -} - -#[test] -fn just_option_none_layer() { - let subscriber = tracing_subscriber::registry().with(Some(LevelFilter::ERROR)); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::ERROR)); -} diff --git a/vendor/tracing-subscriber/tests/registry_max_level_hint.rs b/vendor/tracing-subscriber/tests/registry_max_level_hint.rs deleted file mode 100644 index f94c8a1fb..000000000 --- a/vendor/tracing-subscriber/tests/registry_max_level_hint.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![cfg(all(feature = "registry", feature = "fmt"))] -use tracing_subscriber::{filter::LevelFilter, prelude::*}; - -#[test] -fn registry_sets_max_level_hint() { - tracing_subscriber::registry() - .with(tracing_subscriber::fmt::layer()) - .with(LevelFilter::DEBUG) - .init(); - assert_eq!(LevelFilter::current(), LevelFilter::DEBUG); -} diff --git a/vendor/tracing-subscriber/tests/registry_with_subscriber.rs b/vendor/tracing-subscriber/tests/registry_with_subscriber.rs deleted file mode 100644 index 50d2f551d..000000000 --- a/vendor/tracing-subscriber/tests/registry_with_subscriber.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![cfg(feature = "registry")] -use tracing_futures::{Instrument, WithSubscriber}; -use tracing_subscriber::prelude::*; - -#[tokio::test] -async fn future_with_subscriber() { - tracing_subscriber::registry().init(); - let span = tracing::info_span!("foo"); - let _e = span.enter(); - let span = tracing::info_span!("bar"); - let _e = span.enter(); - tokio::spawn( - async { - async { - let span = tracing::Span::current(); - println!("{:?}", span); - } - .instrument(tracing::info_span!("hi")) - .await - } - .with_subscriber(tracing_subscriber::registry()), - ) - .await - .unwrap(); -} diff --git a/vendor/tracing-subscriber/tests/reload.rs b/vendor/tracing-subscriber/tests/reload.rs deleted file mode 100644 index 28662e2e6..000000000 --- a/vendor/tracing-subscriber/tests/reload.rs +++ /dev/null @@ -1,155 +0,0 @@ -#![cfg(feature = "registry")] -use std::sync::atomic::{AtomicUsize, Ordering}; -use tracing_core::{ - span::{Attributes, Id, Record}, - subscriber::Interest, - Event, LevelFilter, Metadata, Subscriber, -}; -use tracing_subscriber::{layer, prelude::*, reload::*}; - -pub struct NopSubscriber; -fn event() { - tracing::info!("my event"); -} - -impl Subscriber for NopSubscriber { - fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { - Interest::never() - } - - fn enabled(&self, _: &Metadata<'_>) -> bool { - false - } - - fn new_span(&self, _: &Attributes<'_>) -> Id { - Id::from_u64(1) - } - - fn record(&self, _: &Id, _: &Record<'_>) {} - fn record_follows_from(&self, _: &Id, _: &Id) {} - fn event(&self, _: &Event<'_>) {} - fn enter(&self, _: &Id) {} - fn exit(&self, _: &Id) {} -} - -#[test] -fn reload_handle() { - static FILTER1_CALLS: AtomicUsize = AtomicUsize::new(0); - static FILTER2_CALLS: AtomicUsize = AtomicUsize::new(0); - - enum Filter { - One, - Two, - } - - impl tracing_subscriber::Layer for Filter { - fn register_callsite(&self, m: &Metadata<'_>) -> Interest { - println!("REGISTER: {:?}", m); - Interest::sometimes() - } - - fn enabled(&self, m: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { - println!("ENABLED: {:?}", m); - match self { - Filter::One => FILTER1_CALLS.fetch_add(1, Ordering::SeqCst), - Filter::Two => FILTER2_CALLS.fetch_add(1, Ordering::SeqCst), - }; - true - } - - fn max_level_hint(&self) -> Option { - match self { - Filter::One => Some(LevelFilter::INFO), - Filter::Two => Some(LevelFilter::DEBUG), - } - } - } - - let (layer, handle) = Layer::new(Filter::One); - - let subscriber = tracing_core::dispatcher::Dispatch::new(layer.with_subscriber(NopSubscriber)); - - tracing_core::dispatcher::with_default(&subscriber, || { - assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 0); - assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0); - - event(); - - assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1); - assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0); - - assert_eq!(LevelFilter::current(), LevelFilter::INFO); - handle.reload(Filter::Two).expect("should reload"); - assert_eq!(LevelFilter::current(), LevelFilter::DEBUG); - - event(); - - assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1); - assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 1); - }) -} - -#[test] -fn reload_filter() { - struct NopLayer; - impl tracing_subscriber::Layer for NopLayer { - fn register_callsite(&self, _m: &Metadata<'_>) -> Interest { - Interest::sometimes() - } - - fn enabled(&self, _m: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { - true - } - } - - static FILTER1_CALLS: AtomicUsize = AtomicUsize::new(0); - static FILTER2_CALLS: AtomicUsize = AtomicUsize::new(0); - - enum Filter { - One, - Two, - } - - impl tracing_subscriber::layer::Filter for Filter { - fn enabled(&self, m: &Metadata<'_>, _: &layer::Context<'_, S>) -> bool { - println!("ENABLED: {:?}", m); - match self { - Filter::One => FILTER1_CALLS.fetch_add(1, Ordering::SeqCst), - Filter::Two => FILTER2_CALLS.fetch_add(1, Ordering::SeqCst), - }; - true - } - - fn max_level_hint(&self) -> Option { - match self { - Filter::One => Some(LevelFilter::INFO), - Filter::Two => Some(LevelFilter::DEBUG), - } - } - } - - let (filter, handle) = Layer::new(Filter::One); - - let dispatcher = tracing_core::Dispatch::new( - tracing_subscriber::registry().with(NopLayer.with_filter(filter)), - ); - - tracing_core::dispatcher::with_default(&dispatcher, || { - assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 0); - assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0); - - event(); - - assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1); - assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 0); - - assert_eq!(LevelFilter::current(), LevelFilter::INFO); - handle.reload(Filter::Two).expect("should reload"); - assert_eq!(LevelFilter::current(), LevelFilter::DEBUG); - - event(); - - assert_eq!(FILTER1_CALLS.load(Ordering::SeqCst), 1); - assert_eq!(FILTER2_CALLS.load(Ordering::SeqCst), 1); - }) -} diff --git a/vendor/tracing-subscriber/tests/same_len_filters.rs b/vendor/tracing-subscriber/tests/same_len_filters.rs deleted file mode 100644 index 879e578d7..000000000 --- a/vendor/tracing-subscriber/tests/same_len_filters.rs +++ /dev/null @@ -1,81 +0,0 @@ -// These tests include field filters with no targets, so they have to go in a -// separate file. -#![cfg(feature = "env-filter")] - -use tracing::{self, subscriber::with_default, Level}; -use tracing_mock::*; -use tracing_subscriber::{filter::EnvFilter, prelude::*}; - -#[test] -fn same_length_targets() { - let filter: EnvFilter = "foo=trace,bar=trace".parse().expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::TRACE)) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - - with_default(subscriber, || { - tracing::trace!(target: "foo", "foo"); - tracing::trace!(target: "bar", "bar"); - }); - - finished.assert_finished(); -} - -#[test] -fn same_num_fields_event() { - let filter: EnvFilter = "[{foo}]=trace,[{bar}]=trace" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .event( - event::mock() - .at_level(Level::TRACE) - .with_fields(field::mock("foo")), - ) - .event( - event::mock() - .at_level(Level::TRACE) - .with_fields(field::mock("bar")), - ) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - with_default(subscriber, || { - tracing::trace!(foo = 1); - tracing::trace!(bar = 3); - }); - - finished.assert_finished(); -} - -#[test] -fn same_num_fields_and_name_len() { - let filter: EnvFilter = "[foo{bar=1}]=trace,[baz{boz=1}]=trace" - .parse() - .expect("filter should parse"); - let (subscriber, finished) = subscriber::mock() - .new_span( - span::mock() - .named("foo") - .at_level(Level::TRACE) - .with_field(field::mock("bar")), - ) - .new_span( - span::mock() - .named("baz") - .at_level(Level::TRACE) - .with_field(field::mock("boz")), - ) - .done() - .run_with_handle(); - let subscriber = subscriber.with(filter); - with_default(subscriber, || { - tracing::trace_span!("foo", bar = 1); - tracing::trace_span!("baz", boz = 1); - }); - - finished.assert_finished(); -} diff --git a/vendor/tracing-subscriber/tests/support.rs b/vendor/tracing-subscriber/tests/support.rs deleted file mode 100644 index 50e0e6669..000000000 --- a/vendor/tracing-subscriber/tests/support.rs +++ /dev/null @@ -1,407 +0,0 @@ -#![allow(missing_docs, dead_code)] -pub use tracing_mock::{event, field, span, subscriber}; - -use tracing_core::{ - span::{Attributes, Id, Record}, - Event, Subscriber, -}; -use tracing_mock::{ - event::MockEvent, - span::{MockSpan, NewSpan}, - subscriber::{Expect, MockHandle}, -}; -use tracing_subscriber::{ - layer::{Context, Layer}, - registry::{LookupSpan, SpanRef}, -}; - -use std::{ - collections::VecDeque, - fmt, - sync::{Arc, Mutex}, -}; - -pub mod layer { - use super::ExpectLayerBuilder; - - pub fn mock() -> ExpectLayerBuilder { - ExpectLayerBuilder { - expected: Default::default(), - name: std::thread::current() - .name() - .map(String::from) - .unwrap_or_default(), - } - } - - pub fn named(name: impl std::fmt::Display) -> ExpectLayerBuilder { - mock().named(name) - } -} - -pub struct ExpectLayerBuilder { - expected: VecDeque, - name: String, -} - -pub struct ExpectLayer { - expected: Arc>>, - current: Mutex>, - name: String, -} - -impl ExpectLayerBuilder { - /// Overrides the name printed by the mock subscriber's debugging output. - /// - /// The debugging output is displayed if the test panics, or if the test is - /// run with `--nocapture`. - /// - /// By default, the mock subscriber's name is the name of the test - /// (*technically*, the name of the thread where it was created, which is - /// the name of the test unless tests are run with `--test-threads=1`). - /// When a test has only one mock subscriber, this is sufficient. However, - /// some tests may include multiple subscribers, in order to test - /// interactions between multiple subscribers. In that case, it can be - /// helpful to give each subscriber a separate name to distinguish where the - /// debugging output comes from. - pub fn named(mut self, name: impl fmt::Display) -> Self { - use std::fmt::Write; - if !self.name.is_empty() { - write!(&mut self.name, "::{}", name).unwrap(); - } else { - self.name = name.to_string(); - } - self - } - - pub fn enter(mut self, span: MockSpan) -> Self { - self.expected.push_back(Expect::Enter(span)); - self - } - - pub fn event(mut self, event: MockEvent) -> Self { - self.expected.push_back(Expect::Event(event)); - self - } - - pub fn exit(mut self, span: MockSpan) -> Self { - self.expected.push_back(Expect::Exit(span)); - self - } - - pub fn done(mut self) -> Self { - self.expected.push_back(Expect::Nothing); - self - } - - pub fn record(mut self, span: MockSpan, fields: I) -> Self - where - I: Into, - { - self.expected.push_back(Expect::Visit(span, fields.into())); - self - } - - pub fn new_span(mut self, new_span: I) -> Self - where - I: Into, - { - self.expected.push_back(Expect::NewSpan(new_span.into())); - self - } - - pub fn run(self) -> ExpectLayer { - ExpectLayer { - expected: Arc::new(Mutex::new(self.expected)), - name: self.name, - current: Mutex::new(Vec::new()), - } - } - - pub fn run_with_handle(self) -> (ExpectLayer, MockHandle) { - let expected = Arc::new(Mutex::new(self.expected)); - let handle = MockHandle::new(expected.clone(), self.name.clone()); - let layer = ExpectLayer { - expected, - name: self.name, - current: Mutex::new(Vec::new()), - }; - (layer, handle) - } -} - -impl ExpectLayer { - fn check_span_ref<'spans, S>( - &self, - expected: &MockSpan, - actual: &SpanRef<'spans, S>, - what_happened: impl fmt::Display, - ) where - S: LookupSpan<'spans>, - { - if let Some(exp_name) = expected.name() { - assert_eq!( - actual.name(), - exp_name, - "\n[{}] expected {} a span named {:?}\n\ - [{}] but it was named {:?} instead (span {} {:?})", - self.name, - what_happened, - exp_name, - self.name, - actual.name(), - actual.name(), - actual.id() - ); - } - - if let Some(exp_level) = expected.level() { - let actual_level = actual.metadata().level(); - assert_eq!( - actual_level, - &exp_level, - "\n[{}] expected {} a span at {:?}\n\ - [{}] but it was at {:?} instead (span {} {:?})", - self.name, - what_happened, - exp_level, - self.name, - actual_level, - actual.name(), - actual.id(), - ); - } - - if let Some(exp_target) = expected.target() { - let actual_target = actual.metadata().target(); - assert_eq!( - actual_target, - exp_target, - "\n[{}] expected {} a span with target {:?}\n\ - [{}] but it had the target {:?} instead (span {} {:?})", - self.name, - what_happened, - exp_target, - self.name, - actual_target, - actual.name(), - actual.id(), - ); - } - } -} - -impl Layer for ExpectLayer -where - S: Subscriber + for<'a> LookupSpan<'a>, -{ - fn register_callsite( - &self, - metadata: &'static tracing::Metadata<'static>, - ) -> tracing_core::Interest { - println!("[{}] register_callsite {:#?}", self.name, metadata); - tracing_core::Interest::always() - } - - fn on_record(&self, _: &Id, _: &Record<'_>, _: Context<'_, S>) { - unimplemented!( - "so far, we don't have any tests that need an `on_record` \ - implementation.\nif you just wrote one that does, feel free to \ - implement it!" - ); - } - - fn on_event(&self, event: &Event<'_>, cx: Context<'_, S>) { - let name = event.metadata().name(); - println!( - "[{}] event: {}; level: {}; target: {}", - self.name, - name, - event.metadata().level(), - event.metadata().target(), - ); - match self.expected.lock().unwrap().pop_front() { - None => {} - Some(Expect::Event(mut expected)) => { - let get_parent_name = || cx.event_span(event).map(|span| span.name().to_string()); - expected.check(event, get_parent_name, &self.name); - let mut current_scope = cx.event_scope(event).into_iter().flatten(); - let expected_scope = expected.scope_mut(); - let mut i = 0; - for (expected, actual) in expected_scope.iter_mut().zip(&mut current_scope) { - println!( - "[{}] event_scope[{}] actual={} ({:?}); expected={}", - self.name, - i, - actual.name(), - actual.id(), - expected - ); - self.check_span_ref( - expected, - &actual, - format_args!("the {}th span in the event's scope to be", i), - ); - i += 1; - } - let remaining_expected = &expected_scope[i..]; - assert!( - remaining_expected.is_empty(), - "\n[{}] did not observe all expected spans in event scope!\n[{}] missing: {:#?}", - self.name, - self.name, - remaining_expected, - ); - assert!( - current_scope.next().is_none(), - "\n[{}] did not expect all spans in the actual event scope!", - self.name, - ); - } - Some(ex) => ex.bad(&self.name, format_args!("observed event {:#?}", event)), - } - } - - fn on_follows_from(&self, _span: &Id, _follows: &Id, _: Context<'_, S>) { - // TODO: it should be possible to expect spans to follow from other spans - } - - fn on_new_span(&self, span: &Attributes<'_>, id: &Id, cx: Context<'_, S>) { - let meta = span.metadata(); - println!( - "[{}] new_span: name={:?}; target={:?}; id={:?};", - self.name, - meta.name(), - meta.target(), - id - ); - let mut expected = self.expected.lock().unwrap(); - let was_expected = matches!(expected.front(), Some(Expect::NewSpan(_))); - if was_expected { - if let Expect::NewSpan(mut expected) = expected.pop_front().unwrap() { - let get_parent_name = || { - span.parent() - .and_then(|id| cx.span(id)) - .or_else(|| cx.lookup_current()) - .map(|span| span.name().to_string()) - }; - expected.check(span, get_parent_name, &self.name); - } - } - } - - fn on_enter(&self, id: &Id, cx: Context<'_, S>) { - let span = cx - .span(id) - .unwrap_or_else(|| panic!("[{}] no span for ID {:?}", self.name, id)); - println!("[{}] enter: {}; id={:?};", self.name, span.name(), id); - match self.expected.lock().unwrap().pop_front() { - None => {} - Some(Expect::Enter(ref expected_span)) => { - self.check_span_ref(expected_span, &span, "to enter"); - } - Some(ex) => ex.bad(&self.name, format_args!("entered span {:?}", span.name())), - } - self.current.lock().unwrap().push(id.clone()); - } - - fn on_exit(&self, id: &Id, cx: Context<'_, S>) { - if std::thread::panicking() { - // `exit()` can be called in `drop` impls, so we must guard against - // double panics. - println!("[{}] exit {:?} while panicking", self.name, id); - return; - } - let span = cx - .span(id) - .unwrap_or_else(|| panic!("[{}] no span for ID {:?}", self.name, id)); - println!("[{}] exit: {}; id={:?};", self.name, span.name(), id); - match self.expected.lock().unwrap().pop_front() { - None => {} - Some(Expect::Exit(ref expected_span)) => { - self.check_span_ref(expected_span, &span, "to exit"); - let curr = self.current.lock().unwrap().pop(); - assert_eq!( - Some(id), - curr.as_ref(), - "[{}] exited span {:?}, but the current span was {:?}", - self.name, - span.name(), - curr.as_ref().and_then(|id| cx.span(id)).map(|s| s.name()) - ); - } - Some(ex) => ex.bad(&self.name, format_args!("exited span {:?}", span.name())), - }; - } - - fn on_close(&self, id: Id, cx: Context<'_, S>) { - if std::thread::panicking() { - // `try_close` can be called in `drop` impls, so we must guard against - // double panics. - println!("[{}] close {:?} while panicking", self.name, id); - return; - } - let span = cx.span(&id); - let name = span.as_ref().map(|span| { - println!("[{}] close_span: {}; id={:?};", self.name, span.name(), id,); - span.name() - }); - if name.is_none() { - println!("[{}] drop_span: id={:?}", self.name, id); - } - if let Ok(mut expected) = self.expected.try_lock() { - let was_expected = match expected.front() { - Some(Expect::DropSpan(ref expected_span)) => { - // Don't assert if this function was called while panicking, - // as failing the assertion can cause a double panic. - if !::std::thread::panicking() { - if let Some(ref span) = span { - self.check_span_ref(expected_span, span, "to close"); - } - } - true - } - Some(Expect::Event(_)) => { - if !::std::thread::panicking() { - panic!( - "[{}] expected an event, but dropped span {} (id={:?}) instead", - self.name, - name.unwrap_or(""), - id - ); - } - true - } - _ => false, - }; - if was_expected { - expected.pop_front(); - } - } - } - - fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>) { - panic!("well-behaved subscribers should never do this to us, lol"); - } -} - -impl fmt::Debug for ExpectLayer { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("ExpectLayer"); - s.field("name", &self.name); - - if let Ok(expected) = self.expected.try_lock() { - s.field("expected", &expected); - } else { - s.field("expected", &format_args!("")); - } - - if let Ok(current) = self.current.try_lock() { - s.field("current", &format_args!("{:?}", ¤t)); - } else { - s.field("current", &format_args!("")); - } - - s.finish() - } -} diff --git a/vendor/tracing-subscriber/tests/unhinted_layer_filters_dont_break_other_layers.rs b/vendor/tracing-subscriber/tests/unhinted_layer_filters_dont_break_other_layers.rs deleted file mode 100644 index 9fa5c6bd4..000000000 --- a/vendor/tracing-subscriber/tests/unhinted_layer_filters_dont_break_other_layers.rs +++ /dev/null @@ -1,123 +0,0 @@ -#![cfg(feature = "registry")] -mod support; -use self::support::*; -use tracing::Level; -use tracing_subscriber::{filter::DynFilterFn, prelude::*}; - -#[test] -fn layer_filters() { - let (unfiltered, unfiltered_handle) = unfiltered("unfiltered"); - let (filtered, filtered_handle) = filtered("filtered"); - - let _subscriber = tracing_subscriber::registry() - .with(unfiltered) - .with(filtered.with_filter(filter())) - .set_default(); - - events(); - - unfiltered_handle.assert_finished(); - filtered_handle.assert_finished(); -} - -#[test] -fn layered_layer_filters() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - let unfiltered = unfiltered1.and_then(unfiltered2); - - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - let filtered = filtered1 - .with_filter(filter()) - .and_then(filtered2.with_filter(filter())); - - let _subscriber = tracing_subscriber::registry() - .with(unfiltered) - .with(filtered) - .set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -#[test] -fn out_of_order() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - - let _subscriber = tracing_subscriber::registry() - .with(unfiltered1) - .with(filtered1.with_filter(filter())) - .with(unfiltered2) - .with(filtered2.with_filter(filter())) - .set_default(); - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -#[test] -fn mixed_layered() { - let (unfiltered1, unfiltered1_handle) = unfiltered("unfiltered_1"); - let (unfiltered2, unfiltered2_handle) = unfiltered("unfiltered_2"); - let (filtered1, filtered1_handle) = filtered("filtered_1"); - let (filtered2, filtered2_handle) = filtered("filtered_2"); - - let layered1 = filtered1.with_filter(filter()).and_then(unfiltered1); - let layered2 = unfiltered2.and_then(filtered2.with_filter(filter())); - - let _subscriber = tracing_subscriber::registry() - .with(layered1) - .with(layered2) - .set_default(); - - events(); - - unfiltered1_handle.assert_finished(); - unfiltered2_handle.assert_finished(); - filtered1_handle.assert_finished(); - filtered2_handle.assert_finished(); -} - -fn events() { - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); -} - -fn filter() -> DynFilterFn { - DynFilterFn::new(|metadata, _| metadata.level() <= &Level::INFO) -} - -fn unfiltered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(name) - .event(event::mock().at_level(Level::TRACE)) - .event(event::mock().at_level(Level::DEBUG)) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle() -} - -fn filtered(name: &str) -> (ExpectLayer, subscriber::MockHandle) { - layer::named(name) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle() -} diff --git a/vendor/tracing-subscriber/tests/utils.rs b/vendor/tracing-subscriber/tests/utils.rs deleted file mode 100644 index e95868d5e..000000000 --- a/vendor/tracing-subscriber/tests/utils.rs +++ /dev/null @@ -1,39 +0,0 @@ -#![cfg(feature = "std")] - -use tracing_mock::*; -use tracing_subscriber::prelude::*; - -#[test] -fn init_ext_works() { - let (subscriber, finished) = subscriber::mock() - .event( - event::mock() - .at_level(tracing::Level::INFO) - .with_target("init_works"), - ) - .done() - .run_with_handle(); - - let _guard = subscriber.set_default(); - tracing::info!(target: "init_works", "it worked!"); - finished.assert_finished(); -} - -#[test] -#[cfg(feature = "fmt")] -fn builders_are_init_ext() { - tracing_subscriber::fmt().set_default(); - let _ = tracing_subscriber::fmt() - .with_target(false) - .compact() - .try_init(); -} - -#[test] -#[cfg(all(feature = "fmt", feature = "env-filter"))] -fn layered_is_init_ext() { - tracing_subscriber::registry() - .with(tracing_subscriber::fmt::layer()) - .with(tracing_subscriber::EnvFilter::new("foo=info")) - .set_default(); -} diff --git a/vendor/tracing-subscriber/tests/vec.rs b/vendor/tracing-subscriber/tests/vec.rs deleted file mode 100644 index 92abf0bff..000000000 --- a/vendor/tracing-subscriber/tests/vec.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![cfg(feature = "registry")] -use tracing::level_filters::LevelFilter; -use tracing::Subscriber; -use tracing_subscriber::prelude::*; - -#[test] -fn just_empty_vec() { - // Just a None means everything is off - let subscriber = tracing_subscriber::registry().with(Vec::::new()); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::OFF)); -} - -#[test] -fn layer_and_empty_vec() { - let subscriber = tracing_subscriber::registry() - .with(LevelFilter::INFO) - .with(Vec::::new()); - assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::INFO)); -} diff --git a/vendor/tracing-subscriber/tests/vec_subscriber_filter_interests_cached.rs b/vendor/tracing-subscriber/tests/vec_subscriber_filter_interests_cached.rs deleted file mode 100644 index 10467cb7d..000000000 --- a/vendor/tracing-subscriber/tests/vec_subscriber_filter_interests_cached.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![cfg(feature = "registry")] -mod support; -use self::support::*; - -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; -use tracing::{Level, Subscriber}; -use tracing_subscriber::{filter, prelude::*}; - -#[test] -fn vec_layer_filter_interests_are_cached() { - let mk_filtered = |level: Level, subscriber: ExpectLayer| { - let seen = Arc::new(Mutex::new(HashMap::new())); - let filter = filter::filter_fn({ - let seen = seen.clone(); - move |meta| { - *seen.lock().unwrap().entry(*meta.level()).or_insert(0usize) += 1; - meta.level() <= &level - } - }); - (subscriber.with_filter(filter).boxed(), seen) - }; - - // This layer will return Interest::always for INFO and lower. - let (info_layer, info_handle) = layer::named("info") - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::INFO)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - let (info_layer, seen_info) = mk_filtered(Level::INFO, info_layer); - - // This layer will return Interest::always for WARN and lower. - let (warn_layer, warn_handle) = layer::named("warn") - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .event(event::mock().at_level(Level::WARN)) - .event(event::mock().at_level(Level::ERROR)) - .done() - .run_with_handle(); - let (warn_layer, seen_warn) = mk_filtered(Level::WARN, warn_layer); - - let subscriber = tracing_subscriber::registry().with(vec![warn_layer, info_layer]); - assert!(subscriber.max_level_hint().is_none()); - - let _subscriber = subscriber.set_default(); - - fn events() { - tracing::trace!("hello trace"); - tracing::debug!("hello debug"); - tracing::info!("hello info"); - tracing::warn!("hello warn"); - tracing::error!("hello error"); - } - - events(); - { - let lock = seen_info.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the INFO subscriber (after first set of events)", - level - ); - } - - let lock = seen_warn.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the WARN subscriber (after first set of events)", - level - ); - } - } - - events(); - { - let lock = seen_info.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the INFO subscriber (after second set of events)", - level - ); - } - - let lock = seen_warn.lock().unwrap(); - for (&level, &count) in lock.iter() { - if level == Level::INFO { - continue; - } - assert_eq!( - count, 1, - "level {:?} should have been seen 1 time by the WARN subscriber (after second set of events)", - level - ); - } - } - - info_handle.assert_finished(); - warn_handle.assert_finished(); -} diff --git a/vendor/tracing/.cargo-checksum.json b/vendor/tracing/.cargo-checksum.json index 7b9d07340..8bfa395bb 100644 --- a/vendor/tracing/.cargo-checksum.json +++ b/vendor/tracing/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"dc3017cca8de9a33d8e0c3cba87b3977b1c84e1fe16ff87bc36614572ddd5832","Cargo.toml":"e4ffa43825ed68447646e39babd364b737b1353f95a7a6baa995879ad282952d","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"2a2ff5fa337287734c28e856a185afbced4cd656791a1aaeef0b982784e601d7","benches/baseline.rs":"43a3e31b6c33dba2e6328052301b707b212487b83f0dcffc843061a9c48a2319","benches/dispatch_get_clone.rs":"866239abeb74a82440741c948a4e7e0a44e92e8cc87319ec57e3b057c9e8f5dd","benches/dispatch_get_ref.rs":"dd2803259a6784c256304e676bbce05de233e4c8451ac85863787213343e9be7","benches/empty_span.rs":"9f51cf376414ea751b2f50c357f2435a545d606118286f5b8b89f185e28aad8c","benches/enter_span.rs":"4410ec73d277e7b54e9f306c00ff3b79a150d1832966b7fc29984c8e3ad8d57c","benches/event.rs":"98de3c82ed18abe0a3cbe6eda9a4f9deec2b69bca42c3aac11dea4b608b85a67","benches/shared.rs":"2623311af7d153685064e664a5903d03e7dc3179754c324f3a76f29f060515e6","benches/span_fields.rs":"9166cd43ef2783e5419dd61ea57a02e48e8cc38aa1b357e9b79fa581929b60d8","benches/span_no_fields.rs":"79cc4befacf27d7ce728246087c4f06a6066f913e831d9043caeb7941f0193f6","benches/span_repeated.rs":"e4b3c99a7a9fc15d9042b8db399a56cf647b4eebd26f29d95325bb057b68330b","src/dispatcher.rs":"a8158e1901c50dc83d2f15b1773e6b9e31985d9af65e460be52dbf8be6874cd2","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"c7edb1602b2e9d164bc90f9d0dff48abb2fad840c07c6283481255fbe5d321e6","src/macros.rs":"f1a83930cea322f1f2000548d91800c22a9e28d2daf3f178c7c7c3ac8da5a02d","src/span.rs":"372695b3eda8354a892316826d2598f821fcb835fb18e1e0271767bce730b7ad","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"8933d8766439f929c0a98a0863d20aff37b221314b3825edd9058be511149968","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"7678d1cc8a29ae8b716fbddb7cc4836422732ba3dce109ff511c8bb6100da606","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"} \ No newline at end of file +{"files":{"CHANGELOG.md":"dc8a552611986799a0eebb56fd119ea8ae32c9b8da4be9914fe127627ad4f38a","Cargo.toml":"f8d12a05bc7ed5cfef787db206c05cc5ebcd2c165e6e629b613d1a3ff4f138de","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"6ff17749109fbe0855220188015846f40d3997bc2631c3163496c183c0bd50ce","benches/baseline.rs":"43a3e31b6c33dba2e6328052301b707b212487b83f0dcffc843061a9c48a2319","benches/dispatch_get_clone.rs":"866239abeb74a82440741c948a4e7e0a44e92e8cc87319ec57e3b057c9e8f5dd","benches/dispatch_get_ref.rs":"dd2803259a6784c256304e676bbce05de233e4c8451ac85863787213343e9be7","benches/empty_span.rs":"9f51cf376414ea751b2f50c357f2435a545d606118286f5b8b89f185e28aad8c","benches/enter_span.rs":"4410ec73d277e7b54e9f306c00ff3b79a150d1832966b7fc29984c8e3ad8d57c","benches/event.rs":"98de3c82ed18abe0a3cbe6eda9a4f9deec2b69bca42c3aac11dea4b608b85a67","benches/shared.rs":"2623311af7d153685064e664a5903d03e7dc3179754c324f3a76f29f060515e6","benches/span_fields.rs":"9166cd43ef2783e5419dd61ea57a02e48e8cc38aa1b357e9b79fa581929b60d8","benches/span_no_fields.rs":"79cc4befacf27d7ce728246087c4f06a6066f913e831d9043caeb7941f0193f6","benches/span_repeated.rs":"e4b3c99a7a9fc15d9042b8db399a56cf647b4eebd26f29d95325bb057b68330b","src/dispatcher.rs":"a8732392ffe56b1178f8fd3d6e6e02d40b51475c38bb4600abd9cd170df1bf6c","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"325d0d9487ecd646a7e5e22617f5f291c4112e0e7e359e0033de1677217c5b22","src/macros.rs":"1b38906bcb32cad50b60d350c88f6f4f1fa4d46d99bf50318c44d75219760c42","src/span.rs":"372695b3eda8354a892316826d2598f821fcb835fb18e1e0271767bce730b7ad","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"8933d8766439f929c0a98a0863d20aff37b221314b3825edd9058be511149968","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"7678d1cc8a29ae8b716fbddb7cc4836422732ba3dce109ff511c8bb6100da606","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"} \ No newline at end of file diff --git a/vendor/tracing/CHANGELOG.md b/vendor/tracing/CHANGELOG.md index 8b7d58808..978e0ca55 100644 --- a/vendor/tracing/CHANGELOG.md +++ b/vendor/tracing/CHANGELOG.md @@ -1,3 +1,55 @@ +# 0.1.37 (October 6, 2022) + +This release of `tracing` incorporates changes from `tracing-core` +[v0.1.30][core-0.1.30] and `tracing-attributes` [v0.1.23][attrs-0.1.23], +including the new `Subscriber::on_register_dispatch` method for performing late +initialization after a `Subscriber` is registered as a `Dispatch`, and bugfixes +for the `#[instrument]` attribute. Additionally, it fixes instances of the +`bare_trait_objects` lint, which is now a warning on `tracing`'s MSRV and will +become an error in the next edition. + +### Fixed + +- **attributes**: Incorrect handling of inner attributes in `#[instrument]`ed + functions ([#2307]) +- **attributes**: Incorrect location of compiler diagnostic spans generated for + type errors in `#[instrument]`ed `async fn`s ([#2270]) +- **attributes**: Updated `syn` dependency to fix compilation with `-Z + minimal-versions` ([#2246]) +- `bare_trait_objects` warning in `valueset!` macro expansion ([#2308]) + +### Added + +- **core**: `Subscriber::on_register_dispatch` method ([#2269]) +- **core**: `WeakDispatch` type and `Dispatch::downgrade()` function ([#2293]) + +### Changed + +- `tracing-core`: updated to [0.1.30][core-0.1.30] +- `tracing-attributes`: updated to [0.1.23][attrs-0.1.23] + +### Documented + +- Added [`tracing-web`] and [`reqwest-tracing`] to related crates ([#2283], + [#2331]) + +Thanks to new contributors @compiler-errors, @e-nomem, @WorldSEnder, @Xiami2012, +and @tl-rodrigo-gryzinski, as well as @jswrenn and @CAD97, for contributing to +this release! + +[core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30 +[attrs-0.1.23]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.23 +[`tracing-web`]: https://crates.io/crates/tracing-web/ +[`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing/ +[#2246]: https://github.com/tokio-rs/tracing/pull/2246 +[#2269]: https://github.com/tokio-rs/tracing/pull/2269 +[#2283]: https://github.com/tokio-rs/tracing/pull/2283 +[#2270]: https://github.com/tokio-rs/tracing/pull/2270 +[#2293]: https://github.com/tokio-rs/tracing/pull/2293 +[#2307]: https://github.com/tokio-rs/tracing/pull/2307 +[#2308]: https://github.com/tokio-rs/tracing/pull/2308 +[#2331]: https://github.com/tokio-rs/tracing/pull/2331 + # 0.1.36 (July 29, 2022) This release adds support for owned values and fat pointers as arguments to the diff --git a/vendor/tracing/Cargo.toml b/vendor/tracing/Cargo.toml index 9b4b5fa80..90f084d8e 100644 --- a/vendor/tracing/Cargo.toml +++ b/vendor/tracing/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.49.0" name = "tracing" -version = "0.1.36" +version = "0.1.37" authors = [ "Eliza Weisman ", "Tokio Contributors ", @@ -98,11 +98,11 @@ optional = true version = "0.2.9" [dependencies.tracing-attributes] -version = "0.1.22" +version = "0.1.23" optional = true [dependencies.tracing-core] -version = "0.1.29" +version = "0.1.30" default-features = false [dev-dependencies.criterion] diff --git a/vendor/tracing/README.md b/vendor/tracing/README.md index 16e671e05..694734577 100644 --- a/vendor/tracing/README.md +++ b/vendor/tracing/README.md @@ -250,7 +250,7 @@ my_future is as long as the future's. The second, and preferred, option is through the -[`#[instrument]`](https://docs.rs/tracing/0.1.36/tracing/attr.instrument.html) +[`#[instrument]`](https://docs.rs/tracing/0.1.37/tracing/attr.instrument.html) attribute: ```rust @@ -297,7 +297,7 @@ span.in_scope(|| { // Dropping the span will close it, indicating that it has ended. ``` -The [`#[instrument]`](https://docs.rs/tracing/0.1.36/tracing/attr.instrument.html) attribute macro +The [`#[instrument]`](https://docs.rs/tracing/0.1.37/tracing/attr.instrument.html) attribute macro can reduce some of this boilerplate: ```rust diff --git a/vendor/tracing/src/dispatcher.rs b/vendor/tracing/src/dispatcher.rs index 8817ac033..a84b99f4e 100644 --- a/vendor/tracing/src/dispatcher.rs +++ b/vendor/tracing/src/dispatcher.rs @@ -133,7 +133,7 @@ pub use tracing_core::dispatcher::with_default; #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub use tracing_core::dispatcher::DefaultGuard; pub use tracing_core::dispatcher::{ - get_default, set_global_default, Dispatch, SetGlobalDefaultError, + get_default, set_global_default, Dispatch, SetGlobalDefaultError, WeakDispatch, }; /// Private API for internal use by tracing's macros. diff --git a/vendor/tracing/src/lib.rs b/vendor/tracing/src/lib.rs index 7d60c7721..342e04a82 100644 --- a/vendor/tracing/src/lib.rs +++ b/vendor/tracing/src/lib.rs @@ -727,6 +727,8 @@ //! in [bunyan] format, enriched with timing information. //! - [`tracing-wasm`] provides a `Subscriber`/`Layer` implementation that reports //! events and spans via browser `console.log` and [User Timing API (`window.performance`)]. +//! - [`tracing-web`] provides a layer implementation of level-aware logging of events +//! to web browsers' `console.*` and span events to the [User Timing API (`window.performance`)]. //! - [`tide-tracing`] provides a [tide] middleware to trace all incoming requests and responses. //! - [`test-log`] takes care of initializing `tracing` for tests, based on //! environment variables with an `env_logger` compatible syntax. @@ -744,6 +746,7 @@ //! grouping together logs from the same spans during writing. //! - [`tracing-loki`] provides a layer for shipping logs to [Grafana Loki]. //! - [`tracing-logfmt`] provides a layer that formats events and spans into the logfmt format. +//! - [`reqwest-tracing`] provides a middleware to trace [`reqwest`] HTTP requests. //! //! If you're the maintainer of a `tracing` ecosystem crate not listed above, //! please let us know! We'd love to add your project to the list! @@ -761,6 +764,7 @@ //! [`tracing-bunyan-formatter`]: https://crates.io/crates/tracing-bunyan-formatter //! [bunyan]: https://github.com/trentm/node-bunyan //! [`tracing-wasm`]: https://docs.rs/tracing-wasm +//! [`tracing-web`]: https://docs.rs/tracing-web //! [User Timing API (`window.performance`)]: https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API //! [`tide-tracing`]: https://crates.io/crates/tide-tracing //! [tide]: https://crates.io/crates/tide @@ -781,6 +785,8 @@ //! [`tracing-loki`]: https://crates.io/crates/tracing-loki //! [Grafana Loki]: https://grafana.com/oss/loki/ //! [`tracing-logfmt`]: https://crates.io/crates/tracing-logfmt +//! [`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing +//! [`reqwest`]: https://crates.io/crates/reqwest //! //!
 //!     Note: Some of these ecosystem crates are currently
@@ -811,7 +817,7 @@
 //!
 //!   ```toml
 //!   [dependencies]
-//!   tracing = { version = "0.1.36", default-features = false }
+//!   tracing = { version = "0.1.37", default-features = false }
 //!   ```
 //!
 //! 
@@ -894,7 +900,7 @@
 //! [flags]: #crate-feature-flags
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
-#![doc(html_root_url = "https://docs.rs/tracing/0.1.36")]
+#![doc(html_root_url = "https://docs.rs/tracing/0.1.37")]
 #![doc(
     html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
     issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
diff --git a/vendor/tracing/src/macros.rs b/vendor/tracing/src/macros.rs
index b134af6e8..f3968e5c1 100644
--- a/vendor/tracing/src/macros.rs
+++ b/vendor/tracing/src/macros.rs
@@ -2193,79 +2193,79 @@ macro_rules! valueset {
     // };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = ?$val:expr, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&debug(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = %$val:expr, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&display(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = $val:expr, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&$val as &Value)) },
+            @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&$($k).+ as &Value)) },
+            @ { $($out),*, (&$next, Some(&$($k).+ as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, ?$($k:ident).+, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&debug(&$($k).+) as &Value)) },
+            @ { $($out),*, (&$next, Some(&debug(&$($k).+) as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, %$($k:ident).+, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&display(&$($k).+) as &Value)) },
+            @ { $($out),*, (&$next, Some(&display(&$($k).+) as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = ?$val:expr) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&debug(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = %$val:expr) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&display(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = $val:expr) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&$val as &Value)) },
+            @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&$($k).+ as &Value)) },
+            @ { $($out),*, (&$next, Some(&$($k).+ as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, ?$($k:ident).+) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&debug(&$($k).+) as &Value)) },
+            @ { $($out),*, (&$next, Some(&debug(&$($k).+) as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, %$($k:ident).+) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&display(&$($k).+) as &Value)) },
+            @ { $($out),*, (&$next, Some(&display(&$($k).+) as &dyn Value)) },
             $next,
         )
     };
@@ -2273,47 +2273,47 @@ macro_rules! valueset {
     // Handle literal names
     (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = ?$val:expr, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&debug(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = %$val:expr, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&display(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = $val:expr, $($rest:tt)*) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&$val as &Value)) },
+            @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
             $next,
             $($rest)*
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = ?$val:expr) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&debug(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = %$val:expr) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&display(&$val) as &Value)) },
+            @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
             $next,
         )
     };
     (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = $val:expr) => {
         $crate::valueset!(
-            @ { $($out),*, (&$next, Some(&$val as &Value)) },
+            @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
             $next,
         )
     };
 
     // Remainder is unparseable, but exists --- must be format args!
     (@ { $(,)* $($out:expr),* }, $next:expr, $($rest:tt)+) => {
-        $crate::valueset!(@ { (&$next, Some(&format_args!($($rest)+) as &Value)), $($out),* }, $next, )
+        $crate::valueset!(@ { (&$next, Some(&format_args!($($rest)+) as &dyn Value)), $($out),* }, $next, )
     };
 
     // === entry ===
diff --git a/vendor/unicode-ident/.cargo-checksum.json b/vendor/unicode-ident/.cargo-checksum.json
index 8066cd8bc..1fcb95c86 100644
--- a/vendor/unicode-ident/.cargo-checksum.json
+++ b/vendor/unicode-ident/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"43a169366c8f04f5c100d7b1a29fbe9f4d50ff5a019d72761be6c949f259333a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"31a16b16a84da0ccaaeb16b1a4c70d89592d12de5c139053f724dbac91bdd40c","benches/xid.rs":"a61f61ecc7d5124c759cdeb55ab74470ab69f2f3ca37613da65f16e0e5e33487","src/lib.rs":"d0030259a628125669ad6c02d3eb791526e6d6ae35d8a858a87f90245162666c","src/tables.rs":"887457a7ce0d2fff750b40134de684e86d3999e5d191544f31ee45936b7bcb72","tests/compare.rs":"89c4dc4f745064a9f734667b1d960596a10b8cb019a8ed1c5b9512678a866ad5","tests/fst/mod.rs":"69a3aaf59acd8bca962ecc6234be56be8c0934ab79b253162f10eb881523901f","tests/fst/xid_continue.fst":"6e079a81175e445461dc330f61294c9f24bdb1681b7a591999fbb4547766ea99","tests/fst/xid_start.fst":"382fc736b472d09052a53c89cc2060bd839792350c6d22638b91e9123bf14540","tests/roaring/mod.rs":"784f65a48477fab7549620c7843c7ad6da533f69a18abca1172f6acb95045e53","tests/static_size.rs":"3974f6948c06d60b63738ddf5688478144718da87ccfdc4af6918d76a0bd9f06","tests/trie/mod.rs":"d4acbb716bcbaf80660039797f45e138ed8bbd66749fa3b19b1a971574679cc9","tests/trie/trie.rs":"6780e33f74f86131aa32f321bc3c77c4d9b526b708e82db64b198dce4c86429b"},"package":"5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"}
\ No newline at end of file
+{"files":{"Cargo.toml":"4589e7f695ce2ae3c0dbb7a79647d044b8f2ef71183bf478fe01922966c54556","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","LICENSE-UNICODE":"68f5b9f5ea36881a0942ba02f558e9e1faf76cc09cb165ad801744c61b738844","README.md":"3dc1793fcaf87c77c5ed467c4a76cb696883f2f4329c011a869fbd34c4404382","benches/xid.rs":"a61f61ecc7d5124c759cdeb55ab74470ab69f2f3ca37613da65f16e0e5e33487","src/lib.rs":"d0030259a628125669ad6c02d3eb791526e6d6ae35d8a858a87f90245162666c","src/tables.rs":"4a84cc7a1a391abebe5672db993c519b9f8fe462690d7e5a8bdd43be8481c10b","tests/compare.rs":"89c4dc4f745064a9f734667b1d960596a10b8cb019a8ed1c5b9512678a866ad5","tests/fst/mod.rs":"69a3aaf59acd8bca962ecc6234be56be8c0934ab79b253162f10eb881523901f","tests/fst/xid_continue.fst":"0624500413ac318fee8424eecdad70397f911e3beae52231bfca295bb1bb9e04","tests/fst/xid_start.fst":"cc36f4f1149a4004ea7e2075cfb54756328b571946fda526be508cf5ed53dbdb","tests/roaring/mod.rs":"784f65a48477fab7549620c7843c7ad6da533f69a18abca1172f6acb95045e53","tests/static_size.rs":"6686edc08a6718cb4be03916b87a2594a2d2f2c779dbac6372fd27d5d7f7d8b6","tests/trie/mod.rs":"d4acbb716bcbaf80660039797f45e138ed8bbd66749fa3b19b1a971574679cc9","tests/trie/trie.rs":"dbd7de5fe601159643a4c6febed06793f812e8d71010b0ec78f2557353a976b2"},"package":"6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"}
\ No newline at end of file
diff --git a/vendor/unicode-ident/Cargo.toml b/vendor/unicode-ident/Cargo.toml
index bb1171eaa..03e1871fc 100644
--- a/vendor/unicode-ident/Cargo.toml
+++ b/vendor/unicode-ident/Cargo.toml
@@ -13,12 +13,20 @@
 edition = "2018"
 rust-version = "1.31"
 name = "unicode-ident"
-version = "1.0.1"
+version = "1.0.5"
 authors = ["David Tolnay "]
 description = "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31"
 documentation = "https://docs.rs/unicode-ident"
 readme = "README.md"
-license = "MIT OR Apache-2.0"
+keywords = [
+    "unicode",
+    "xid",
+]
+categories = [
+    "development-tools::procedural-macro-helpers",
+    "no-std",
+]
+license = "(MIT OR Apache-2.0) AND Unicode-DFS-2016"
 repository = "https://github.com/dtolnay/unicode-ident"
 
 [package.metadata.docs.rs]
@@ -29,7 +37,7 @@ name = "xid"
 harness = false
 
 [dev-dependencies.criterion]
-version = "0.3"
+version = "0.4"
 default-features = false
 
 [dev-dependencies.fst]
@@ -40,11 +48,11 @@ version = "0.8"
 features = ["small_rng"]
 
 [dev-dependencies.roaring]
-version = "0.9"
+version = "0.10"
 
 [dev-dependencies.ucd-trie]
 version = "0.1"
 default-features = false
 
 [dev-dependencies.unicode-xid]
-version = "0.2"
+version = "0.2.4"
diff --git a/vendor/unicode-ident/LICENSE-UNICODE b/vendor/unicode-ident/LICENSE-UNICODE
new file mode 100644
index 000000000..85d0d580d
--- /dev/null
+++ b/vendor/unicode-ident/LICENSE-UNICODE
@@ -0,0 +1,46 @@
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+
+See Terms of Use 
+for definitions of Unicode Inc.’s Data Files and Software.
+
+NOTICE TO USER: Carefully read the following legal agreement.
+BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
+DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
+YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+TERMS AND CONDITIONS OF THIS AGREEMENT.
+IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
+THE DATA FILES OR SOFTWARE.
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright © 1991-2022 Unicode, Inc. All rights reserved.
+Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Unicode data files and any associated documentation
+(the "Data Files") or Unicode software and any associated documentation
+(the "Software") to deal in the Data Files or Software
+without restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, and/or sell copies of
+the Data Files or Software, and to permit persons to whom the Data Files
+or Software are furnished to do so, provided that either
+(a) this copyright and permission notice appear with all copies
+of the Data Files or Software, or
+(b) this copyright and permission notice appear in associated
+Documentation.
+
+THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in these Data Files or Software without prior
+written authorization of the copyright holder.
diff --git a/vendor/unicode-ident/README.md b/vendor/unicode-ident/README.md
index 4acefdb05..6c590b06c 100644
--- a/vendor/unicode-ident/README.md
+++ b/vendor/unicode-ident/README.md
@@ -41,10 +41,10 @@ different ratios of ASCII to non-ASCII codepoints in the input data.
 
 | | static storage | 0% nonascii | 1% | 10% | 100% nonascii |
 |---|---|---|---|---|---|
-| **`unicode-ident`** | 9.75 K | 0.96 ns | 0.95 ns | 1.09 ns | 1.55 ns |
-| **`unicode-xid`** | 11.34 K | 1.88 ns | 2.14 ns | 3.48 ns | 15.63 ns |
-| **`ucd-trie`** | 9.95 K | 1.29 ns | 1.28 ns | 1.36 ns | 2.15 ns |
-| **`fst`** | 133 K | 55.1 ns | 54.9 ns | 53.2 ns | 28.5 ns |
+| **`unicode-ident`** | 10.0 K | 0.96 ns | 0.95 ns | 1.09 ns | 1.55 ns |
+| **`unicode-xid`** | 11.5 K | 1.88 ns | 2.14 ns | 3.48 ns | 15.63 ns |
+| **`ucd-trie`** | 10.2 K | 1.29 ns | 1.28 ns | 1.36 ns | 2.15 ns |
+| **`fst`** | 138 K | 55.1 ns | 54.9 ns | 53.2 ns | 28.5 ns |
 | **`roaring`** | 66.1 K | 2.78 ns | 3.09 ns | 3.37 ns | 4.70 ns |
 
 Source code for the benchmark is provided in the *bench* directory of this repo
@@ -263,15 +263,21 @@ is_xid_start:
 
 ## License
 
-
-Licensed under either of Apache License, Version
-2.0 or MIT license at your option.
-
+Use of the Unicode Character Database, as this crate does, is governed by the Unicode License Agreement – Data Files and Software
+(2016).
 
-
+All intellectual property within this crate that is **not generated** using the +Unicode Character Database as input is licensed under either of Apache License, Version 2.0 or MIT license at your option. + +The **generated** files incorporate tabular data derived from the Unicode +Character Database, together with intellectual property from the original source +code content of the crate. One must comply with the terms of both the Unicode +License Agreement and either of the Apache license or MIT license when those +generated files are involved. - Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. - +be licensed as just described, without any additional terms or conditions. diff --git a/vendor/unicode-ident/src/tables.rs b/vendor/unicode-ident/src/tables.rs index a697636b6..380c798d1 100644 --- a/vendor/unicode-ident/src/tables.rs +++ b/vendor/unicode-ident/src/tables.rs @@ -28,7 +28,7 @@ pub(crate) static ASCII_CONTINUE: Align64<[bool; 128]> = Align64([ pub(crate) const CHUNK: usize = 64; -pub(crate) static TRIE_START: Align8<[u8; 394]> = Align8([ +pub(crate) static TRIE_START: Align8<[u8; 402]> = Align8([ 0x04, 0x0B, 0x0F, 0x13, 0x17, 0x1B, 0x1F, 0x23, 0x27, 0x2D, 0x31, 0x34, 0x38, 0x3C, 0x40, 0x02, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, @@ -39,21 +39,22 @@ pub(crate) static TRIE_START: Align8<[u8; 394]> = Align8([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x64, 0x66, 0x6A, 0x6E, 0x72, 0x28, 0x76, 0x78, 0x7C, 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9E, 0xA2, 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0xAE, 0x00, 0xB2, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xC6, 0x00, 0x00, 0x00, 0xB9, - 0xBC, 0xCF, 0x00, 0xBF, 0xD3, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xB1, 0x00, 0xB5, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC8, 0x00, 0x00, 0x00, 0xAF, + 0xCE, 0xD2, 0xD6, 0xBC, 0xDA, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0xD9, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xDC, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xDF, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xE1, 0x00, 0x00, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xDD, + 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xE9, 0x00, 0x00, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0xE7, ]); pub(crate) static TRIE_CONTINUE: Align8<[u8; 1793]> = Align8([ @@ -66,23 +67,23 @@ pub(crate) static TRIE_CONTINUE: Align8<[u8; 1793]> = Align8([ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x64, 0x68, 0x6C, 0x70, 0x74, 0x28, 0x76, 0x7A, 0x7E, 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9B, 0xA0, 0xA4, - 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x00, 0xB4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, 0xC1, 0xC4, 0xC8, 0x00, 0xCA, 0x00, 0xB9, - 0xCD, 0xD1, 0x00, 0xBF, 0xD5, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x00, 0x00, + 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xB3, 0x00, 0xB7, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, 0xC4, 0xC6, 0xCA, 0x00, 0xCC, 0x00, 0xAF, + 0xD0, 0xD4, 0xD8, 0xBC, 0xDC, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0xD9, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xDC, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xDF, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xE1, 0x00, 0x00, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xE9, 0x00, 0x00, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -169,10 +170,10 @@ pub(crate) static TRIE_CONTINUE: Align8<[u8; 1793]> = Align8([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xCB, + 0xC2, ]); -pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ +pub(crate) static LEAF: Align64<[u8; 7520]> = Align64([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -240,7 +241,7 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xF0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00, 0x40, 0x70, 0x80, 0x03, 0x00, 0x00, 0xFC, 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0x3D, 0x60, 0x27, 0xCF, 0xFF, 0x00, 0x00, - 0xEF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0xF3, 0xDF, 0x3D, 0x60, 0x60, 0xCF, 0xFF, 0x06, 0x00, + 0xEF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0xF3, 0xDF, 0x3D, 0x60, 0x60, 0xCF, 0xFF, 0x0E, 0x00, 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7D, 0xF0, 0x80, 0xCF, 0xFF, 0x00, 0xFC, 0xEE, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x84, 0x5F, 0xFF, 0xC0, 0xFF, 0x0C, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -248,7 +249,7 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x7F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, - 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0x3F, 0x5F, 0x3F, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, + 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0x3F, 0x5F, 0x7F, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xFF, 0x03, 0xA0, 0xC2, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0xFE, 0xFF, 0xDF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x80, 0x00, 0x00, 0x3F, 0x3C, 0x62, 0xC0, 0xE1, 0xFF, @@ -309,7 +310,7 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xF0, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -339,7 +340,7 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, @@ -434,7 +435,7 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, @@ -445,11 +446,11 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xDE, 0xFF, 0x17, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x0F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x03, 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xFB, 0x9F, 0x39, 0x81, 0xE0, 0xCF, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -499,28 +500,34 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0x7F, 0xFB, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF4, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x07, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE3, 0x07, 0xF8, 0xE7, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xE0, @@ -545,26 +552,24 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x6F, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F, 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x3F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F, 0xFF, 0x01, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x6F, 0xFF, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x64, 0xDE, 0xFF, 0xEB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xE7, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0x7B, 0x5F, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -581,10 +586,12 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0x10, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xF9, 0xDB, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x3F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xF9, 0xDB, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -595,6 +602,14 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -617,12 +632,14 @@ pub(crate) static LEAF: Align64<[u8; 7264]> = Align64([ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/vendor/unicode-ident/tests/fst/xid_continue.fst b/vendor/unicode-ident/tests/fst/xid_continue.fst index 5359051cb..05e7b1aa2 100644 Binary files a/vendor/unicode-ident/tests/fst/xid_continue.fst and b/vendor/unicode-ident/tests/fst/xid_continue.fst differ diff --git a/vendor/unicode-ident/tests/fst/xid_start.fst b/vendor/unicode-ident/tests/fst/xid_start.fst index 5c2e43fac..a5975b67e 100644 Binary files a/vendor/unicode-ident/tests/fst/xid_start.fst and b/vendor/unicode-ident/tests/fst/xid_start.fst differ diff --git a/vendor/unicode-ident/tests/static_size.rs b/vendor/unicode-ident/tests/static_size.rs index f0e04d4db..df65f45dd 100644 --- a/vendor/unicode-ident/tests/static_size.rs +++ b/vendor/unicode-ident/tests/static_size.rs @@ -13,7 +13,7 @@ fn test_size() { + size_of_val(&tables::TRIE_START) + size_of_val(&tables::TRIE_CONTINUE) + size_of_val(&tables::LEAF); - assert_eq!(9752, size); + assert_eq!(10016, size); } #[test] @@ -24,7 +24,7 @@ fn test_xid_size() { mod ucd; let size = size_of_val(ucd::XID_START) + size_of_val(ucd::XID_CONTINUE); - assert_eq!(11344, size); + assert_eq!(11528, size); let _ = ucd::BY_NAME; } @@ -71,7 +71,7 @@ fn test_trieset_size() { + size_of_val(tree3_level2) + size_of_val(tree3_level3); - assert_eq!(9952, start_size + continue_size); + assert_eq!(10208, start_size + continue_size); let _ = trie::BY_NAME; } @@ -81,7 +81,7 @@ fn test_fst_size() { let xid_start_fst = include_bytes!("fst/xid_start.fst"); let xid_continue_fst = include_bytes!("fst/xid_continue.fst"); let size = xid_start_fst.len() + xid_continue_fst.len(); - assert_eq!(132897, size); + assert_eq!(137749, size); } #[test] diff --git a/vendor/unicode-ident/tests/trie/trie.rs b/vendor/unicode-ident/tests/trie/trie.rs index 7f7a14f31..821e7cb0f 100644 --- a/vendor/unicode-ident/tests/trie/trie.rs +++ b/vendor/unicode-ident/tests/trie/trie.rs @@ -2,9 +2,9 @@ // // ucd-generate property-bool UCD --include XID_Start,XID_Continue --trie-set // -// Unicode version: 14.0.0. +// Unicode version: 15.0.0. // -// ucd-generate 0.2.10 is available on crates.io. +// ucd-generate 0.2.13 is available on crates.io. pub const BY_NAME: &'static [(&'static str, &'static ::ucd_trie::TrieSet)] = &[ ("XID_Continue", XID_CONTINUE), ("XID_Start", XID_START), @@ -77,10 +77,10 @@ pub const XID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet { 0xF3C5FDFFFFF99FEF, 0x5003FFCFB080799F, 0xD36DFDFFFFF987EE, 0x3FFFC05E023987, 0xF3EDFDFFFFFBBFEE, 0xFE00FFCF00013BBF, 0xF3EDFDFFFFF99FEE, 0x2FFCFB0E0399F, 0xC3FFC718D63DC7EC, 0xFFC000813DC7, - 0xF3FFFDFFFFFDDFFF, 0xFFCF27603DDF, 0xF3EFFDFFFFFDDFEF, 0x6FFCF60603DDF, + 0xF3FFFDFFFFFDDFFF, 0xFFCF27603DDF, 0xF3EFFDFFFFFDDFEF, 0xEFFCF60603DDF, 0xFFFFFFFFFFFDDFFF, 0xFC00FFCF80F07DDF, 0x2FFBFFFFFC7FFFEE, 0xCFFC0FF5F847F, 0x7FFFFFFFFFFFFFE, 0x3FF7FFF, 0x3FFFFFAFFFFFF7D6, - 0xF3FF3F5F, 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF, + 0xF3FF7F5F, 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF, 0x40, 0xFFFFFFFFFFFF03FF, 0xFFFFFFFF3FFFFFFF, 0xF7FFFFFFFFFF20BF, 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x3FE00E7FFFFFF, 0xFFFFFFFF0000FFFF, @@ -112,78 +112,80 @@ pub const XID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet { ], tree3_level1: &[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ], tree3_level2: &[ 0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 17, 4, 2, 2, 2, 2, 18, 19, 20, 4, 21, 22, 23, 24, 25, 4, 26, 4, 27, 28, - 29, 30, 31, 32, 33, 4, 2, 34, 35, 35, 36, 4, 4, 4, 4, 4, 37, 4, 38, 39, - 40, 41, 2, 42, 3, 43, 44, 45, 2, 46, 47, 4, 48, 49, 50, 51, 4, 4, 2, 52, - 2, 53, 4, 4, 54, 55, 2, 56, 57, 58, 59, 60, 4, 4, 3, 4, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 57, 4, 4, 4, 4, 70, 71, 72, 4, 73, 74, 75, 4, 4, 4, 4, - 76, 4, 4, 77, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 78, 4, 2, 79, - 2, 2, 2, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 81, 82, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 29, 30, 31, 32, 33, 4, 2, 34, 35, 35, 36, 4, 4, 4, 4, 4, 37, 38, 39, 40, + 41, 42, 2, 43, 3, 44, 45, 46, 2, 47, 48, 49, 50, 51, 52, 53, 4, 4, 2, 54, + 2, 55, 4, 4, 56, 57, 2, 58, 59, 60, 61, 62, 4, 4, 3, 4, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 59, 4, 4, 4, 4, 72, 73, 74, 4, 75, 76, 77, 4, 4, 4, 4, + 78, 79, 80, 81, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 82, 4, 2, 83, + 2, 2, 2, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 85, 86, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 88, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, - 2, 2, 2, 2, 2, 2, 2, 57, 83, 67, 84, 18, 85, 86, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 2, 4, 4, 2, 87, 88, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 59, 89, 69, 90, 18, 91, 92, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 2, 4, 4, 2, 93, 94, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 91, 34, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 88, 34, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 92, 2, 2, 2, 2, 93, 94, 2, 2, 2, 2, 2, 95, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 97, 2, 2, 2, 2, 98, 99, 2, 2, 2, 2, 2, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 2, 96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 2, 101, 102, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 98, 60, 4, 4, 4, 4, 4, 4, 4, 99, 100, 4, 4, 101, 4, 4, - 4, 4, 4, 4, 2, 102, 103, 104, 105, 106, 2, 2, 2, 2, 107, 108, 109, 110, - 111, 112, 4, 4, 4, 4, 4, 4, 4, 4, 113, 114, 115, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 23, 4, 4, 4, 116, 4, 4, 4, 117, 118, 4, 4, 4, - 4, 119, 120, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 121, - 2, 2, 2, 122, 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 124, 125, 126, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 103, 62, 4, 4, 4, 4, 4, 4, 4, 104, 105, 4, 4, 106, 4, + 4, 4, 4, 4, 4, 2, 107, 108, 109, 110, 111, 2, 2, 2, 2, 112, 113, 114, 115, + 116, 117, 4, 4, 4, 4, 4, 4, 4, 4, 118, 119, 120, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 121, 4, 4, 4, 122, 123, 124, 4, 125, 126, 4, 4, + 4, 4, 127, 128, 4, 4, 4, 4, 4, 4, 4, 129, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 130, 2, 2, 2, 131, 2, 132, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 133, 134, 135, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 128, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 136, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 137, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 2, 2, 2, + 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 138, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 130, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, - 2, 131, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 132, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 139, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 133, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, + 2, 2, 2, 140, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 141, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 87, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 87, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ], tree3_level3: &[ 0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0, @@ -195,32 +197,34 @@ pub const XID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet { 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x873FFFFFFEEFF06F, 0x1FFFFFFF00000000, 0x1FFFFFFF, 0x7FFFFFFEFF, 0x3FFFFFFFFFFFFF, 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, - 0x3FF00FFFFFFFFFF, 0x31BFFFFFFFFFF, 0xFFFF00801FFFFFFF, - 0xFFFF00000001FFFF, 0xFFFF00000000003F, 0x7FFFFF0000001F, - 0x803FFFC00000007F, 0x3FF01FFFFFF0004, 0xFFDFFFFFFFFFFFFF, - 0x4FFFFFFFFF00F0, 0x17FFDE1F, 0x40FFFFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F, - 0x3FF07FFFFFFFFFF, 0xFBEDFDFFFFF99FEF, 0x1F1FCFE081399F, 0x3C3FF07FF, - 0x3FF00BF, 0xFF3FFFFFFFFFFFFF, 0x3F000001, 0x3FF0011, 0x1FFFFFFFFFFFFFF, - 0x3FF, 0x3FF0FFFE7FFFFFF, 0x7F, 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF, - 0xF9BFFFFFFF6FF27F, 0x3FF000F, 0xFFFFFCFF00000000, 0x1BFCFFFFFF, - 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080, 0xFFFF000023FFFFFF, - 0xFF7FFFFFFFFFFDFF, 0xFFFC000003FF0001, 0x7FFEFFFFFCFFFF, - 0xB47FFFFFFFFFFB7F, 0xFFFFFDBF03FF00FF, 0x3FF01FB7FFF, 0x7FFFFF00000000, - 0x1000000000000, 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0xFFFFFFFFFFFF0000, - 0x1FFFFFFFFFFFF, 0xFFFF03FF7FFFFFFF, 0x1F3FFFFFFF03FF, 0xE0FFFFF803FF000F, - 0xFFFF, 0xFFFFFFFFFFFF87FF, 0xFFFF80FF, 0x3001B00000000, 0xFFFFFFFFFFFFFF, - 0x3FFFFF, 0x6FEF000000000000, 0x7FFFFFFFF, 0xFFFF00F000070000, - 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x63FF01FF, 0xFFFF3FFFFFFFFFFF, - 0xF807E3E000000000, 0x3C0000000FE7, 0x1C, 0xFFFFFFFFFFDFFFFF, - 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, - 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD, - 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, - 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF, 0x201FFFFFFFFFFF, 0xFFFEF8000010, - 0x7DBF9FFFF7F, 0x3FFF1FFFFFFFFFFF, 0x43FF, 0x7FFFFFFF0000, - 0x3FFFFFFFFFFFFFF, 0x7FFF6F7F00000000, 0x7F001F, 0x3FF0FFF, - 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, + 0x3FF00FFFFFFFFFF, 0x31BFFFFFFFFFF, 0xE000000000000000, + 0xFFFF00801FFFFFFF, 0xFFFF00000001FFFF, 0xFFFF00000000003F, + 0x7FFFFF0000001F, 0x803FFFC00000007F, 0x3FF01FFFFFF0004, + 0xFFDFFFFFFFFFFFFF, 0x4FFFFFFFFF00F0, 0x17FFDE1F, 0xC0FFFFFFFFFBFFFF, 0x3, + 0xFFFF01FFBFFFBD7F, 0x3FF07FFFFFFFFFF, 0xFBEDFDFFFFF99FEF, + 0x1F1FCFE081399F, 0x3C3FF07FF, 0x3FF00BF, 0xFF3FFFFFFFFFFFFF, 0x3F000001, + 0x3FF0011, 0x1FFFFFFFFFFFFFF, 0x3FF, 0x3FF0FFFE7FFFFFF, 0x7F, + 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF, 0xF9BFFFFFFF6FF27F, 0x3FF000F, + 0xFFFFFCFF00000000, 0x1BFCFFFFFF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080, + 0xFFFF000023FFFFFF, 0xFF7FFFFFFFFFFDFF, 0xFFFC000003FF0001, + 0x7FFEFFFFFCFFFF, 0xB47FFFFFFFFFFB7F, 0xFFFFFDBF03FF00FF, 0x3FF01FB7FFF, + 0x7FFFFF00000000, 0xC7FFFFFFFFFDFFFF, 0x3FF0007, 0x1000000000000, + 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF, + 0xFFFFFFFFFFFF, 0x3FFFFF, 0xFFFF03FF7FFFFFFF, 0x1F3FFFFFFF03FF, + 0xE0FFFFF803FF000F, 0xFFFF, 0xFFFFFFFFFFFF87FF, 0xFFFF80FF, + 0x3001B00000000, 0xFFFFFFFFFFFFFF, 0x6FEF000000000000, 0x40007FFFFFFFF, + 0xFFFF00F000270000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x63FF01FF, + 0xFFFF3FFFFFFFFFFF, 0xF807E3E000000000, 0x3C0000000FE7, 0x1C, + 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, + 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, + 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, + 0xFFFFFDFFFFFFFDFF, 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF, + 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7E07FFFFFFF, 0xFFFF07DBF9FFFF7F, + 0x3FFFFFFFFFFF, 0x8000, 0x3FFF1FFFFFFFFFFF, 0x43FF, 0x7FFFFFFF0000, + 0x3FFFFFFFFFFFFFF, 0x3FFFFFFFFFF0000, 0x7FFF6F7F00000000, 0x7F001F, + 0x3FF0FFF, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0x3FF000000000000, 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, - 0x3FFFFFFF, 0x7FF, 0xFFFFFFFFFFFF, + 0x3FFFFFFF, 0xFFFFFFFFFFFF07FF, ], }; @@ -336,7 +340,7 @@ pub const XID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet { ], tree3_level1: &[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 5, 11, 12, 5, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 13, 14, 15, 7, 16, 17, 7, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 7, 7, 13, 14, 15, 7, 16, 17, 7, 18, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -345,61 +349,63 @@ pub const XID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ], tree3_level2: &[ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 16, 4, 2, 2, 2, 2, 17, 18, 19, 4, 20, 21, 22, 23, 24, 4, 25, 4, 26, 27, 28, 29, 30, 31, 32, 4, 2, 33, 34, 34, 35, 4, 4, 4, 4, 4, 36, 4, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 4, 50, 22, 51, 52, 4, 4, 5, - 53, 54, 55, 4, 4, 56, 57, 54, 58, 59, 4, 60, 61, 4, 4, 62, 4, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 4, 4, 4, 4, 73, 74, 75, 4, 76, 77, 78, 4, 4, - 4, 4, 79, 4, 4, 80, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 81, 4, 2, - 56, 2, 2, 2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 83, 84, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 4, 4, 4, 4, 4, 4, 4, 4, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 22, 52, 53, 4, 4, 5, + 54, 55, 56, 4, 4, 57, 58, 55, 59, 60, 4, 61, 62, 4, 4, 63, 4, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 4, 4, 4, 4, 74, 75, 76, 4, 77, 78, 79, 4, 4, + 4, 4, 80, 81, 4, 82, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 83, 4, + 2, 57, 2, 2, 2, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 85, 86, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, 87, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 2, 2, 2, 2, 2, 2, 2, 2, 72, 85, 86, 87, 54, 88, 75, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 2, 4, 4, 2, 89, 90, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 2, 2, 2, 2, 2, 2, 2, 2, 73, 88, 89, 90, 55, 91, 76, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 2, 4, 4, 2, 92, 93, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 96, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 94, 2, 2, 2, 2, 95, 96, 2, 2, 2, 2, 2, 97, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 97, 2, 2, 2, 2, 98, 99, 2, 2, 2, 2, 2, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 98, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 100, 101, 102, 103, 104, 2, 2, - 2, 2, 105, 106, 107, 108, 109, 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 111, - 112, 4, 4, 4, 4, 87, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 113, 2, 2, 2, 114, 2, 115, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 116, 117, 118, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 119, 2, 2, 2, 2, 2, 2, + 4, 4, 4, 4, 4, 4, 2, 101, 102, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 103, 104, 105, 106, 107, + 2, 2, 2, 2, 108, 109, 110, 111, 112, 113, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 114, 4, 4, 4, 115, 116, + 4, 4, 117, 118, 4, 4, 4, 4, 90, 63, 4, 4, 4, 4, 4, 4, 4, 119, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 120, 2, 2, 2, 121, 2, 122, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 123, 124, 125, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 126, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 120, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 128, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 121, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 122, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 123, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 130, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 131, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ], tree3_level3: &[ 0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0, @@ -414,23 +420,25 @@ pub const XID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet { 0x303FFFFFFFFFF, 0xFFFF00801FFFFFFF, 0xFFFF00000000003F, 0xFFFF000000000003, 0x7FFFFF0000001F, 0xFFFFFFFFFFFFF8, 0x26000000000000, 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8, 0x47FFFFFFFF0090, - 0x7FFFFFFFFFFF8, 0x1400001E, 0xFFFFFFBFFFF, 0xFFFF01FFBFFFBD7F, + 0x7FFFFFFFFFFF8, 0x1400001E, 0x80000FFFFFFBFFFF, 0x1, 0xFFFF01FFBFFFBD7F, 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x380000780, 0xFFFFFFFFFFFF, 0xB0, 0x7FFFFFFFFFFF, 0xF000000, 0x10, 0x10007FFFFFFFFFF, 0x7FFFFFF, 0x7F, 0xFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF, 0x8000FFFFFF6FF27F, 0x2, 0xFFFFFCFF00000000, 0xA0001FFFF, 0x407FFFFFFFFF801, 0xFFFFFFFFF0010000, 0xFFFF0000200003FF, 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF, 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040, - 0x10003FF, 0x7FFFF00000000, 0x1000000000000, 0x3FFFFFF, 0xF, - 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF, 0xFFFF00007FFFFFFF, + 0x10003FF, 0x7FFFF00000000, 0xFFFFFFFFDFFF4, 0x1000000000000, 0x3FFFFFF, + 0xF, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF, 0x7E, 0xFFFF00007FFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x107FF, 0xFFF80000, 0xB00000000, 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x6FEF000000000000, - 0x7FFFFFFFF, 0xFFFF00F000070000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, - 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF, - 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF, - 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF, - 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x3F801FFFFFFFFFFF, 0x4000, 0x7FFF6F7F00000000, - 0x1F, 0x80F, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, - 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0x7FF, + 0x40007FFFFFFFF, 0xFFFF00F000270000, 0xFFFFFFFFFFFFFFF, + 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, + 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, + 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, + 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x7E07FFFFFFF, + 0xFFFF000000000000, 0x3FFFFFFFFFFF, 0x3F801FFFFFFFFFFF, 0x4000, + 0xFFFFFFF0000, 0x7FFF6F7F00000000, 0x1F, 0x80F, 0xAF7FE96FFFFFFEF, + 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0xFFFFFFFF, 0x3FFFFFFFFFFFFFF, + 0xFFFF0003FFFFFFFF, 0x1FFFFFFFF, 0x3FFFFFFF, 0xFFFFFFFFFFFF07FF, ], }; diff --git a/vendor/unicode-normalization/.cargo-checksum.json b/vendor/unicode-normalization/.cargo-checksum.json index 617f69464..7d296934d 100644 --- a/vendor/unicode-normalization/.cargo-checksum.json +++ b/vendor/unicode-normalization/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"61d13c11053dc298bbfb471307ca7aadbd704d880154a709d03f8a7c229a5388","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"7bef9d9fba0d6241f26cc14785e9616f8a5c35ad75a2991980fe2ca0961c1d6a","benches/bench.rs":"827e5343b059a732904be29717c2797203bfd0a633edf08042afea65372a3e2c","scripts/unicode.py":"b2182eaa678e126d1b0e8d81ec1a950effe4b8827482dd729f03e6d2035e61da","src/__test_api.rs":"78e21bfa0b98894f545c8ed3e31cec20d7a48951a7f3ed69a6130c4b3d463aee","src/decompose.rs":"c0eb774843a545356e63bbcd7fb926f80d3c97ef4601ca3701fc34154f2e9905","src/lib.rs":"1983769ea083caa36b0736c87cf2a98e91c2b900f1d5dec64e327360fa862386","src/lookups.rs":"962f9909b32e02b8a2a05836135d9cd39bb1ce01f7c659de99cbd8a3a3c78574","src/no_std_prelude.rs":"602e81e67b8952b6571826f431e3b6787be3073bc10f38a0d3374278f81a6a1f","src/normalize.rs":"de2670b4437d335d42884af844a750f70e541467ecd34077dfe032103cb9b041","src/perfect_hash.rs":"400c84e2f467f61bd55d55d08672da6a9ad7a57c938ce5d0c701a6994b1b273b","src/quick_check.rs":"9756312d75fc31b67fca954e44a4812945a7e436b03ba18b9a2441f6de570f6f","src/recompose.rs":"a6228ad7561a5c7a1ef1d510159bdde1eea8a161007c80e470432e9b844d5536","src/replace.rs":"b24c904f3e00851a78820e30ddfa4ff10c795f8925fd0ee7f5870f31fdfa770b","src/stream_safe.rs":"383d71f0da401af8e735877e43855c7e16cb06deb2263539cdec2a407dbe257d","src/tables.rs":"a5dfbf4adc3b8e872b1edeaeed9a48da38648a97940c811d04e0bce9c97361d5","src/test.rs":"3af8ad8c6bd2cc1ca44660bd265ad813c88d3074b448df4d9ff376b25fb77d26"},"package":"854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6"} \ No newline at end of file +{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"d43bfc158330a3a780af52ff0e82d88c8b54707ddf0469e6e27749c8ded4d1b7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"60162364e07490163f7a8e199c7a0a8ace165ae5aa7e4b6f16ff1617ddef5867","benches/bench.rs":"827e5343b059a732904be29717c2797203bfd0a633edf08042afea65372a3e2c","scripts/unicode.py":"6b1d9025fa9970c23b9721c6704aa085263408d645cf9c469295978010fd7504","src/__test_api.rs":"78e21bfa0b98894f545c8ed3e31cec20d7a48951a7f3ed69a6130c4b3d463aee","src/decompose.rs":"c0eb774843a545356e63bbcd7fb926f80d3c97ef4601ca3701fc34154f2e9905","src/lib.rs":"1983769ea083caa36b0736c87cf2a98e91c2b900f1d5dec64e327360fa862386","src/lookups.rs":"962f9909b32e02b8a2a05836135d9cd39bb1ce01f7c659de99cbd8a3a3c78574","src/no_std_prelude.rs":"602e81e67b8952b6571826f431e3b6787be3073bc10f38a0d3374278f81a6a1f","src/normalize.rs":"de2670b4437d335d42884af844a750f70e541467ecd34077dfe032103cb9b041","src/perfect_hash.rs":"400c84e2f467f61bd55d55d08672da6a9ad7a57c938ce5d0c701a6994b1b273b","src/quick_check.rs":"9756312d75fc31b67fca954e44a4812945a7e436b03ba18b9a2441f6de570f6f","src/recompose.rs":"a6228ad7561a5c7a1ef1d510159bdde1eea8a161007c80e470432e9b844d5536","src/replace.rs":"b24c904f3e00851a78820e30ddfa4ff10c795f8925fd0ee7f5870f31fdfa770b","src/stream_safe.rs":"383d71f0da401af8e735877e43855c7e16cb06deb2263539cdec2a407dbe257d","src/tables.rs":"3d9983a4e24c5b1e5dc272a025cdc729b7107f9a52a1fc89eca598e69af36c3a","src/test.rs":"3af8ad8c6bd2cc1ca44660bd265ad813c88d3074b448df4d9ff376b25fb77d26"},"package":"5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"} \ No newline at end of file diff --git a/vendor/unicode-normalization/Cargo.toml b/vendor/unicode-normalization/Cargo.toml index 417d04ce9..1c4d1f527 100644 --- a/vendor/unicode-normalization/Cargo.toml +++ b/vendor/unicode-normalization/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2018" name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" authors = [ "kwantam ", "Manish Goregaokar ", diff --git a/vendor/unicode-normalization/README.md b/vendor/unicode-normalization/README.md index cdc456f31..35030e360 100644 --- a/vendor/unicode-normalization/README.md +++ b/vendor/unicode-normalization/README.md @@ -31,7 +31,7 @@ to your `Cargo.toml`: ```toml [dependencies] -unicode-normalization = "0.1.20" +unicode-normalization = "0.1.22" ``` ## `no_std` + `alloc` support diff --git a/vendor/unicode-normalization/scripts/unicode.py b/vendor/unicode-normalization/scripts/unicode.py index bfe49c8b2..d32d9128a 100644 --- a/vendor/unicode-normalization/scripts/unicode.py +++ b/vendor/unicode-normalization/scripts/unicode.py @@ -21,7 +21,7 @@ import collections import urllib.request -UNICODE_VERSION = "14.0.0" +UNICODE_VERSION = "15.0.0" UCD_URL = "https://www.unicode.org/Public/%s/ucd/" % UNICODE_VERSION PREAMBLE = """// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT diff --git a/vendor/unicode-normalization/src/tables.rs b/vendor/unicode-normalization/src/tables.rs index 0370e2bdb..4c6885562 100644 --- a/vendor/unicode-normalization/src/tables.rs +++ b/vendor/unicode-normalization/src/tables.rs @@ -15,163 +15,165 @@ use crate::quick_check::IsNormalized; use crate::quick_check::IsNormalized::*; #[allow(unused)] -pub const UNICODE_VERSION: (u8, u8, u8) = (14, 0, 0); +pub const UNICODE_VERSION: (u8, u8, u8) = (15, 0, 0); pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ 0x0, 0x1, - 0x5ef, - 0x7c, - 0xa, - 0x0, - 0x1f3, - 0x7, - 0x8b, + 0x224, + 0x197, + 0x4, 0x0, + 0x6f, + 0x4, + 0xaf, 0x0, - 0x2, 0x0, - 0x12, + 0x4, 0x0, - 0x1, 0x0, + 0x88, + 0xa, + 0x8, 0x0, 0x0, 0x0, - 0x52, - 0xc8, + 0x1c, + 0x46, 0x1, - 0x8a, - 0x8e, + 0xd, + 0x1b, 0x0, - 0x4, - 0x83, + 0x15, + 0x12, + 0x45, + 0xec, + 0x36, + 0x10, 0x0, - 0x5d, - 0x42, - 0x4, 0x0, 0x0, - 0x65, 0x2, 0x0, - 0x4a, + 0x94, 0x0, - 0x3, - 0x6, - 0x4, - 0xa, - 0x4, + 0x57, 0x0, - 0x4, + 0x8, + 0x3, 0x7, - 0xa, - 0x1a, 0x0, - 0x32, - 0x10, - 0x36, - 0x13, - 0x2b, - 0x12, - 0x68, + 0x16, + 0x3a, + 0x2, + 0x23, + 0x3, + 0x4, + 0x1c, 0x1, 0x0, - 0x19, + 0x47, + 0x11, + 0x17, + 0x4, + 0x1b, 0x0, + 0x13, 0x0, 0x0, 0x0, - 0x5, - 0x1, 0x0, 0x1, - 0xa, + 0x7, + 0x7, + 0x4, + 0x2e, 0x0, 0x0, - 0x5f, + 0x2c, 0x0, 0x0, - 0x16, + 0x3, + 0xf, 0x0, - 0x7, 0x0, - 0x3, + 0x13, 0x0, + 0x1, 0x2, - 0x11, - 0x2, - 0xd, + 0x1, + 0x9, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, + 0x2, + 0x2, + 0x3, + 0x2, + 0x1e, + 0x0, + 0x8, 0x11, 0x1, - 0x17, - 0x0, - 0x15, 0x0, - 0x47, - 0x3, - 0x27, - 0x2c, 0x5, 0x0, - 0x8, - 0x0, - 0x7, + 0x79, 0x0, + 0x4, + 0x13, 0x0, 0x0, 0x5, - 0x20, - 0x7, - 0x15, - 0x10, - 0x15, - 0x4, - 0x3, - 0x6, - 0x0, + 0x2, 0x0, + 0x5, 0x1, - 0x13, - 0xb, 0x15, + 0x1, + 0x0, 0x3, + 0xc, 0x0, + 0x35, + 0x3, 0x2, + 0x5, + 0x6, 0x0, - 0x3, + 0x5, + 0x4, + 0x2, + 0x1c, 0x0, 0x0, 0x0, - 0xe, + 0x4, 0x0, 0x0, 0x0, - 0x7, 0x9, - 0x5, - 0x6, - 0x24, - 0xa, - 0x0, - 0x20, - 0x1, + 0x2, + 0x9, + 0x7, 0x0, + 0x5, 0x0, - 0x19, - 0x3a, + 0x8, + 0x7, 0x0, - 0x3, + 0x12, 0x9, 0x0, + 0x39, + 0x2, + 0x9, 0x0, 0x4, + 0x2, 0x0, 0x0, 0x0, @@ -179,182 +181,184 @@ pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x11, - 0x1c, - 0x4, + 0x22, + 0x2, 0x0, + 0x1b, + 0x13, + 0xc, 0x14, - 0x21, - 0x2, - 0x5, - 0xf, + 0x6, 0x4, - 0x3, + 0x5, + 0x13, 0x2, 0x0, - 0x2, - 0x2, + 0x3, + 0x4, 0x2, 0x0, - 0xb, + 0x18, + 0x0, + 0x6, + 0x4, + 0x0, 0x0, 0xa, + 0xa, + 0x0, 0x1, 0x0, + 0xf, + 0x10, + 0x1, 0x0, - 0x14, - 0x4, 0x0, - 0x3, 0x0, - 0x14, 0x2, + 0xf, + 0x1, 0x4, - 0x0, - 0x0, - 0x0, - 0x3, - 0x17, + 0x2, + 0xa, + 0xb, + 0x9, 0x4, - 0x3, - 0x3, - 0xe, - 0x1c, 0x1, - 0x2, - 0x5, 0x0, - 0x1, 0xb, 0x0, - 0x0, - 0xd, - 0x0, 0x3, + 0x0, 0x6, - 0x3, - 0xe, 0x0, + 0x6, 0x0, - 0x2, + 0x3, + 0x4, 0x0, 0x0, - 0x5, + 0x3, 0x0, - 0x10, 0x0, + 0x1, + 0x2, + 0x15, 0x0, - 0x19, 0x0, - 0x18, 0x0, - 0x1, + 0x14, + 0x1b, 0x0, - 0x1, - 0x9, - 0x5, + 0xc, 0x0, 0x0, - 0x1, - 0x4, 0x8, + 0x3, + 0xc, 0x0, - 0x9, - 0x11, - 0x1b, - 0x7, - 0x0, + 0xe, 0x2, 0x0, - 0x11, + 0x3, + 0x0, + 0xa, + 0x2, + 0x6, 0x1, + 0x0, 0x4, - 0x4, + 0x0, + 0x1, + 0x6, 0x2, - 0x11, + 0x3, + 0x2, + 0x10, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, - 0xa, - 0x0, + 0x3, + 0x4, + 0xd, 0x6, - 0x8, - 0x9, 0x0, - 0x4, 0x0, + 0x2, 0x0, 0x0, - 0xd, - 0x2, - 0xc, - 0x6, - 0x1d, - 0x7, 0x0, + 0x18, + 0xa, + 0x6, + 0x1, 0x1, - 0xd, 0x8, 0x0, - 0x3, + 0x1, + 0x1, + 0x7, 0x0, - 0x5, - 0x6, - 0x2, 0x3, + 0x9, + 0x11, + 0x5, + 0x1, + 0x5, 0x3, - 0xd, 0x16, - 0x3, 0x7, + 0x5, + 0x4, 0x0, - 0xc, - 0xe, + 0xa, + 0x6, 0x3, 0x0, 0x1, 0x0, - 0x6, - 0x0, - 0x3, - 0x9, - 0x0, 0x7, + 0x0, 0x6, 0x0, - 0xa, - 0x2, - 0x1b, 0x5, + 0x41, 0x9, - 0x16, + 0x1, + 0xa, 0x0, + 0x5, + 0x2, + 0x11, + 0xb, + 0x3, 0x1, 0x0, 0x0, 0x1, - 0x2, + 0x1, 0x0, - 0x7, - 0x3, 0x2, - 0xe, 0x0, - 0x1, + 0x6, + 0x18, + 0x3, 0x0, + 0x3, 0x0, 0x2, - 0x1, + 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x5, - 0x3, - 0x9, + 0x1, + 0x0, 0x0, 0x9, 0x1, @@ -363,295 +367,298 @@ pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ 0x2, 0x1, 0x0, - 0x3, - 0x3, - 0xc, + 0x1, + 0x2, + 0x1, 0x0, + 0x3, + 0x1, 0x1, 0x1, + 0x0, + 0x3, + 0xc, 0x1, + 0x3, 0x1, 0x0, - 0x5, - 0x5, 0x2, - 0x7, - 0x7, - 0x0, - 0x1, 0x0, 0x0, 0x5, - 0x2, - 0xc, + 0x1, + 0x5, 0x0, - 0x3, - 0x12, - 0x4, + 0x1, + 0xb, + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, + 0xf, 0x0, 0x0, - 0xd, + 0x2, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, - 0x0, - 0x9, - 0x0, - 0xc, - 0x0, - 0x8, 0x0, 0x1, - 0x5, - 0x1, - 0x0, 0x0, - 0xa, 0x9, + 0x8, 0x0, - 0x5, 0x0, + 0x3, + 0x3, 0x1, 0x4, + 0x3, + 0x4, + 0x5, + 0x2, 0x0, - 0x1, 0x0, + 0x2, + 0x6, 0x1, - 0x0, 0x5, - 0x9, + 0x1, + 0x0, 0x3, - 0x5, + 0x6, + 0x8, + 0x2, + 0x2, 0x6, 0x3, - 0x4, + 0x0, + 0x10, 0x6, + 0x6, + 0x5, 0x1, - 0x9, - 0x1, + 0x7, 0x0, 0x2, - 0x6, + 0x3, 0x2, - 0x4, 0x0, 0x0, - 0x8, - 0x0, 0x0, + 0x6, 0x0, 0x0, - 0xc, 0x0, 0x0, + 0x1, 0x0, - 0x6, - 0x6, 0x0, - 0x6, 0x0, 0x1, - 0x3, - 0x4, - 0x0, - 0x3, - 0x5, + 0x1, + 0x8, + 0x1, 0x0, 0x2, - 0x2, - 0x1, - 0x4, - 0x4, 0x0, 0x1, + 0xc, + 0x4, 0x1, + 0x2, 0x1, - 0x0, - 0x6, - 0x3, - 0x8, - 0x1, + 0x4, 0x2, + 0x5, + 0x4, 0x0, 0x3, + 0x4, 0x2, 0x0, 0x1, + 0x3, + 0x7, + 0x6, + 0x8, 0x0, + 0x2, 0x3, - 0xd, 0x0, + 0x2, + 0x2, + 0x2, + 0x4, 0x0, + 0x0, + 0x6, + 0x6, + 0x6, + 0xc, 0x5, - 0x1, 0x0, - 0x4, - 0x3, 0x0, 0x0, - 0x8, - 0x4, 0x1, - 0x1, - 0xb, + 0x2, 0x0, 0x3, 0x0, + 0x9, + 0x3, 0x2, 0x1, - 0x0, - 0x16, + 0x1, + 0x9, 0x1, 0x0, - 0x2, 0x8, + 0x1, + 0x6, 0x0, 0x3, 0x0, - 0x0, 0x5, 0x1, - 0x0, - 0x0, 0x1, - 0x4, 0x0, 0x0, - 0x9, 0x2, + 0x4, 0x0, 0x2, 0x0, - 0x9, - 0x4, 0x2, + 0x6, + 0x6, 0x2, + 0x8, + 0x5, + 0x6, + 0x5, 0x1, - 0x1, - 0x3, - 0x0, - 0x7, + 0x6, + 0x2, 0x0, + 0x1, 0x0, 0x0, 0x3, + 0x0, 0x1, - 0x3, - 0x6, - 0x2, + 0x9, + 0x5, + 0x5, 0xe, 0x0, - 0x6, + 0x3, 0x5, 0x0, 0x0, 0x1, + 0x1, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x1, - 0x2, + 0x4, 0x0, - 0x1, + 0x2, 0x4, + 0x6, 0x5, - 0x9, - 0x1, + 0x6, 0x0, - 0x9, 0x0, 0x1, + 0x1, 0x0, 0x0, - 0x1, - 0x2, + 0x5, 0x2, 0x8, - 0x3, - 0x3, + 0x8, + 0x1, + 0x6, 0x0, - 0x7, 0x1, + 0x0, 0x1, - 0x9, - 0x7, - 0x13, + 0x0, + 0x8, 0x0, 0x4, 0x7, + 0xa, 0x1, 0x0, 0x0, 0x2, 0x1, - 0x3, - 0x0, 0x1, 0x1, + 0x0, + 0x1, 0x2, 0x0, 0x2, 0x1, - 0x0, - 0x5, + 0x4, + 0x4, 0x0, 0x0, 0x0, - 0x2, + 0x6, 0x0, - 0x2, + 0x3, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, - 0x3, + 0x2, + 0x1, 0x1, 0x2, 0x2, 0x0, - 0x1, 0x4, + 0x2, 0x1, 0x0, 0x0, - 0x7, 0x1, - 0x1, - 0x3, - 0x0, - 0x5, 0x0, 0x1, + 0x1, + 0x0, 0x2, 0x2, 0x2, 0x2, 0x0, 0x1, + 0x5, + 0x4, + 0x1, + 0x0, + 0x1, + 0x1, 0x0, - 0x3, - 0x2, - 0x2, 0x0, 0x1, + 0x4, 0x1, 0x2, - 0x2, 0x1, 0x1, 0x0, @@ -660,93 +667,94 @@ pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x4, - 0x3, - 0x0, 0x0, - 0x7, 0x1, - 0x7, 0x0, - 0x1, - 0x7, - 0x2, - 0x1, - 0x3, - 0x2, 0x0, 0x4, + 0x1, 0x2, - 0x3, + 0x0, 0x1, + 0xd, + 0x4, 0x0, 0x1, + 0x4, + 0x0, + 0x5, + 0x3, + 0x7, + 0x3, + 0x3, + 0x3, 0x2, 0x0, - 0x4, + 0x2, + 0x2, 0x2, 0x1, 0x0, 0x1, - 0x0, 0x3, 0x4, - 0x3, + 0x1, 0x0, + 0x1, 0x4, - 0x0, 0x1, 0x0, 0x0, - 0xa, - 0x4, - 0x2, - 0x1, 0x0, + 0x1, + 0x3, + 0x1, 0x0, - 0x5, 0x0, - 0x2, - 0x2, 0x1, + 0x4, + 0x1, + 0x8, 0x2, 0x4, 0x1, - 0x0, 0x1, - 0x7, - 0x3, - 0x7, + 0x1, 0x5, 0x1, + 0x4, + 0x1, + 0x1, + 0x2, + 0x6, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, - 0x3, + 0x2, 0x0, - 0x3, - 0x3, - 0x5, - 0x5, 0x6, - 0x0, + 0x3, 0x1, + 0x3, + 0x2, + 0x3, 0x5, 0x4, - 0x2, + 0x1, 0x0, - 0x3, + 0x5, 0x0, 0x0, 0x1, 0x3, 0x0, - 0x3, + 0x2, 0x0, 0x1, - 0x5, + 0x1, 0x0, 0x0, 0x0, @@ -754,124 +762,126 @@ pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0xb, - 0x3, - 0x2, + 0x5, + 0x5, + 0x8, 0x0, 0x0, 0x0, 0x0, - 0x5, + 0x6, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x2, - 0x2, - 0x8, + 0x5, 0x1, - 0x4, 0x0, - 0x5, + 0x1, + 0x1, 0x0, 0x2, 0x2, - 0x2, - 0xb, - 0x6, + 0x7, + 0x1, + 0x1, 0x2, 0x0, - 0x3, + 0x2, 0x2, 0x1, 0x0, 0x0, 0x1, - 0x1, - 0x1, 0x0, 0x2, - 0x5, 0x2, 0x2, + 0x4, 0x1, + 0x4, 0x0, - 0x5, - 0x3, - 0x5, - 0x0, - 0x1, 0x2, - 0x5, - 0x1, + 0x2, + 0x4, 0x4, + 0x0, 0x8, - 0x3, + 0x4, + 0x6, + 0x2, + 0x1, 0x1, - 0x0, 0x0, 0x1, + 0x0, + 0x0, + 0x0, + 0x3, + 0x6, 0x1, + 0x0, + 0x3, 0x2, 0x1, - 0x6, - 0x1, 0x0, + 0x5, 0x4, - 0x1, + 0x0, + 0x0, + 0x5, 0x2, 0x0, 0x0, 0x2, - 0x3, 0x0, 0x0, 0x4, - 0x1, - 0x0, - 0x1, - 0x1, + 0x3, 0x0, + 0x9, + 0x5, 0x2, - 0x3, - 0x1, 0x0, 0x0, 0x2, 0x0, - 0x2, 0x1, + 0x7, + 0x0, 0x3, 0x1, - 0x1, - 0x1, + 0x2, 0x1, 0x0, 0x0, - 0x5, - 0x4, + 0x2, + 0x3, 0x0, 0x2, - 0x1, 0x3, + 0x1, 0x2, 0x1, 0x2, 0x0, + 0x4, 0x2, - 0x2, - 0x1, 0x1, 0x1, 0x1, 0x2, - 0xc, 0x2, 0x0, + 0x4, 0x2, + 0x1, 0x0, 0x0, - 0x2, + 0x3, + 0x0, 0x0, 0x0, 0x0, @@ -884,966 +894,976 @@ pub(crate) const CANONICAL_COMBINING_CLASS_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x2, - 0x2, 0x0, - 0x3, - 0x2, 0x2, + 0x0, 0x1, + 0x0, + 0x2, 0x1, 0x1, - 0x4, 0x0, - 0x3, + 0x2, + 0x0, + 0x1, 0x0, 0x0, - 0x2, 0x1, 0x1, - 0x7, - 0x2, - 0x4, 0x0, + 0x1, + 0x0, + 0x2, 0x0, - 0x4, 0x3, - 0x6, - 0x1, 0x0, 0x1, - 0x2, 0x1, 0x0, + 0x0, 0x1, - 0x3, 0x2, - 0x0, 0x1, + 0x2, + 0x3, + 0x5, + 0x3, 0x1, + 0x0, 0x1, - 0x9, + 0x3, + 0x7, 0x0, 0x0, 0x2, 0x0, 0x2, + 0x3, 0x1, - 0x4, ]; pub(crate) const CANONICAL_COMBINING_CLASS_KV: &[u32] = &[ 0x34AE6, - 0x348DC, - 0xA67AE6, - 0x746DC, - 0x65222, + 0x2DFAE6, + 0x1DFADA, + 0x339DC, + 0x1DFCE9, 0xA4D09, - 0x20D201, + 0x20D0E6, 0x593E6, 0x102E0DC, - 0x1E2EDE6, - 0x302DDE, + 0x1CF4E6, + 0x5A2DC, 0xFE26E6, - 0x898E6, - 0x329DC, + 0x11D4509, + 0x5C219, + 0x6EADC, 0xA675E6, 0x10F4EDC, - 0x2DF7E6, 0xA8EBE6, - 0x310E6, - 0x64F1F, + 0x332DC, + 0xC4D09, 0x741E6, - 0xF8082, - 0x1AC8E6, - 0x322CA, - 0x1144607, - 0x1E023E6, - 0x5C5DC, + 0x1D171D8, + 0xFE2DDC, + 0x1DF2E6, + 0x1DDEE6, + 0xA8E1E6, + 0x5BB14, 0x1DD5E6, 0x8CEE6, + 0x1A7BE6, 0xF7484, - 0x1B6DE6, - 0x59ADE, + 0xA8E6E6, 0x6191F, - 0x82CE6, - 0x305E6, + 0x114C307, + 0x1A79E6, 0x65DE6, - 0x5B812, - 0x8F6DC, - 0x1DEEE6, + 0x8F11C, + 0x1E020E6, + 0xA8F1E6, + 0x1DFDDC, 0xFE25E6, 0x1E947E6, - 0x486E6, 0x1A75E6, + 0xEBA09, 0x1E02AE6, - 0x1D182DC, - 0x1DE6E6, - 0x108DDC, + 0x64B1B, + 0x6D9E6, + 0x116B609, 0x1DECE6, - 0x1E015E6, - 0x8D6E6, + 0xE3A09, + 0x954E6, 0x2DE9E6, 0x1AB3E6, - 0x1AB0E6, + 0x8F3E6, 0x8F7E6, - 0x1136CE6, - 0xE486B, - 0x8E1E6, + 0xA8E2E6, + 0x1E00BE6, + 0xFE28DC, 0x20D801, - 0x821E6, - 0x8FFE6, - 0x135DE6, + 0xAAB0E6, + 0x10F4DDC, 0x825E6, - 0xFB1E1A, - 0x1D16DE2, - 0x8F21D, - 0x2DF1E6, - 0x8E3DC, + 0x611E6, + 0xAABEE6, + 0x820E6, + 0x8E8E6, + 0x306E6, 0x2DE4E6, - 0x1A18DC, + 0x11F4109, 0x111CA07, + 0x2CF0E6, 0x1CD7DC, 0x10A3ADC, - 0x1DC4E6, 0x1E131E6, - 0x6E4E6, + 0x103A09, + 0x73BDC, 0x358E8, 0x487E6, 0x1AB1E6, - 0x35DEA, - 0xFE20E6, + 0x11370E6, + 0x1CD0E6, 0xA8EEE6, - 0x597E6, + 0x33CDC, 0x20D5E6, 0x819E6, - 0x2DE5E6, + 0x16B30E6, 0x16AF301, - 0x1DD0CA, 0x9BC07, + 0x1DE9E6, 0x1DDAE6, - 0x1DF8E4, + 0x1136BE6, 0x82BE6, - 0x1CE201, - 0x327CA, - 0x1A17E6, - 0xECB7A, - 0xA67DE6, - 0x10F48E6, - 0x103707, + 0x173409, + 0x1DDBE6, + 0x5B40E, + 0x1D16DE2, + 0x1D16901, + 0x34CE6, + 0x2DF0E6, 0x33701, - 0x309E6, - 0x32DDC, - 0x1B6EE6, - 0x34BE6, - 0x10EABE6, - 0x344E6, + 0x11373E6, + 0x112E907, + 0x1AC0DC, + 0x20EA01, + 0x33EE6, + 0xF7181, 0x1D16801, 0x346E6, - 0x8DDE6, - 0x367E6, - 0x1E010E6, - 0x302BE4, - 0x5ADDE, - 0x1CDAE6, + 0x1E8D6DC, + 0x1E8D0DC, + 0xFE2CDC, + 0x1CE0E6, + 0x8EAE6, + 0x20DBE6, + 0x16B31E6, 0x735E6, - 0x5C712, - 0x2DEEE6, - 0x1DCED6, - 0x598E6, - 0x1193E09, - 0x116B707, + 0x10EFDDC, + 0x1D17EDC, + 0x11A3409, + 0x81FE6, + 0x1E01CE6, + 0x1DDFE6, 0x20E8DC, - 0x10F4CE6, + 0xABED09, 0x1DE1E6, - 0x65BE6, - 0x611E6, - 0x1E008E6, - 0x1DD9E6, - 0x85BDC, - 0x1A7FDC, + 0x316DC, + 0x1D182DC, + 0x20D7E6, + 0x64F1F, + 0x8F5E6, 0xD4D09, - 0x2DF0E6, - 0x8CCE6, - 0x17D209, - 0x596DC, + 0x1AC9E6, + 0x110B909, + 0x1ABCE6, + 0xA67AE6, 0x1D1AAE6, - 0x5B40E, - 0x1DE3E6, - 0x743E6, + 0x1E4EEDC, + 0x1E130E6, + 0x59FE6, + 0x1939DE, 0x357E6, - 0x324DC, - 0x30BE6, - 0x33EE6, - 0x1CE301, + 0x119E009, + 0x16FF006, + 0x733E6, + 0xFE29DC, 0x1CF8E6, - 0x1E003E6, + 0xF8409, 0x364E6, 0x317DC, 0x483E6, - 0xEBA09, 0x36CE6, - 0x18A9E4, - 0x1CD9DC, - 0x1E005E6, + 0x5B10B, + 0x1CD2E6, + 0x307E6, + 0x65121, 0x330DC, 0x319DC, - 0x81CE6, + 0x656DC, 0x1DE4E6, 0x952DC, - 0x115C007, - 0x1E009E6, - 0x10F49E6, + 0x345F0, + 0x2DF1E6, + 0x193BDC, 0x659E6, - 0x1CDFDC, - 0x1CDBE6, - 0xEB876, - 0x6D7E6, - 0x360EA, + 0x5ABE6, + 0x1B73E6, + 0x2CF1E6, + 0xABC07, + 0xF7C82, 0x1136AE6, 0xA8E4E6, 0x8FBE6, - 0xA67CE6, 0x5B20C, - 0x333DC, - 0x1DCADC, - 0x1E949E6, - 0x11371E6, - 0x5BF17, - 0x135FE6, + 0xFE21E6, + 0x2DFBE6, + 0x31AE8, + 0x738DC, + 0x20D301, + 0xFE2ADC, + 0x11369E6, 0xF7282, - 0x1DFBE6, + 0x1AC2E6, 0x1D17BDC, 0xF86E6, - 0x10F4AE6, + 0x327CA, 0x1DC0E6, - 0xD3C09, + 0x10F48E6, 0x1104609, - 0x5B00A, + 0x1B6BE6, 0x8E6DC, 0x1E134E6, 0x341E6, 0x1DF6E8, - 0xA674E6, + 0xA8ECE6, 0x1D1ABE6, 0x6ECE6, - 0x1D16FD8, + 0x1E2AEE6, 0x5B50F, + 0x1AC7E6, 0x1E002E6, - 0x1D165D8, - 0xF7C82, - 0x67023, - 0x5AADC, - 0x1DD3E6, - 0x10F47DC, - 0x2DE6E6, + 0xFC6DC, + 0x1E136E6, + 0x8DFE6, + 0x64C1C, + 0x658E6, + 0x6E1E6, 0x2DE7E6, - 0x20D6E6, - 0x1D244E6, - 0x1DC6E6, - 0x20E601, - 0x1E00AE6, - 0x135EE6, + 0x8CFDC, + 0x302E6, + 0x1AC4DC, + 0xAABFE6, + 0x5B913, + 0x1D18BDC, 0x1172B09, - 0xAAC1E6, + 0x2DF3E6, 0x739DC, - 0x10AE5E6, + 0x2DE0E6, + 0x1CDCDC, 0x1107009, - 0x308E6, + 0xA92CDC, 0x823E6, - 0x2CF0E6, 0x1DF3E6, + 0xA67DE6, 0x10F46DC, - 0x1DEBE6, + 0x1DCCE6, 0x6DCE6, - 0x1D166D8, 0x11A4709, - 0x614E6, + 0xEB976, + 0x36BE6, 0x65EE6, 0x1CF9E6, - 0x81DE6, - 0x6D9E6, - 0x951E6, - 0x2DE8E6, + 0x8D6E6, + 0x8E0E6, + 0x1B6EE6, 0x8D8E6, - 0x1193D09, - 0x328CA, + 0x1E026E6, + 0x343E6, 0x20D901, - 0x32FDC, - 0xA92CDC, + 0x1E948E6, + 0x5B610, + 0x1E011E6, 0x1DE8E6, - 0x1E00BE6, - 0x8F3E6, - 0x8EEDC, - 0xFE22E6, - 0x8D9E6, - 0x1D189E6, - 0xFE28DC, - 0xF83E6, - 0x2DF4E6, - 0x20F0E6, + 0x1DF7E4, + 0x2DFCE6, + 0x11D9709, + 0x486E6, + 0x1DC1E6, + 0x591DC, + 0x11D4409, + 0xA8C409, + 0x1BAA09, + 0x10EFFDC, 0x6EDDC, - 0xFE29DC, - 0x31EDC, - 0x1DFCE9, + 0x356DC, + 0x1DEEE6, + 0x2DEDE6, 0x64D1D, - 0x1DDDE6, - 0x33BDC, - 0x1D171D8, - 0x111C009, + 0x17D209, + 0xD3C09, + 0x1E945E6, + 0x114C209, 0x303E6, - 0xA8E0E6, - 0xACD09, - 0x5ACE6, + 0xA6F0E6, + 0x302FE0, + 0x1E01BE6, 0x11368E6, - 0x10D24E6, - 0x1DDEE6, - 0x31CDC, - 0x354DC, - 0xF8409, - 0x1E01EE6, + 0x1163F09, + 0x1CE301, + 0x5A3DC, + 0x8EFDC, + 0x596DC, + 0x1E028E6, 0x10F4FDC, - 0x1E014E6, - 0x5C219, + 0xA82C09, + 0x1D172D8, 0x2CEFE6, - 0x326DC, - 0x2DF8E6, + 0x10F49E6, + 0xA8EAE6, 0x32CDC, 0xD3B09, 0x1E00FE6, - 0x1E8D2DC, - 0x5A7DC, + 0x8EDDC, + 0x171409, 0x1ABBE6, - 0x8DAE6, + 0x1E8D3DC, 0xB3C07, - 0x1E013E6, + 0x59DE6, 0x10AE6DC, - 0x1E8D5DC, - 0x745E6, + 0x1DFBE6, + 0x16FF106, 0x82AE6, - 0xFE23E6, - 0x592E6, - 0x1E8D3DC, - 0x1AC5E6, - 0x8D7E6, - 0x5BC15, - 0x33501, - 0x1E027E6, - 0x5B30D, - 0xA80609, - 0x1CD0E6, - 0x363E6, + 0x20EEDC, + 0x1CDFDC, + 0x1CDDDC, + 0x8D2DC, + 0x135FE6, + 0xF7A82, + 0x610E6, + 0x1144209, + 0x2DEEE6, + 0x1145EE6, + 0x73DE6, + 0x35DEA, 0xFE2FE6, + 0xCBC07, 0x1DC7E6, - 0xAAB2E6, - 0x59EE6, - 0x32ADC, + 0x6E7E6, + 0x321CA, + 0x5A6DC, 0xA8F0E6, - 0x31AE8, - 0x10A0FE6, - 0x1123509, - 0x1D18ADC, + 0x5BA13, + 0x2DECE6, + 0x8EEDC, 0x16AF201, - 0x1DFDDC, - 0x10376E6, - 0x353DC, + 0x5C712, + 0x612E6, + 0x59CE6, + 0x11D4207, 0x1ABADC, - 0x20EA01, 0x1AB4E6, - 0x16FF106, + 0x1E8D2DC, + 0x85BDC, 0x1B72E6, - 0x740E6, - 0x1CDCDC, - 0x1E130E6, - 0x302FE0, - 0x1E2ECE6, + 0x1E000E6, + 0x5B00A, + 0x5C5DC, + 0x10F47DC, + 0x1A78E6, 0x1113409, - 0x1E006E6, - 0x35ADC, - 0x8CFDC, - 0x1DCCE6, + 0x1144607, + 0x10D26E6, + 0x20DCE6, + 0x350E6, 0xF7D82, - 0x8EAE6, - 0x173409, - 0x323DC, - 0x1CDEDC, - 0x89DE6, + 0x31FDC, + 0x103909, + 0x8D3DC, + 0x1BE607, + 0x731DC, 0x312E6, - 0x34CE6, 0x829E6, - 0x1DCFDC, - 0x899DC, - 0x10A3901, - 0x114C307, - 0x5B913, + 0x8FADC, + 0x7EBE6, + 0x1DDDE6, + 0x1D165D8, + 0x20E9E6, + 0x1E01EE6, 0x1E135E6, 0x1DEDE6, - 0x1E001E6, - 0x1A7CE6, - 0xA8EDE6, - 0x748DC, - 0x8D3DC, - 0x1E028E6, - 0x8D1DC, + 0xC565B, + 0x1E012E6, + 0x2DE3E6, + 0xF7B82, + 0x1CDEDC, + 0x36DE6, + 0x8F4E6, 0x1E8D4DC, 0x73CDC, - 0x1E8D6DC, - 0xAAB7E6, - 0x20EFDC, + 0x11374E6, + 0x5ACE6, + 0x1AC8E6, 0x2DEBE6, - 0xA8E8E6, - 0x1E01CE6, - 0x1D1ACE6, - 0xA8EFE6, - 0x8E5E6, + 0xA92BDC, + 0x1117307, + 0x111C009, + 0x33601, + 0xF8082, 0x20D4E6, - 0xA6F0E6, - 0x16B32E6, + 0x59BDC, + 0x1E001E6, 0x827E6, - 0xA3C07, + 0x33401, 0x31BD8, - 0x34EDC, - 0xFE2DDC, - 0xDCA09, + 0x20D201, + 0x1E003E6, + 0x1DF0E6, 0x31DDC, - 0x345F0, - 0x171409, - 0x1DFFDC, - 0x1DC3E6, - 0x302ADA, - 0x1E026E6, - 0x302CE8, - 0x1E2AEE6, - 0xFE21E6, - 0x73AE6, + 0x2DF4E6, + 0x11372E6, + 0x314E6, + 0x18A9E4, + 0x1136CE6, + 0x2DE5E6, + 0x1113309, + 0x135DE6, + 0x1A77E6, + 0xE3967, 0x10D27E6, 0xCCD09, - 0x1037AE6, - 0x1B6CDC, - 0xECA7A, - 0x1D185E6, - 0x65CDC, - 0xE3867, - 0x2CF1E6, + 0x32DDC, + 0x592E6, + 0x2DEFE6, + 0x8CAE6, + 0x2DE1E6, + 0x657E6, + 0x32BDC, 0x10EACE6, - 0x20D301, - 0x17DDE6, + 0x309E6, + 0x730E6, 0x65FDC, - 0x11D4409, - 0xF7B82, - 0x8E0E6, - 0x71124, - 0x1CE401, - 0x64E1E, + 0x1E014E6, + 0x8DEE6, + 0x2DFEE6, + 0x16B33E6, + 0x8CDE6, + 0x329DC, + 0x8F21D, 0x93C07, - 0x89EE6, - 0x1DD1E6, + 0x747E6, + 0x859DC, 0x736E6, 0x10A38E6, - 0x20E9E6, + 0x81DE6, 0x1CD5DC, - 0x10F4DDC, - 0x1AC3DC, - 0xFE2ADC, - 0x306E6, + 0x743E6, + 0x746DC, + 0x899DC, 0x61A20, + 0x1CE201, 0x301E6, - 0x738DC, - 0x1D172D8, + 0x1E944E6, + 0x1D186E6, 0x6E0E6, - 0x1DE0E6, - 0x16B30E6, + 0x1194307, 0x355DC, - 0x7EEE6, - 0x11D4207, - 0x7F1E6, + 0x6181E, + 0xA66FE6, + 0x8FFE6, 0x11100E6, - 0x30CE6, + 0x33DE6, 0x1DC2DC, + 0x615E6, 0x342E6, - 0x1CEDDC, - 0x352E6, - 0xE4B6B, - 0xAAB0E6, + 0x1A17E6, + 0x11367E6, + 0x10EABE6, + 0x6EBE6, 0x1E01FE6, - 0x5A4DC, + 0xE4A6B, 0x325DC, - 0x1DE5E6, - 0xA8F1E6, - 0x1D17FDC, - 0x1DF5E6, - 0x11372E6, - 0x484E6, - 0x318DC, - 0x1D16901, - 0x1E8D0DC, - 0xF35DC, + 0x349DC, + 0xFE23E6, + 0x10376E6, + 0x2DFFE6, + 0x1D16FD8, + 0x30FE6, + 0x1BAB09, + 0x2DE2E6, + 0x740E6, + 0x1193E09, 0xF39D8, - 0x1E00CE6, - 0xA8E1E6, + 0x20EFDC, + 0x2DE6E6, 0x1D187E6, - 0x1AC0DC, - 0x817E6, + 0x1DD2E6, + 0x10F4AE6, 0x6D8E6, 0x1B3407, 0x2DEAE6, - 0x103A09, - 0x1CD401, + 0xA679E6, + 0x10F84E6, 0xF87E6, 0x35FE9, 0x300E6, - 0xA6F1E6, + 0x7EEE6, 0x2DF2E6, - 0x103909, - 0x615E6, - 0x2DFFE6, - 0x749E6, - 0x309908, - 0x81FE6, + 0x11F4209, + 0x73AE6, + 0x31EDC, + 0x1E00DE6, + 0x1DCED6, + 0x1AB7DC, 0x1D16ED8, - 0x1E017E6, - 0x1CD8DC, + 0x352E6, + 0x8F6DC, 0xA677E6, - 0xEC97A, - 0x1D186E6, - 0x307E6, - 0x20D7E6, + 0x1A7CE6, + 0x8E7E6, + 0x16B32E6, + 0x1DD9E6, 0x1DF9DC, 0x8E9DC, - 0x2DF9E6, - 0x5B610, - 0x11A3409, + 0x11366E6, + 0x1AC6E6, + 0x1CE701, 0x1CD1E6, - 0x10378E6, - 0x656DC, - 0x818E6, - 0x33401, - 0x1ABDDC, - 0x16FF006, + 0x35EEA, + 0x16AF401, + 0x1AB0E6, + 0x34BE6, + 0x33BDC, + 0x67023, 0x366E6, - 0x1ACCE6, - 0x89ADC, - 0x65020, - 0x20E501, - 0xAAF609, + 0x10D25E6, + 0x9FEE6, + 0xAAB4DC, + 0xBCD09, + 0x1DC9E6, 0x5BD16, 0x8D0DC, - 0x1CDDDC, - 0x7F3E6, + 0x816E6, + 0x101FDDC, + 0xA3C07, 0x1D17CDC, - 0xA678E6, + 0x732E6, 0x826E6, - 0xA679E6, - 0x35CE9, + 0x1133B07, + 0x1CD9DC, 0x81EE6, 0x10F83DC, - 0xF7181, - 0x820E6, - 0x1B73E6, - 0x2DE1E6, + 0x313E6, + 0x1DFFDC, + 0x1D17FDC, 0x1D16701, 0x1A6009, - 0xABC07, + 0x1E949E6, + 0x10A0DDC, 0x1183909, - 0x1B6FE6, - 0x321CA, + 0xF19DC, 0x1DE7E6, - 0x742DC, + 0xB4D09, 0x89CE6, - 0x1E018E6, - 0x65AE6, + 0x2DFDE6, + 0x367E6, 0xA9C009, 0xA67BE6, + 0x333DC, 0x5A1E6, - 0x20E7E6, - 0x11366E6, + 0x8EBE6, + 0x1E009E6, 0x1DEFE6, - 0x1DF4E6, - 0x1E946E6, + 0x324DC, + 0xFE2BDC, 0xFE27DC, - 0x8DEE6, - 0x193AE6, - 0x114C209, + 0x10D24E6, + 0x81BE6, + 0x1E008E6, 0x1E01DE6, 0xA95309, - 0x59FE6, + 0x6DBE6, 0xC5554, 0x2D7F09, - 0x1B6BE6, - 0x610E6, - 0x8F8E6, + 0x1CDAE6, + 0x5BC15, + 0x59ADE, 0xA676E6, - 0x1D188E6, - 0x1BAA09, - 0xAABFE6, + 0x2DF8E6, + 0x20D6E6, + 0x5B30D, 0x1D181DC, 0x1ACADC, - 0xCBC07, - 0x115BF09, + 0x953E6, + 0x328CA, 0x5A0E6, - 0x30FE6, - 0x6E3DC, - 0x82DE6, - 0x658E6, - 0x8FADC, + 0x595E6, + 0x8D5E6, + 0x308E6, + 0xA674E6, + 0x30CE6, 0x1A76E6, - 0x1B4409, - 0x32BDC, - 0x313E6, - 0x11D9709, - 0x1AB8DC, - 0x1E012E6, - 0x1DC8E6, - 0xF18DC, - 0x613E6, - 0x30EE6, - 0x744DC, - 0x8DBE6, - 0x89FE6, - 0x1DDFE6, - 0xE496B, - 0x8FCE6, - 0x654E6, - 0x8ECE6, - 0x8CAE6, - 0x1CF4E6, - 0x1DD7E6, - 0x30AE6, - 0x591DC, - 0x730E6, + 0x1DC6E6, + 0x6E2E6, + 0x10F4CE6, + 0x20F0E6, + 0x8CBE6, + 0x10A0FE6, + 0x135EE6, + 0x1B6FE6, + 0x1AB2E6, + 0x1DF8E4, + 0x5AADC, + 0x10AE5E6, + 0x89FE6, + 0x1E00CE6, + 0x20E501, + 0x8FCE6, + 0x65020, + 0x8ECE6, + 0x898E6, + 0x1E2EDE6, + 0x1DD7E6, + 0xE3867, + 0x89DE6, + 0x1B71E6, 0x85ADC, - 0x6E8E6, - 0x59BDC, - 0x350E6, - 0x171509, - 0x16B34E6, + 0x1DC5E6, + 0x1D189E6, + 0xA69FE6, + 0x348DC, + 0x8DBE6, + 0x1DC4E6, 0x320DC, - 0x10F85DC, - 0x2DEDE6, - 0x1DF2E6, - 0x5BB14, - 0xF82E6, - 0x193BDC, - 0xE3A09, - 0x9FEE6, - 0x1113309, - 0xFE2EE6, - 0xF37DC, - 0x1DC1E6, - 0xC4D09, + 0xA8E3E6, + 0x1E946E6, + 0x1D170D8, + 0xAAF609, + 0x1ACCE6, + 0x360EA, + 0x1ABFDC, + 0x1AC1E6, + 0x302CE8, + 0x2DF7E6, + 0xEB876, + 0x1E132E6, 0x1DFEE6, - 0x1117307, + 0x33FE6, 0x20EB01, - 0x8EFDC, + 0x82DE6, 0x347DC, 0x1123607, - 0x1CE601, - 0x316DC, - 0x6EADC, - 0x1E945E6, - 0x16B36E6, - 0xA8EAE6, - 0x332DC, + 0xA6F1E6, + 0x749E6, + 0x17DDE6, + 0x7F1E6, + 0x617E6, + 0x1ACDE6, + 0x1DE6E6, 0x8E4E6, 0x351E6, - 0x10D25E6, - 0x2DFEE6, - 0x6E2E6, + 0x89EE6, + 0x613E6, + 0x1DCDEA, 0x655DC, - 0x2DEFE6, - 0x1DC9E6, + 0x20E1E6, + 0x65CDC, + 0x1ABDDC, 0x1AB9DC, - 0x11A9909, - 0xF7A82, - 0x20D1E6, - 0x1DF7E4, - 0xBCD09, - 0x5B10B, + 0xA678E6, + 0x10A3F09, + 0x32ADC, + 0xA8EDE6, + 0x302ADA, + 0x20DA01, 0x30DE6, - 0xA8C409, - 0xA8E9E6, - 0x953E6, + 0x302BE4, + 0x8D7E6, + 0x8F01B, 0x8DCE6, 0x5B711, - 0x8F5E6, + 0xA80609, 0x1D1ADE6, - 0x1E020E6, - 0x112E907, - 0x59CE6, + 0x6E4E6, + 0x1DE0E6, + 0x5ADDE, 0x1DF1E6, - 0xAAB4DC, - 0x595E6, - 0x8D2DC, + 0x11102E6, + 0x1E8D5DC, + 0x30EE6, 0x7EFE6, - 0x359DC, - 0x816E6, - 0x731DC, - 0x8D5E6, - 0x1E016E6, - 0x6DBE6, - 0x1DEAE6, - 0xE4A6B, + 0x7F0E6, + 0x597E6, + 0x1E027E6, + 0x1E2ECE6, + 0x31CDC, + 0x315E8, + 0xAAB7E6, + 0x616E6, 0x2DF6E6, - 0x20EEDC, + 0x5BF17, + 0x10A3901, 0x653E6, - 0x6E7E6, - 0x11101E6, - 0x5BA13, + 0x1D166D8, + 0x1AC5E6, 0x361EA, - 0x5AEE4, - 0x1939DE, - 0xA92BDC, - 0x340E6, - 0x612E6, - 0x10F84E6, - 0x73BDC, + 0x8F8E6, + 0x1AC3DC, + 0x103707, + 0x1123509, + 0x36EE6, + 0x1E004E6, + 0x1E023E6, 0x368E6, 0x1DD6E6, - 0x1BF309, - 0x302EE0, + 0x344E6, + 0x742DC, 0x485E6, 0x110BA07, - 0x2DFDE6, + 0x1CD8DC, + 0x1CD401, 0x8FEE6, - 0x331DC, - 0xC3C07, + 0x2DF5E6, 0x1E00EE6, - 0x1A7AE6, - 0x16B33E6, - 0x81BE6, - 0x1E01BE6, - 0x5A9E6, - 0x5C118, - 0x89BDC, + 0xECB7A, + 0x94D09, + 0x1DEBE6, + 0x1133C07, + 0x1E4EFE6, + 0x359DC, + 0x1E010E6, 0x304E6, - 0x20E1E6, + 0x5A8E6, + 0x1CD6DC, 0xAAB3E6, - 0x8E7E6, 0x1B70E6, + 0x6E8E6, 0xA92DDC, - 0x1163F09, - 0x8D4E6, - 0x1AC6E6, - 0xFC6DC, + 0x8D9E6, + 0x16B34E6, + 0xF18DC, + 0x30AE6, 0x20EDDC, - 0xC565B, + 0x1E4ECE8, 0x1E2EFE6, 0x1D242E6, - 0x1E132E6, - 0x1AC7E6, + 0x354DC, + 0x16AF101, 0x35BE6, - 0x1CE0E6, + 0x1DE3E6, 0x73EDC, - 0x64C1C, - 0x1DC5E6, - 0x339DC, - 0x11367E6, - 0x1133B07, - 0x1AC4DC, + 0x1E005E6, + 0x115BF09, + 0x1DC8E6, + 0x484E6, + 0x81CE6, 0x1E133E6, - 0xFE2BDC, - 0x737DC, - 0x1E000E6, + 0x5B812, + 0x340E6, + 0x598E6, + 0x1BC9E01, 0x1DDCE6, - 0x2DF5E6, - 0x35EEA, + 0x115C007, + 0x8E3DC, 0x11C3F09, - 0x16AF401, - 0x116B609, - 0x2DFBE6, - 0x8CBE6, - 0x64B1B, + 0x10F85DC, + 0x35CE9, + 0x1CDBE6, + 0x1D1ACE6, + 0x1E8D1DC, 0x1AB5DC, - 0x1DDBE6, - 0x1DD2E6, + 0xDCA09, + 0x322CA, 0x10F4BDC, - 0x314E6, - 0x1ABCE6, + 0x1DC3E6, + 0x35ADC, 0x7ECE6, 0x112EA09, - 0x11102E6, - 0x1A7BE6, + 0xE4B6B, + 0x7FDDC, 0x32EDC, - 0x6DFE6, - 0x954E6, - 0x617E6, - 0x1E2EEE6, - 0x1E00DE6, + 0x65BE6, + 0xFE22E6, + 0x1DD3E6, + 0x89ADC, + 0xA8E8E6, 0x8F9DC, 0x36FE6, - 0x311E6, - 0x732E6, + 0x1B6DE6, + 0x8CCE6, 0x1134D09, - 0x1AC2E6, + 0x193AE6, 0x309A08, - 0x747E6, + 0xFE20E6, 0x1DE2E6, - 0x11370E6, - 0x110B909, - 0x362E9, - 0x1E944E6, - 0x8F01B, + 0x1CEDDC, + 0x10EFEDC, + 0x1E013E6, + 0x8D4E6, + 0x34EDC, 0x16B35E6, - 0x859DC, + 0x1037AE6, 0x1107F09, - 0xA8E2E6, - 0x1BAB09, + 0x8DDE6, + 0x1DD1E6, 0x33801, - 0x8FDE6, + 0xA67CE6, 0x1ACEE6, - 0x11D4509, - 0x10A3F09, - 0xA8E3E6, - 0x8EDDC, - 0x11369E6, - 0x11373E6, - 0xA66FE6, - 0x20D0E6, - 0x8EBE6, - 0x1AB7DC, - 0x31FDC, - 0xEB976, - 0x1145EE6, - 0x1C3707, - 0x74AE6, + 0x1E08FE6, + 0x1183A07, + 0x1D244E6, + 0x1E018E6, + 0xACD09, + 0x5A5DC, + 0x64E1E, + 0x1CE401, + 0xF37DC, + 0x745E6, + 0xC3C07, + 0x65222, + 0x305E6, + 0x33ADC, + 0x1DF5E6, + 0x1E017E6, 0x1CE801, - 0x33CDC, - 0x1CE701, - 0x1DFADA, - 0x16B31E6, + 0x1193D09, + 0x20D1E6, + 0x318DC, 0x822E6, - 0x94D09, - 0x2DE2E6, - 0x6EBE6, - 0x11374E6, - 0x8F4E6, - 0x10F82E6, - 0x20DBE6, - 0x733E6, - 0x1DE9E6, - 0x6D6E6, - 0x2DF3E6, - 0x2DE0E6, + 0x116B707, + 0x310E6, + 0x821E6, + 0x10378E6, + 0x5A4DC, + 0xF83E6, + 0xAAC1E6, + 0x1DD0CA, + 0x1D185E6, + 0x8D1DC, + 0x5AFE6, + 0x1DE5E6, + 0x309908, 0x365E6, - 0x119E009, - 0xABED09, - 0x8DFE6, - 0x5A2DC, - 0x302E6, + 0x951E6, + 0x369E6, + 0x748DC, + 0xEC97A, + 0x817E6, 0x6DAE6, - 0x5A8E6, + 0x1E4EDE8, 0x1CE501, - 0xAAB8E6, - 0x10A0DDC, - 0x20DA01, - 0x7FDDC, - 0x8F11C, - 0x1A79E6, - 0x7F0E6, - 0x36EE6, - 0x1A77E6, - 0x343E6, + 0x737DC, + 0x311E6, + 0x6E3DC, + 0x1BF309, + 0x89BDC, + 0x11101E6, + 0x5C118, + 0x2DE8E6, + 0x614E6, + 0xFE2EE6, 0x10379E6, - 0x33601, - 0x101FDDC, - 0xA8ECE6, - 0x6E1E6, - 0x657E6, + 0x1DCFDC, + 0x82CE6, + 0x32FDC, + 0x1B4409, + 0x171509, 0x1ACBE6, - 0x5AFE6, - 0x2DFCE6, - 0x1A78E6, - 0x6181E, + 0x1B6CDC, + 0xECA7A, + 0x1E015E6, + 0x20E601, 0xFE24E6, 0x1D243E6, 0x1E021E6, - 0x1ACDE6, - 0x1CD2E6, + 0xE496B, + 0x71124, + 0x6DFE6, 0xA9B307, - 0x356DC, - 0x1D170D8, - 0x5A3DC, - 0xA8E6E6, - 0x2DFAE6, - 0xA82C09, + 0x65AE6, + 0x1A7FDC, + 0x8DAE6, + 0x8E1E6, + 0x11A9909, 0x1D180DC, - 0x1AC1E6, - 0x1ABFDC, + 0xA8EFE6, + 0x1DF4E6, 0x10377E6, + 0x362E9, 0x594E6, - 0x73FE6, - 0x1CD6DC, + 0x33501, 0x7F2DC, - 0x5A5DC, + 0x1D18ADC, 0x1DCBE6, - 0x1B71E6, - 0xAABEE6, + 0x5A9E6, + 0x1CE601, 0x34DDC, 0xEC87A, - 0x33FE6, + 0x6D7E6, + 0x108DDC, 0x5C4E6, 0x36AE6, - 0xB4D09, - 0x1183A07, - 0xA69FE6, - 0x1E8D1DC, - 0x1DCDEA, - 0x33DE6, - 0x2DECE6, + 0x326DC, + 0x1E00AE6, + 0xA8E0E6, + 0x5A7DC, + 0x1DEAE6, + 0x6D6E6, 0xA8E7E6, + 0x30BE6, 0x16AF001, - 0x315E8, - 0x65121, - 0x33ADC, + 0x1C3707, + 0x302EE0, + 0xE486B, 0x1DD8E6, - 0xF19DC, - 0x349DC, - 0x1144209, - 0x1DF0E6, - 0x5A6DC, - 0x369E6, + 0x1AB8DC, + 0x1A18DC, + 0x2DF9E6, + 0xFB1E1A, + 0x363E6, + 0x74AE6, 0x1E024E6, 0x599E6, - 0x8E8E6, - 0x1133C07, - 0xE3967, + 0x59EE6, + 0x7F3E6, 0x1BF209, - 0x1E004E6, - 0x73DE6, + 0x818E6, + 0xA8E9E6, + 0x16B36E6, 0x10F50DC, 0x1DD4E6, - 0x5ABE6, - 0x1E011E6, + 0xAAB2E6, 0xA8E5E6, - 0x1D18BDC, - 0x36BE6, - 0x16AF101, - 0xFE2CDC, - 0x1136BE6, + 0x744DC, + 0x10F82E6, + 0x302DDE, + 0x331DC, + 0x1D188E6, 0x7EDE6, - 0x8CDE6, - 0x1AC9E6, - 0x10D26E6, - 0x20DCE6, - 0x616E6, - 0x1194307, - 0x1BC9E01, + 0x1E006E6, + 0xAAB8E6, + 0x353DC, + 0x1E016E6, + 0x1DCADC, + 0x73FE6, + 0xF35DC, 0xA69EE6, - 0x1E136E6, + 0x323DC, + 0x8E5E6, 0x20ECDC, - 0x59DE6, - 0x1E948E6, - 0x36DE6, + 0x1E2EEE6, + 0x5AEE4, + 0x11371E6, 0x1E029E6, 0x734DC, 0x1AB6DC, - 0x7EBE6, + 0x20E7E6, 0x1D17DDC, - 0x2DE3E6, + 0x8FDE6, 0x9CD09, - 0x1D17EDC, - 0x1BE607, - 0x1AB2E6, - 0x1E94A07, + 0xF82E6, + 0x1A7AE6, + 0x654E6, + 0x1E94A07, ]; @@ -16550,6 +16570,68 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_CHARS: &[char] = &[ '\u{0037}', '\u{0038}', '\u{0039}', + '\u{0430}', + '\u{0431}', + '\u{0432}', + '\u{0433}', + '\u{0434}', + '\u{0435}', + '\u{0436}', + '\u{0437}', + '\u{0438}', + '\u{043A}', + '\u{043B}', + '\u{043C}', + '\u{043E}', + '\u{043F}', + '\u{0440}', + '\u{0441}', + '\u{0442}', + '\u{0443}', + '\u{0444}', + '\u{0445}', + '\u{0446}', + '\u{0447}', + '\u{0448}', + '\u{044B}', + '\u{044D}', + '\u{044E}', + '\u{A689}', + '\u{04D9}', + '\u{0456}', + '\u{0458}', + '\u{04E9}', + '\u{04AF}', + '\u{04CF}', + '\u{0430}', + '\u{0431}', + '\u{0432}', + '\u{0433}', + '\u{0434}', + '\u{0435}', + '\u{0436}', + '\u{0437}', + '\u{0438}', + '\u{043A}', + '\u{043B}', + '\u{043E}', + '\u{043F}', + '\u{0441}', + '\u{0443}', + '\u{0444}', + '\u{0445}', + '\u{0446}', + '\u{0447}', + '\u{0448}', + '\u{044A}', + '\u{044B}', + '\u{0491}', + '\u{0456}', + '\u{0455}', + '\u{045F}', + '\u{04AB}', + '\u{A651}', + '\u{04B1}', '\u{0627}', '\u{0628}', '\u{062C}', @@ -16940,181 +17022,184 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_CHARS: &[char] = &[ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, - 0xf, + 0x3, 0x0, 0x0, 0x0, - 0x4, + 0x1, + 0x16c, + 0xe, + 0x4ef, + 0x2, 0x0, - 0x8, - 0x6, - 0x5, 0x0, 0x0, - 0x490, - 0x1db, - 0x16, - 0x6, 0x2, - 0x7a8, - 0x24b, 0x0, - 0x42c, + 0x1, + 0x3, + 0x97, + 0x165, 0x0, - 0x68, - 0x7, - 0x266, 0x0, + 0x185, 0x0, + 0x1, 0x0, + 0x3f4, 0x0, 0x0, - 0xf, - 0x194, - 0x376, - 0x6, + 0x0, + 0x0, + 0x4, + 0x91, + 0x0, + 0xdd, + 0x1, + 0x26c, + 0x0, 0xb, 0x0, - 0xa3, + 0xe0, + 0xbc, + 0x3, + 0x213, + 0x1, 0x0, - 0x170, - 0xfe, + 0xc8, 0x3, - 0x1b2, - 0x1dc, + 0x1c, + 0xfc, 0x0, - 0x93, - 0x7, - 0x1f, - 0x130, 0x0, + 0x11, + 0x132, 0x0, - 0xa, - 0x35, 0x0, + 0x10b, + 0x90, + 0x474, + 0xd6, 0x0, - 0x35, - 0x12c, - 0x1b, - 0x3d, 0x0, + 0x3, + 0xd, + 0x5, 0x0, - 0x1, + 0x6, + 0x19, 0x54, - 0x58, - 0x0, - 0x4, - 0x92, - 0x10, - 0x1, - 0x0, - 0x38, - 0x14, - 0x11a, - 0xe8, + 0x132, + 0x4c, + 0x17, + 0x6, + 0x48, + 0x3, 0x0, 0x0, 0x6, - 0x7, 0xc, + 0x3, 0x0, + 0xb1, 0x1, - 0x2c, - 0x156, - 0x3d, + 0x8c, 0x0, - 0x9, - 0x1, - 0x11, + 0x1b, + 0xc0, + 0x7, + 0x2, 0x0, - 0x18, + 0x12, 0x0, 0x0, - 0xe, - 0x5, - 0x90, - 0x9, + 0x6, + 0x1, + 0x1be, + 0xc8, 0x0, - 0x9, + 0x7d, 0x0, - 0x41, + 0xa, 0x0, - 0x38, - 0x1, - 0x1a0, - 0x3, - 0x1a, + 0x0, + 0xb4, + 0x2, + 0x8, 0x5, - 0x9, + 0x144, + 0xdb, + 0x1, 0x6, 0x0, 0x0, - 0x53, - 0x5, - 0x0, + 0xd, + 0x14, 0x0, - 0x1, + 0x4f, + 0x2, 0x0, - 0x15, - 0xc3, + 0x3, + 0x32, 0x0, - 0xd, + 0x5, 0xe, - 0x19, - 0xf, - 0x20, + 0x7c, + 0x2c, + 0x6, 0x0, 0x0, - 0x4, + 0x7, 0x0, 0x5f, - 0x4, - 0x74, - 0x24, - 0x0, + 0x5, 0xf, - 0x9b, + 0x67, 0x0, + 0x1, + 0x34, 0x0, - 0x4c, - 0x2c, 0x0, 0x0, + 0x90, + 0x12, 0x0, - 0x4a, - 0x1, 0x0, - 0x45, + 0x1e, + 0x4c, + 0x89, + 0xa8, 0x0, - 0x2, + 0x4, + 0x1f, 0x0, 0x0, + 0x1, + 0x99, + 0x18, + 0xd, 0x3, - 0x2d, - 0x3b, + 0x7, + 0x5, + 0x19, 0x2, 0x0, - 0x5, - 0x69, + 0x4, + 0x1, 0x3, + 0x90, 0xb, - 0x0, - 0x9, - 0x1, + 0x29, 0x55, - 0x9, 0x0, - 0x1, - 0x1c, - 0x0, - 0x9, + 0x51, 0x0, 0x2, - 0x2, - 0x7f, - 0x42, + 0xd0, + 0x7a, + 0x66, 0x0, - 0x26, + 0x95, 0x7, 0x0, 0x0, @@ -17122,1327 +17207,1349 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x1, 0x0, - 0x72, - 0x30, - 0x3c, - 0xd9, - 0x36, + 0x8d, + 0xf, + 0x21, + 0x56, + 0xa, 0x1b, 0x0, 0x0, - 0x4, - 0x1, - 0x0, - 0x3d, - 0x0, - 0x21, - 0x1, - 0x0, - 0x2f, + 0x8, + 0x7, + 0x7c, + 0x5, 0x0, - 0x33, + 0x62, + 0x2, + 0x13, + 0x6, 0x0, - 0xe, - 0x14, - 0x19, + 0x4f, 0x0, - 0x11, - 0x3, - 0x3, - 0x10, 0x0, - 0x16, + 0x32, + 0x2f, + 0x4, + 0xd, + 0xa0, + 0x4, + 0x8, + 0x24, + 0x1f, 0x0, - 0x5, 0x0, - 0x46, - 0x6, + 0x82, + 0x45, 0x0, + 0x61, 0x0, + 0x1d, 0x1, - 0x4, + 0x0, 0x1, 0x0, + 0x7, + 0x17, + 0xb, 0x0, - 0x6, - 0x13, - 0x33, 0x0, 0x0, - 0x16, - 0x5c, - 0x7, + 0xb, + 0x8, + 0x8, 0x0, 0x0, - 0x2a, + 0x3d, 0x0, - 0x13, + 0x96, 0x0, 0x0, 0x0, - 0xb, + 0x8, 0x0, 0x0, 0x0, - 0x3, + 0x4, 0x0, 0x3, - 0x4c, - 0x0, + 0x7, + 0x2c, 0x0, 0x0, - 0x3, + 0x14, + 0x24, 0x2, - 0x6, 0x2, 0x0, - 0x8, - 0x0, - 0x55, - 0x1, - 0x1c, - 0x0, + 0x2, 0x0, 0x12, - 0xb, - 0x5, - 0xc, - 0x3, - 0x0, - 0xe, + 0x1, 0x0, - 0xa, 0x2, 0x0, - 0x30, - 0xe, + 0x25, 0xa, - 0x4, + 0x1, + 0x66, + 0xb, + 0x8, 0x0, + 0xc, + 0x10, 0x2, - 0x0, + 0x3, + 0x8, + 0x4, 0x6, + 0x1, + 0x4, + 0xe3, + 0x23, + 0x20, + 0x7, 0x0, - 0x9, - 0x47, - 0xb, - 0x71, - 0x2, + 0xf, + 0x1e, + 0x23, + 0x3d, + 0x4, 0x0, - 0x3, + 0x1, 0x0, - 0xf, - 0xd, + 0x3, + 0x25, 0x0, 0x1, - 0x3b, - 0x7, + 0x31, + 0x9d, 0x0, 0x0, - 0x8, + 0x4, 0x1, 0x0, 0x0, - 0x12, + 0x8, 0x0, 0x0, - 0x13, + 0x26, 0x0, 0x0, 0x2, 0x0, - 0x3, + 0x2, 0x0, 0x3, - 0x12, 0x0, 0x1b, 0x0, - 0x6, - 0xc, - 0x33, - 0x5, - 0x6, 0x2, - 0x1, 0x0, 0x1, + 0xa, 0x3, - 0x0, - 0x7, - 0x4, - 0x4, - 0x0, - 0xb, - 0x4, - 0x0, + 0x1, + 0x2, + 0xc, + 0xc, + 0x1, 0x1, 0x0, - 0x5, + 0x11, + 0x4, + 0x3d, + 0x2, + 0x1b, + 0x2, 0x0, 0xc, - 0x2, - 0x3, - 0x69, + 0x6, + 0x6, 0x0, - 0x7, - 0x50, - 0x1, 0x0, + 0x3, 0x0, - 0xb, + 0x9, + 0x2c, 0x0, + 0x9, + 0x37, + 0x2d, 0x0, + 0x12, + 0x23, 0x0, - 0x1b, - 0x17, - 0x21, - 0x3, - 0x4, 0x0, - 0x12, + 0x1c, 0x0, - 0x4, - 0x2f, - 0x1d, - 0x4, - 0x38, 0x26, + 0x10, + 0x15, 0x2, 0x0, + 0xb, 0x0, - 0x28, - 0x2, - 0x2e, - 0x1, + 0x4, + 0x14, + 0x5, + 0x13, + 0x7, 0x1c, + 0x3, + 0x36, 0x0, + 0x8, + 0x1, + 0x19, + 0x2, 0x0, + 0x1, 0x0, - 0x3, - 0x2, 0x0, + 0x4, + 0x1, + 0x8, 0x2, + 0xa, 0x6, - 0x0, - 0x38, + 0x13, 0x0, 0x0, 0x0, - 0x7, - 0x2, + 0x2f, + 0x1, 0x0, - 0xf, - 0x9, - 0x4, + 0x16, 0x5, - 0xb, - 0x4, + 0xc, + 0xc, 0x1, + 0x10, + 0x3, + 0xe, + 0x0, + 0x1, + 0xd, + 0x28, 0x0, - 0x27, - 0x9, - 0x15, - 0x34, 0x0, 0x1, - 0x9, 0x0, - 0x11, - 0x83, + 0x0, + 0x4, + 0x10, 0x21, 0x0, - 0x5, - 0xb, + 0x1, 0x3, - 0x9, 0x0, - 0x1, + 0x23, 0x0, + 0x1, 0x0, 0x0, - 0x2d, - 0x7, 0x0, + 0xd, + 0x1, 0x0, - 0x7, - 0x1c, - 0x16, 0x0, + 0x6, + 0x6b, 0x0, - 0x17, - 0xb, - 0x2b, - 0x7, + 0x14, 0x0, 0x0, 0x6, + 0x12, + 0x0, + 0x2, + 0x0, + 0x2a, + 0x1, + 0xb, 0x1, - 0x7, 0x6, - 0x3, + 0x9, 0x8, - 0xb, 0x1, - 0x5, 0x0, - 0x38, - 0x1, - 0xc, + 0x2b, 0x0, - 0x2, + 0x8, + 0x7, 0x0, + 0xf, + 0x16, 0x0, - 0x11, 0x0, + 0x44, 0x0, - 0x2b, + 0x1, 0x0, 0x0, + 0xc, + 0x19, + 0x25, 0x2, - 0x10, - 0x8, - 0x1, - 0x14, - 0x4, + 0x1f, + 0xf, + 0xc, 0x1, - 0xb, + 0x1f, + 0xa, + 0x0, + 0x38, + 0xe, + 0xf, + 0xc, + 0x25, 0x0, 0x6, - 0x11, + 0xe, 0x0, - 0x7, - 0x10, - 0x3, + 0x8, 0x0, - 0x4, - 0x32, - 0x0, - 0x6, - 0x0, - 0x1, + 0x2, 0x0, 0x0, 0x1, - 0x1f, + 0x9, 0x1, + 0x16, 0x0, 0x0, 0x0, - 0x0, - 0xb, - 0x7, - 0xa, - 0x4, - 0x0, + 0x3, 0x15, - 0xa, - 0x0, + 0x62, 0x1, 0x0, 0x0, - 0x2f, - 0x1, - 0x1, - 0x6, - 0xe, - 0x1d, - 0x7, + 0x2, 0x0, - 0x4, - 0xa, - 0xa, 0x0, + 0x3d, 0x0, + 0x3, + 0x1, + 0x1, + 0x1, 0x0, + 0x1, 0x0, 0x29, + 0x4, + 0x2c, 0x1, - 0xe, 0x0, 0x0, - 0x18, - 0x3, - 0x3, 0x0, - 0x3, - 0x3, 0x0, - 0x2, + 0x22, 0x0, - 0xe, + 0x14, + 0x28, 0x0, - 0x10, + 0x7, + 0x4, + 0x3, + 0x6, 0x0, - 0x8, - 0xc, - 0x1b, + 0x1, + 0xd, + 0x2a, 0x0, 0x0, + 0x44, 0x0, + 0x8, 0x0, + 0x2, 0x1, - 0x1, - 0xd, - 0x10, + 0xb, 0x0, - 0xc, - 0x6, 0x0, - 0x1a, - 0x1, - 0x1d, 0x0, - 0x2, 0x0, - 0x7, - 0x3b, 0x4, + 0x3, + 0x1c, + 0x5, 0x0, + 0x6, 0x2, - 0xe, - 0x10, - 0x4, - 0x1c, - 0x44, 0x0, - 0x3e, + 0x11, + 0x6, + 0x7, 0x0, + 0x2, + 0x28, + 0x7, + 0x1d, + 0xb, 0x5, + 0x2e, + 0x11, 0x0, 0x1, - 0x17, - 0x1, - 0x3, - 0x0, + 0xc, 0x0, 0x7, + 0x2f, 0x0, - 0x3, - 0x29, - 0x1e, - 0x6, 0x0, - 0x2, 0x5, - 0x2, - 0x12, + 0xa, 0x0, - 0xb, + 0x8, + 0x6, 0x0, 0x0, - 0x15, + 0x7, 0x1, + 0x8, + 0x20, + 0xc, 0x0, - 0x3, - 0x28, + 0x1a, + 0x5, + 0x0, + 0x26, + 0x26, + 0x2, + 0xb, + 0x8, 0x0, 0x4, + 0x5, + 0x2, + 0x0, + 0x5, + 0x12, + 0x0, + 0x5, 0x0, - 0xb, 0x1, - 0x16, + 0x6, + 0x9, + 0x1, 0x3, + 0x15, 0x3, 0x0, - 0x1d, - 0x0, 0x0, - 0x4, + 0x2, 0x0, - 0x15, + 0x3, 0x0, - 0x7, + 0x16, 0x0, - 0x7, - 0xa, + 0x10, + 0x3, 0x0, - 0xb, + 0x1b, 0x2, 0x0, - 0x28, + 0x9, 0x0, - 0x1, + 0x9, 0x0, - 0x13, + 0x9, 0x0, 0x0, 0x1, - 0x5, + 0x1, + 0xc, + 0x26, + 0x1, 0x0, - 0x13, - 0x6, 0x0, - 0x2, + 0x4, 0x0, - 0x3, + 0xc, + 0x1e, 0x0, - 0x1d, - 0x24, 0x1, - 0x26, - 0x2, - 0x19, + 0x36, + 0x6, + 0x3, 0x0, - 0x4, 0x0, - 0xf, + 0x1, + 0x0, + 0x6, 0x0, 0x0, 0x0, - 0x1, 0x8, + 0xc, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x5, - 0xb, + 0x4, 0x2, - 0x0, + 0x7, 0x1, - 0x4, - 0x21, - 0x5, - 0x0, - 0x0, - 0x33, - 0x3, - 0x3, - 0x0, + 0x2, + 0x7, + 0xd, 0x2, 0x0, 0x0, - 0x1d, 0x0, 0x2, - 0x0, - 0x0, - 0x1a, - 0x1b, 0x5, - 0x1, 0x0, - 0x9, - 0x2, - 0x9, - 0x1, + 0x8, + 0x5, 0x0, - 0xc, - 0x1, 0x0, - 0x4, + 0x3, + 0x6, 0x0, 0x0, + 0x8, 0x1, + 0x5, 0x1, 0x3, - 0x8, + 0x3, + 0x10, + 0xb, + 0x7, 0x0, + 0xf, + 0x11, 0x0, - 0x8, + 0x18, 0x0, - 0x2, 0x0, - 0xe, + 0xf, 0x2, - 0xb, - 0xe, - 0x3, - 0x0, - 0xa, - 0x0, - 0x4, + 0x7, 0x1, - 0x3, 0x0, 0x0, - 0x4, - 0x2, 0x0, 0xc, - 0x3, - 0x11, + 0x18, 0x0, - 0x1, + 0x17, 0x0, - 0x7, 0x1, - 0x3, - 0x6, - 0x21, 0x0, - 0x6, + 0x26, + 0x3, 0x0, - 0x1, - 0xb, + 0x1b, 0x0, + 0x8, + 0x3, + 0x3, 0x0, 0x0, + 0x2, + 0x6, 0x0, + 0xb, + 0x1b, + 0x9, 0x0, 0x3, 0x0, 0x0, - 0xe, - 0x6, - 0x1, 0x1, - 0x3c, - 0x5, - 0x0, - 0x0, - 0x2, - 0x6, - 0x7, - 0x2, - 0x7, - 0xe, - 0x4, - 0x4, - 0x0, 0x1, 0x1, 0x5, 0x0, - 0x0, - 0x9, - 0x1, - 0x2, - 0x17, + 0x6, 0x0, 0x4, - 0xa, - 0x1f, - 0x1, + 0x3, 0x0, 0x0, - 0x13, - 0x5, 0x0, - 0x3, - 0x9, - 0xf, 0x0, - 0x3, - 0x1b, 0x0, + 0x9, + 0x9, 0x0, + 0x2, 0x7, + 0xe, + 0x23, 0x3, - 0x0, + 0x1, 0x0, 0x0, 0xf, - 0xa, 0x0, 0x8, - 0xa, - 0x9, + 0x22, + 0xe, + 0x10, + 0x7, + 0x3, + 0xc, + 0x19, 0x1, - 0x1f, + 0xa, 0x2, - 0xc, 0x0, - 0x9, 0x3, + 0x18, + 0x1, + 0x16, + 0xa, 0x0, - 0x8, - 0x0, - 0x0, - 0x4, 0x2, + 0x8, 0x0, - 0xb, - 0x5, - 0xa, - 0x15, - 0x12, - 0xc, + 0x23, 0x0, - 0x3, 0x0, - 0x1, - 0x1, 0x6, 0x2, 0x0, + 0x4, + 0xd, + 0x1b, 0x0, - 0xc, - 0x0, - 0x0, - 0x2, - 0x5, - 0xa, - 0x3, - 0x0, - 0xa, - 0x1, - 0x1, + 0x4, + 0x38, 0x0, - 0x1, 0x0, 0x11, - 0x1f, + 0xe, 0x0, - 0xa, 0x0, - 0x4, 0x0, + 0x9, 0x0, - 0x1, + 0x21, + 0x13, 0x2, - 0x0, - 0x12, - 0x1, + 0x18, 0x4, + 0x1, + 0x10, 0x0, - 0xd, - 0x13, + 0x2, 0x0, + 0x6, + 0x14, + 0xa, 0x0, 0x0, + 0x4, + 0xe, 0x0, 0x0, - 0xb, + 0x5, + 0x4, 0x0, + 0x20, + 0x1d, + 0x1, 0x0, - 0x4, + 0x9, 0x0, + 0x1, + 0x1, + 0x4, 0x2, 0x0, - 0x7, - 0x3, - 0x3, - 0x3, - 0x6, - 0x6, 0x1, 0x0, 0x0, + 0x24, 0x1, - 0xc, 0x0, - 0x2, + 0x9, + 0x8, 0x0, - 0xb, - 0x4, 0x1, - 0x5, + 0xa, + 0x1, 0x0, - 0x8, + 0x4, 0x0, + 0x13, + 0x5, 0x0, 0x1, + 0x0, 0x1, - 0xc, 0x0, 0x0, - 0x5, - 0x7, 0x2, - 0x1c, 0x4, 0x0, - 0x16, - 0x2, - 0x4, + 0x0, + 0x5, + 0x1, 0x9, + 0x2, + 0x5, 0x0, 0x0, - 0x1, - 0xf, 0x0, 0x0, 0x0, - 0x11, + 0xa, 0x0, 0x0, - 0x3, - 0x4, 0x10, + 0x1, + 0x4, 0x0, - 0x2, - 0xa, 0x0, 0x1, + 0x4, 0x0, + 0x1, 0x2, - 0x0, - 0x0, - 0x0, - 0xb, - 0x7, - 0xb, - 0x0, + 0x4, 0x3, 0x0, - 0x1, - 0x1a, + 0x4, + 0x14, + 0x7, + 0xa, 0x2, - 0x1, 0x6, - 0x4, 0x0, - 0xd, + 0x2, 0x1, + 0x8, + 0x7, 0x0, 0x0, - 0x2, - 0x2, - 0x6, - 0x7, + 0x0, + 0x14, 0x1, - 0x9, - 0x16, + 0x10, 0x0, 0x0, - 0x3, + 0x5, 0x1, 0x6, + 0x5, 0x3, 0x0, - 0x0, - 0xe, - 0x1, - 0x3, + 0x9, 0x2, - 0x0, - 0xa, 0x4, - 0x19, - 0x8, - 0x0, 0x2, 0x0, - 0x1, 0x0, + 0xc, + 0x19, 0x0, 0x0, - 0x4, - 0x1, 0x0, - 0x2, - 0x1, - 0xb, - 0x1, - 0x8, 0x1, - 0x2, - 0x2, 0x0, - 0xb, 0x0, + 0xf, + 0x8, + 0xd, 0x0, - 0x2, - 0x27, - 0x1, 0x3, + 0x1, 0x0, + 0x9, + 0x14, + 0x17, 0x0, - 0x7, - 0x8, - 0x6, 0x0, 0x0, - 0x1, - 0x17, 0x0, 0x3, - 0x0, 0x1, - 0x2, 0x0, + 0x5, 0x15, - 0x9, - 0xe, - 0x9, - 0xe, - 0xc, - 0x9, - 0x2, 0x1, - 0x9, + 0x19, + 0x1, + 0x1, + 0x1, + 0x1, + 0x3, + 0x0, + 0x6, + 0x3, + 0x0, + 0x11, + 0x5, + 0x0, + 0x4, + 0xc, + 0x3, 0x0, 0x7, + 0x0, + 0x0, + 0x3, + 0x4, + 0x3, + 0xb, + 0x0, + 0x0, + 0x6, + 0x8, + 0x3, 0x1, 0x0, + 0x0, 0x1, + 0xd, + 0x3, 0x0, + 0x7, 0x0, 0x1, 0x0, 0x0, - 0x2, 0x0, - 0x1a, + 0x9, 0x1, - 0x8, - 0x0, 0x0, - 0x8, + 0x2, + 0x1, + 0x9, 0xa, + 0x8, 0x1, - 0x2, - 0x2, - 0x1d, + 0x7, 0x3, 0x0, - 0x11, - 0x0, - 0x2, - 0x0, - 0x0, + 0x3, 0x0, 0x0, + 0x4, 0x0, + 0x4, + 0x1, + 0xb, 0x0, + 0x13, + 0x6, + 0x7, 0x0, 0x0, 0x8, - 0x8, + 0x7, + 0x7, + 0x0, + 0x3, 0x0, + 0x2, + 0x3, 0x0, + 0x1, + 0x1, + 0x1, + 0x1b, + 0x3, + 0x2, 0x9, 0x2, + 0x1, + 0x2, + 0x0, 0x4, - 0xd, + 0x1, 0x0, - 0x7, + 0x6, + 0x0, + 0x0, + 0x1, 0x5, - 0x4, - 0x8, 0x0, + 0xf, + 0x1, 0x6, + 0x8, + 0x4, 0x0, 0x0, 0x3, + 0xb, + 0x2, + 0x5, 0x1, - 0x1, + 0x2, + 0x13, + 0x13, 0x0, + 0x9, 0x2, 0x0, 0x0, 0x0, - 0x1, - 0x1f, 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x4, + 0x2, + 0x21, + 0x0, + 0x6, 0x3, + 0x1, + 0x1, 0x5, + 0x3, 0x0, + 0x10, + 0x22, + 0xb, 0x0, 0x8, + 0x0, + 0x0, + 0x3, + 0x4, 0x1, + 0x1a, + 0x2, 0x0, - 0x15, 0x0, 0x0, - 0x4, - 0xf, - 0x3, 0x2, + 0x1, + 0x0, 0x0, 0x2, + 0x0, + 0x0, + 0x12, 0x1, 0x0, - 0x3, + 0x2, + 0x0, + 0x0, 0x1, + 0x0, 0x2, - 0xa, + 0x21, + 0x0, + 0x2, + 0xd, + 0x1, + 0x3, + 0x5, + 0x1, 0xc, + 0x10, 0x0, - 0x14, + 0x24, 0x0, 0x0, - 0x4, - 0x7, + 0x6, + 0x6, + 0x1b, 0x1, - 0x1f, + 0xd, 0x0, - 0x3, + 0x1, 0x0, + 0x1, 0x0, - 0x4, 0x0, + 0x7, 0x2, - 0x1, 0x0, - 0x2f, - 0xa, + 0x5, + 0x24, 0x6, 0x1, - 0xb, + 0xe, 0x0, - 0x8, - 0x7, + 0xb, + 0xe, 0x7, 0x0, 0x0, 0x0, - 0x13, - 0x0, - 0x0, 0x3, - 0x2, - 0x6, - 0x11, - 0x6, 0x0, 0x0, - 0xe, - 0x2, 0x2, + 0x18, + 0x3, + 0x3, 0x1, 0x0, - 0xc, - 0x2, 0x0, + 0x4, + 0x4, 0x0, - 0xa, - 0xa, - 0x2, + 0x1, 0x0, - 0x13, + 0x14, + 0x6, + 0xb, 0x0, - 0x5, + 0x2, + 0x1, + 0x2, + 0x6, + 0x6, 0x0, 0x6, - 0x3, - 0x1, + 0x0, 0x0, 0x1, 0x2, - 0x1, + 0x2, 0x1, 0x2, - 0x5, - 0x0, 0x0, 0x1, - 0x14, + 0x8, 0x1, - 0x3, - 0x5, + 0xc, + 0x0, 0x7, - 0x1, - 0x15, 0x2, - 0x0, + 0x3, 0x1, + 0x0, + 0x6, 0x1, + 0x7, + 0x11, + 0x3, + 0x0, 0x1, - 0xb, + 0xa, + 0x2, + 0x2, + 0x8, + 0x6, 0x8, 0x0, + 0x0, 0x4, + 0x8, + 0x1, + 0x7, + 0x2, + 0x2, + 0x6, + 0x0, + 0x6, 0x0, 0x0, + 0x7, 0x1, - 0x6, + 0xe, 0x2, - 0x3, 0x2, - 0x1, - 0x1, + 0x32, + 0x7, + 0xb, + 0x4, + 0x4, 0x0, - 0x9, + 0x6, 0x0, - 0x26, - 0x5, - 0x1, - 0x3, - 0xa, - 0x12, 0x8, - 0x13, - 0x8, - 0x1, - 0x14, - 0x5, - 0x3, - 0x0, - 0x9, 0x0, 0x0, 0x0, + 0x9, 0x2, - 0x3, - 0xd, + 0x1b, + 0x0, 0x0, 0x0, - 0x21, 0x1, + 0xc, 0x2, - 0x11, - 0xe, 0x1, + 0x2, + 0xf, 0x0, 0x0, 0x0, - 0xd, - 0x4, - 0x2, - 0xb, + 0x3, + 0xc, + 0x5, 0x0, 0x0, 0x0, - 0x5, - 0x8, + 0xb, + 0x0, + 0x2, 0x1, + 0x3, 0x0, - 0xc, 0x1, 0x6, - 0xc, + 0xa, 0x1, 0x0, - 0x5, + 0x8, 0x0, - 0x1, + 0x4, 0x1, 0x0, - 0x27, + 0x1, 0x0, - 0xa, - 0x10, - 0x6, - 0x4, + 0xe, + 0x2, 0x1, - 0xd, 0x1, - 0x3, 0x1, + 0x7, 0x1, + 0x3, 0x1, 0x2, - 0x2, - 0x2, - 0x0, - 0xf, - 0x5, 0x1, - 0x0, - 0x0, + 0x3, 0x2, - 0x4, 0x0, - 0x3, 0x11, + 0x3, + 0x2, + 0x3, 0x0, 0x0, + 0x3, + 0x4, + 0x0, 0x0, 0x1, + 0x20, 0x0, 0x0, 0x1, 0x0, 0x0, 0x7, + 0x2, + 0x0, + 0x12, + 0x0, 0xa, + 0x1, + 0x2, 0x0, - 0x3, - 0x5, 0x0, 0x0, 0x0, - 0x3, - 0x8, + 0x2, 0x0, - 0x5, 0x0, - 0x8, - 0x7, - 0x5, - 0x5, + 0x4, + 0xf, 0x0, + 0x7, 0x4, - 0x1, - 0xc, - 0x1, - 0x18, 0x2, + 0x12, + 0x0, 0x1, - 0x8, 0x4, 0x2, + 0x3, + 0x0, 0x1, + 0x17, + 0x1, + 0x1, + 0x5, 0x0, - 0x13, + 0x1, 0x0, 0x0, - 0xc, + 0xb, 0x0, - 0x3, + 0x1, 0x0, 0x0, 0x0, - 0x7, + 0x4, 0x0, 0x0, - 0xb, - 0x7, - 0x15, + 0x9, 0x0, + 0x4, 0x0, - 0x6, - 0x1b, 0x0, - 0xb, + 0x4, + 0xa, + 0x0, + 0x0, + 0x6, 0x7, - 0x12, - 0x1, - 0x9, + 0x2, + 0x3, 0x0, 0x0, 0x0, - 0x2, - 0x2, + 0x0, + 0x6, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x2, - 0x5, - 0x8, - 0x7, - 0x5, - 0x8, 0x0, 0x1, 0x0, - 0x0, - 0x0, + 0xc, + 0x8, 0x1, - 0x3, - 0x9, 0xd, + 0xb, + 0x2, + 0x0, + 0x0, 0x0, 0x1, - 0x4, + 0x5, + 0x1, + 0x0, + 0x0, 0x2, + 0x3, + 0x3, 0x0, 0x0, - 0x9, + 0x8, 0x0, - 0x2, - 0x12, - 0x5, 0x1, + 0x9, + 0x11, 0x1, + 0xc, 0x0, 0x0, 0x0, - 0x3, + 0x4, 0x0, 0x0, 0x0, - 0x4, - 0x8, - 0x5, - 0x5, - 0x6, + 0x1, + 0x1, + 0x17, + 0x1, 0x0, - 0x3, - 0x2, + 0x5, + 0xb, 0x1, + 0x4, 0x1, - 0x3, 0x6, - 0x15, - 0x2, - 0x4, - 0x5, + 0x1d, + 0x0, 0x1, + 0x4, 0x2, - 0x0, + 0x9, + 0x2, + 0xf, + 0x14, 0x2, 0x1, - 0x4, - 0x3, - 0x4, - 0xc, + 0x7, 0x1, + 0x1, + 0x7, + 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, + 0x4, + 0x13, 0x2, - 0x7, 0x1, - 0x2, - 0x6, + 0x1, + 0x3, 0x0, 0x2, - 0x0, 0x2, 0x0, - 0x1, 0x3, - 0x4, + 0x1, + 0x0, + 0x5, 0x1, 0x1, 0x0, - 0x12, - 0x2, 0x1, + 0x1, + 0x2, 0x0, 0x0, - 0xa, + 0x3, 0x0, - 0x8, - 0x8, + 0xa, + 0x6, 0x1, - 0xc, - 0xe, + 0x6, + 0x7, 0x1, 0x0, - 0x5, + 0x0, + 0x2, + 0x7, 0x4, - 0x1, - 0x17, 0x0, 0x0, - 0x11, - 0x2, + 0xc, 0x2, 0x0, + 0xa, 0x1, 0x0, 0x0, - 0x2, - 0x2, - 0x3, - 0x2, + 0xa, + 0x0, + 0x6, 0x3, - 0x4, 0x1, + 0x0, + 0xd, + 0x3, 0x5, 0x0, - 0x9, - 0x6, 0x2, - 0x0, - 0x1, - 0x5, 0xa, 0x0, - 0x8, + 0xb, + 0x1, + 0x6, + 0x22, + 0x0, + 0x5, + 0x1, 0x0, 0x2, - 0x4, 0x0, 0x0, + 0x12, + 0x4, + 0x2, 0x0, - 0xf, - 0x3, - 0x8, 0x0, - 0x2, + 0xc, 0x0, - 0x7, + 0x1, 0x0, 0x0, 0x0, @@ -18451,455 +18558,463 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0x5, - 0x3, - 0x3, - 0x3, - 0x3, - 0x3, 0x1, + 0x4, + 0x2, + 0x1, + 0x8, + 0x4, + 0x6, 0x1, 0x0, - 0x20, - 0x5, + 0x3, + 0xa, 0x0, - 0x2, + 0x5, 0x1, 0x0, 0x0, - 0x9, - 0x1, + 0x3, 0x0, + 0x6, 0x0, - 0x8, - 0x2, - 0xf, - 0x1, + 0x0, + 0x3, + 0x0, + 0x4, 0x0, 0x0, 0x0, + 0xe, + 0x1, 0x1, - 0x4, - 0x7, 0x0, 0x6, - 0x4, 0x0, + 0x8, 0x0, - 0x3, - 0x5, + 0x0, + 0xa, 0x1, - 0x7, 0x0, + 0x4, + 0x0, + 0x4, 0x1, 0x0, - 0x11, 0x0, 0x0, 0x0, 0x0, + 0x1, + 0x0, + 0x17, 0x4, 0x0, - 0x1, 0xb, - 0x0, - 0x2, - 0x2, 0x3, - 0x1, + 0x5, + 0x4, 0x0, - 0x2, + 0x3, + 0xf, + 0x6, 0x1, - 0xb, 0x1, - 0x2, 0x7, - 0x6, - 0x6, - 0x1, 0x4, - 0x0, + 0x3, 0x1, + 0x3, 0x4, - 0x0, - 0x0, - 0x5, - 0x1, - 0x0, - 0x0, 0x1, - 0x8, 0x1, 0x0, 0x0, + 0x0, + 0x2, 0x1, 0x0, + 0x5, 0x0, 0x2, 0x0, + 0x0, + 0x3, 0x1, - 0x4, - 0x6, 0x0, - 0xf, + 0x5, + 0x0, + 0xd, + 0x6, + 0x1, 0x0, 0x0, + 0x7, 0x0, - 0xd, - 0x5, 0x0, + 0xa, + 0x3, + 0x2, + 0xa, 0x1, + 0x7, + 0x1, + 0x0, 0x1, - 0x2, 0x0, 0x5, - 0x4, - 0x9, 0x3, 0x0, 0x5, - 0x4, - 0xd, + 0x2, + 0x1, 0x0, - 0x5, + 0x2, 0x0, 0x1, - 0x2, - 0x8, - 0x7, - 0x11, - 0x6, - 0x2, 0x1, - 0x0, + 0x4, + 0x9, + 0x5, + 0x1, 0x1, 0x6, + 0x0, + 0x9, + 0x1, + 0xa, 0x2, 0x2, - 0x8, 0x0, 0x0, - 0x3, - 0x1, - 0x4, 0x2, - 0xf, - 0xa, - 0x8, - 0xc, - 0x0, - 0x6, 0x2, + 0x7, + 0x9, + 0x0, + 0x10, + 0x1c, + 0x4, + 0x0, + 0x0, 0x3, + 0x3, + 0xd, 0x1, 0x3, - 0x2, 0x0, - 0xa, 0x0, + 0xc, + 0x7, 0x1, - 0x6, - 0x2, - 0x3, - 0x4, - 0x1, - 0x0, - 0x3, - 0x2, 0x3, + 0x7, 0x8, + 0x3, + 0x6, 0x0, 0x3, - 0x2, - 0x2, - 0x4, + 0x1, + 0x1, 0x0, + 0x1, + 0x1, + 0x4, + 0xa, 0x5, + 0x0, 0x1, + 0x13, 0x2, 0x0, 0x0, - 0xc, + 0x1, 0x2, 0x1, - 0x3, + 0xe, 0x1, + 0xc, 0x1, - 0x5, 0x1, - 0x3, + 0x9, 0x0, 0x0, - 0x2, - 0x10, + 0x1, + 0xc, 0x0, 0x1, 0x0, - 0xc, - 0xb, 0x2, - 0x1, 0x4, - 0x0, 0x3, - 0x0, 0x1, - 0x14, + 0xc, + 0xc, + 0x3, + 0x0, + 0xc, + 0xb, 0x0, 0x1, - 0x2, 0x1, + 0xa, + 0x1, + 0xb, 0x0, - 0x7, 0x0, - 0x2, + 0x1c, 0x0, 0x0, 0x0, 0x1, 0x2, - 0x4, - 0x0, - 0x6, + 0x8, 0x3, 0x0, - 0x11, - 0xe, - 0x0, + 0x5, 0x0, 0x3, + 0x3, 0x0, - 0x1, - 0x0, - 0xf, 0x4, - 0xa, + 0x0, 0x2, + 0x6, + 0xf, 0x0, - 0x3, - 0x12, 0x1, - 0x6, + 0x4, + 0x0, 0x0, + 0x11, + 0xb, + 0x4, + 0x5, 0x4, 0x0, - 0x2, - 0x3, + 0xd, + 0x4, + 0x4, 0x3, - 0xe, + 0x1, 0x0, 0x0, - 0x7, + 0x2, 0x0, 0x0, 0x0, - 0x4, + 0xa, + 0x1, 0x13, - 0x4, + 0x6, + 0x0, + 0x7, 0x7, - 0x5, - 0x4, - 0x2, - 0xf, - 0x2, 0x1, 0x1, - 0x0, - 0x0, + 0x4, 0x4, 0x0, - 0x1, - 0x7, - 0xc, 0x0, + 0x3, 0x0, 0x7, 0x0, 0x2, + 0x1, + 0x0, 0x2, 0x0, + 0x2, + 0x2, 0x0, 0x0, - 0x2, - 0xc, - 0xa, - 0x7, 0x0, + 0x3, 0x4, + 0x5, + 0x10, 0x0, - 0x4, + 0x7, 0x0, + 0xa, + 0x11, 0x0, 0x0, 0x1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xb, - 0xa, - 0x3, - 0x6, + 0x1, 0x0, 0x0, - 0x4, - 0x3, 0x0, - 0x6, + 0x2, + 0x2, 0x0, + 0xa, 0x0, + 0x3, 0x0, + 0x7, 0x6, - 0xa, - 0x4, + 0x1, 0x0, 0x4, - 0x5, - 0x16, + 0x2, + 0x2, 0x0, 0x1, - 0x1, + 0x2, + 0x3, 0x4, - 0x1c, 0x0, - 0x6, - 0x1, + 0x4, 0x0, + 0x1, 0x0, 0x2, - 0x2, + 0x10, + 0x5, 0x0, 0x0, + 0x1, 0x0, + 0xa, 0x4, - 0x16, - 0x2, 0x0, + 0x4, 0x0, - 0x3, 0x0, 0x0, - 0x3, 0x6, 0xb, - 0x4, + 0xb, + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, + 0x9, 0x0, - 0x5, - 0x5, - 0x3, - 0x1, 0x2, 0x4, 0x0, - 0x4, + 0x5, + 0x2, 0x0, + 0x3, 0x0, - 0x1, 0x0, - 0x2, - 0x8, 0x0, 0x2, - 0xf, - 0x9, - 0x5, 0x0, 0x1, - 0x1, 0x0, + 0x4, 0x6, + 0x1, + 0x4, + 0x1, 0x0, + 0x1, + 0x7, 0x0, 0x6, - 0x4, + 0x0, 0x0, 0x2, 0x2, - 0x3, 0x0, - 0x2, + 0x6, + 0x5, + 0x8, + 0x0, 0x1, + 0x2, 0x1, + 0x0, 0x4, - 0x1, + 0x7, 0x0, - 0x5, - 0x2, 0x1, - 0x5, + 0x7, 0x0, - 0x1, - 0x5, - 0x1, 0x2, 0x2, + 0xb, + 0x1, 0x2, + 0x6, + 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, + 0x2, + 0x4, 0x0, 0x0, - 0x2, - 0x9, - 0x6, + 0x3, + 0x1, + 0x7, 0x0, 0x1, - 0x3, 0x1, - 0x8, 0x0, + 0x1, 0x0, - 0x2, 0x0, + 0xb, 0x0, 0x0, - 0x3, - 0x3, - 0x1, 0x0, - 0x2, + 0x6, 0x0, + 0x1, + 0x0, + 0x4, + 0xc, 0x2, 0x0, 0x1, + 0x1, 0x2, - 0x3, 0x4, - 0x1, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, + 0x2, 0x1, 0x0, - 0xd, - 0x1, - 0x3, + 0x4, 0x3, + 0x18, + 0x0, 0x1, + 0x0, + 0x2, 0x5, - 0x3, - 0x1, 0x1, 0x2, - 0x2, 0x0, + 0x1, 0x3, - 0x3, + 0x4, 0x0, 0x0, - 0x8, + 0x5, + 0x2, 0x0, 0x0, 0x1, @@ -18909,12 +19024,12 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x2, + 0x3, 0x0, - 0x5, - 0xf, - 0x4, + 0x1, 0x0, - 0xb, + 0x0, + 0x1, 0x3, 0x0, 0x0, @@ -18923,192 +19038,195 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x1, 0x0, 0x0, - 0x3, + 0x14, 0x4, - 0x6, - 0x3, + 0xb, + 0x12, 0x0, 0x0, - 0x1, - 0x1, 0x2, 0x0, + 0x1, + 0x0, 0x0, 0x0, - 0x2, 0x1, - 0x8, 0x3, - 0xe, - 0x6, - 0x2, + 0xb, + 0x3, 0x0, 0x1, - 0x0, - 0x2, 0x2, - 0xa, + 0x0, + 0x10, + 0xd, + 0x1, + 0x1, + 0x7, 0x6, 0x1, - 0x0, - 0x8, + 0x1, + 0x2, 0x0, 0x0, - 0xd, 0x1, - 0x0, + 0x3, 0x2, 0x1, 0x3, + 0x1, 0x0, 0x0, 0x0, + 0x8, + 0x4, 0x2, - 0x2, - 0x0, - 0x2, - 0x0, - 0xd, - 0x0, - 0x3, + 0x6, 0x9, + 0x5, 0x0, + 0x16, 0x1, - 0x0, 0x4, - 0x6, 0x0, + 0x3, + 0x3, + 0x4, + 0x1, 0x0, - 0x5, 0x0, - 0x1, + 0x2, 0x0, 0x1, 0x0, - 0x7, - 0x8, 0x2, - 0x6, - 0x1, + 0xd, 0x2, 0x0, - 0x9, - 0x0, - 0x1, - 0x0, + 0xb, + 0x6, + 0xa, + 0x3, 0x0, + 0x5, 0x0, 0x1, - 0x1, 0x0, - 0x3, 0x0, - 0x2, 0x0, + 0x5, 0x1, 0x0, 0xa, 0x0, - 0x7, - 0x1, 0x2, - 0x4, 0x0, + 0x2, + 0x2, + 0x5, 0x1, + 0x2, 0x0, + 0x2, + 0x2, + 0x5, 0x0, 0x1, 0x0, 0x0, - 0xb, - 0x2, - 0x0, + 0x3, 0x0, - 0x6, - 0x2, + 0x3, 0x2, - 0xf, + 0x0, + 0x0, 0x0, 0x1, + 0x1, + 0x1, 0x0, + 0x19, 0x0, - 0x3, - 0x5, 0x0, - 0xc, 0x3, - 0x2, 0x0, 0x1, 0x0, + 0x1, 0x5, - 0x5, + 0x4, 0x1, - 0x8, + 0x4, 0x0, + 0x1, 0x3, - 0xe, + 0x4, + 0x6, 0x1, - 0x2, - 0x0, 0x1, - 0x11, - 0xa, - 0x0, - 0x3, - 0x9, + 0x4, 0x3, - 0x2, - 0x0, + 0x4, 0x0, + 0x4, + 0x5, + 0x9, 0x0, + 0x1, 0x9, + 0x2, 0x1, 0x0, 0x0, + 0x0, + 0xc, 0x1, 0x0, - 0x2, 0x0, + 0x3, 0x2, - 0x0, - 0x5, 0x3, + 0x2, + 0x1, 0x0, - 0xb, 0x4, 0x0, - 0x0, - 0x3, + 0x4, + 0x7, 0x3, - 0x0, - 0x10, - 0xc, + 0x1, 0x0, 0x1, 0x1, - 0x9, + 0x0, 0x0, 0x1, + 0x5, + 0x6, + 0x9, 0x0, 0x2, + 0x1b, + 0x2, 0x0, + 0x9, 0x0, 0x0, - 0x2, + 0x6, + 0x0, 0x0, 0x0, + 0x3, + 0x0, + 0x1, 0x6, - 0xc, 0x2, 0x1, + 0x6, 0x1, - 0x1, + 0xb, 0x3, - 0x2, - 0x8, - 0x5, - 0x2, + 0x6, 0x0, 0x0, 0x0, @@ -19119,496 +19237,483 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x2, - 0x6, - 0x0, + 0x2, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x0, 0x3, 0x0, - 0x1, - 0x0, - 0x0, + 0x3, 0x3, 0x5, + 0xb, + 0x0, 0x0, - 0x3, 0x1, - 0x9, - 0x9, - 0x4, - 0x4, - 0x10, + 0x0, 0x0, 0x2, - 0x5, + 0xb, + 0x3, 0x2, + 0x13, 0x1, 0x1, - 0x1, + 0x8, + 0x3, + 0x2, + 0x5, 0x1, 0x0, + 0x1, + 0x1, 0x5, + 0x0, + 0x1, 0x3, - 0x8, 0x4, - 0xb, - 0x1, + 0x5, + 0x0, 0x2, 0x0, - 0x4, - 0x8, + 0xe, + 0x1, 0x0, 0x0, 0x5, - 0x1, + 0x3, + 0x5, 0x0, - 0x7, 0x1, - 0x3, + 0x2, 0x0, 0x0, - 0x1, + 0x8, 0x0, 0x1, - 0x4, + 0x2, 0x0, - 0x1, + 0x9, 0x0, 0x0, 0x0, - 0x1, + 0x6, 0x0, 0x3, - 0xd, 0x3, 0x9, - 0x0, - 0x2, - 0x3, - 0x7, - 0xf, - 0xa, 0x7, - 0x4, - 0x1, - 0x1, + 0x0, + 0x8, + 0x0, 0x1, + 0x3, 0x0, - 0x6, + 0x3, 0x5, + 0x4, 0x1, + 0x2, + 0x2, 0x0, - 0x1, - 0x1, 0x4, 0x3, + 0x0, + 0x7, + 0x5, + 0x3, 0x1, - 0x1, - 0x1, - 0x2, 0x0, 0x4, - 0x6, - 0x5, - 0x2, + 0x1, 0x0, + 0x3, 0x0, - 0x7, - 0x2, 0x8, 0x2, + 0x4, + 0x4, + 0x0, 0x9, + 0x1, + 0x4, 0x0, + 0x6, + 0x4, 0x0, 0x0, - 0x4, - 0x1, 0x0, - 0x8, - 0x2, + 0xa, + 0x1, 0x0, 0x1, + 0x6, + 0x0, 0x1, - 0xf, + 0x6, + 0x3, 0x2, - 0x9, - 0x0, - 0x9, 0x2, - 0x7, + 0x0, + 0x1, + 0x1, 0x3, + 0x5, 0x0, 0x0, - 0x1, 0x2, + 0x4, 0x1, 0x0, 0x0, 0x1, - 0x1, + 0x6, 0x0, + 0x5, + 0x4, + 0x4, 0x1, 0x1, - 0x1, - 0x1, - 0x1, - 0x0, + 0x4, 0x1, 0x2, 0x0, + 0x2, + 0x2, + 0x5, + 0xd, 0x1, - 0x1, - 0x4, - 0x6, - 0xa, 0x0, 0x2, 0x0, 0x0, - 0x4, - 0x0, - 0x2, 0x2, 0x0, 0x1, 0x1, 0x0, 0x0, - 0x2, - 0x0, 0x1, + 0x4, 0x0, 0x0, + 0x7, 0x0, - 0x1, 0x5, 0x0, + 0x0, + 0x0, + 0x1, + 0x4, + 0x0, 0x9, 0x2, - 0x2, + 0x4, 0x0, 0x0, 0x1, 0x0, - 0x5, + 0x3, 0x0, - 0x1, + 0xa, 0x0, - 0x1, + 0x3, 0x1, 0x5, - 0x3, + 0x1, 0x0, 0x0, - 0x3, 0x5, + 0xa, 0x1, 0x2, 0x0, 0x2, - 0x2, - 0x2, - 0x2, - 0x0, + 0x4, + 0x9, + 0x1, + 0x4, 0x5, 0x0, 0x0, 0x1, - 0x0, - 0xc, - 0x1, - 0x6, - 0x7, + 0x3, + 0x9, + 0x2, + 0x4, + 0x8, 0x2, 0x0, 0x0, - 0x7, + 0x3, + 0x8, 0x0, 0x0, 0x2, 0x1, - 0x0, + 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x1, - 0x3, + 0x4, + 0x1, 0x1, 0x0, - 0x2, - 0x2, - 0x2, + 0x1, 0x0, + 0x1, 0x0, - 0x5, - 0x2, - 0xe, 0x0, 0x1, + 0x2, + 0x9, + 0x1, + 0x1, 0x5, 0x2, 0x0, 0x1, 0x0, 0x0, - 0x3, - 0x0, 0x2, 0x0, - 0x1, - 0xb, + 0x3, 0x0, 0x1, 0x2, - 0x1, - 0x2, + 0x0, 0x4, 0x2, + 0x4, 0x2, 0x2, 0x0, - 0x5, + 0x1, + 0xa, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x0, - 0xb, + 0x3, + 0x0, + 0x3, 0x2, + 0x5, 0x1, - 0x0, 0x2, - 0x3, + 0x1, 0x2, 0x0, - 0x0, + 0x4, + 0x2, 0x1, 0x0, - 0x2, 0x1, 0x0, 0x0, 0x1, - 0x2, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x0, + 0x2, 0x0, + 0x2, 0x3, - 0x5, - 0x12, - 0x0, - 0x0, 0x2, - 0xe, 0x0, - 0x2, - 0x6, + 0x0, 0x0, 0x5, 0x1, - 0x2, - 0x2, 0x0, 0x1, - 0x6, - 0x2, - 0x0, 0x1, - 0x3, 0x0, + 0x7, 0x1, 0x1, - 0x6, - 0x1, 0x3, - 0x4, 0x0, + 0x3, + 0x1, + 0x1, 0x0, - 0x5, + 0x9, + 0x2, 0x0, 0x1, 0x1, - 0x3, + 0x7, + 0x6, + 0x2, + 0x0, + 0x6, + 0x0, + 0x4, + 0x0, + 0x2, + 0x7, 0x4, 0x1, + 0x1, 0x0, 0x0, 0x2, - 0x3, + 0x1, 0x0, - 0x2, + 0x4, + 0x3, 0x0, + 0xa, 0x0, - 0x3, 0x0, 0x2, 0x2, - 0x2, - 0x5, - 0x4, 0x1, + 0x1, + 0x3, 0x2, 0x1, + 0x1, 0x0, - 0x2, + 0x3, 0x0, 0x0, 0x0, 0x1, - 0xe, - 0x1, - 0x2, + 0x6, 0x1, - 0x2, + 0x3, + 0xb, + 0xb, 0x0, - 0x8, 0x4, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x1, + 0x2, 0x0, 0x0, - 0x2, 0x1, + 0x4, 0x0, 0x0, - 0x2, + 0x1, 0x0, 0x0, + 0x5, + 0x3, 0x2, 0x3, - 0x0, - 0x4, + 0x8, 0x1, + 0x6, 0x1, 0x2, 0x0, 0x1, - 0x0, 0x4, + 0x5, + 0x2, + 0x0, + 0x6, + 0x1, + 0x1, 0x0, + 0x2, 0x1, + 0x2, + 0x2, 0x0, 0x0, - 0x2, 0x4, - 0xe, 0x0, - 0x2, 0x1, - 0xe, 0x2, 0x0, - 0xa, - 0x0, + 0x5, + 0x2, 0x2, - 0x3, 0x6, - 0x0, 0x1, - 0x8, - 0x1, - 0x4, - 0x0, + 0x5, 0x3, 0x2, - 0x1, + 0x5, 0x2, - 0x7, - 0x3, + 0x1, + 0x1, 0x0, 0x4, - 0x3, + 0x2, 0x0, - 0x4, + 0x2, 0x0, 0x0, - 0x1, + 0x5, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x9, + 0x2, 0x0, 0x0, 0x0, - 0x1, + 0x15, 0x2, 0x0, 0x0, 0x1, 0x2, 0x7, - 0x2, - 0xa, + 0x3, + 0x3, + 0x3, 0x1, - 0x0, 0x1, + 0x2, + 0x6, 0x1, - 0xb, 0x7, 0x0, 0x0, 0x0, 0x0, - 0x1, - 0x1, - 0x0, - 0x2, - 0x0, - 0x0, - 0x2, - 0x1, - 0xa, 0x4, - 0x2, - 0x7, - 0x1, - 0x2, + 0x0, + 0x3, 0x2, 0x0, 0x0, - 0x2, - 0x2, 0x1, 0x1, + 0x3, 0x1, - 0x0, 0x1, 0x0, - 0x3, 0x1, - 0x0, 0x1, + 0x5, 0x0, - 0x0, - 0x0, - 0x0, - 0x3, - 0x2, - 0x2, - 0x2, - 0x0, - 0x0, - 0x1, 0x1, + 0x5, + 0x4, + 0x8, 0x2, 0x1, 0x0, @@ -19623,154 +19728,178 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x7, - 0x2, - 0x3, - 0x6, 0x3, - 0x4, + 0x1, 0x1, 0x0, - 0x2, - 0xb, 0x0, - 0x5, + 0x4, 0x3, - 0x2, 0x1, + 0x4, 0x0, + 0x4, 0x0, - 0x0, - 0xc, 0x2, - 0x1, - 0x3, - 0x3, - 0x1, + 0x2, 0x3, 0x0, - 0x6, 0x1, 0x0, 0x0, - 0x7, - 0x0, - 0x0, - 0xa, - 0x0, 0x0, + 0x1, + 0x5, 0x0, + 0x2, + 0x4, + 0x2, + 0x1, + 0x6, 0x0, - 0x3, + 0x1, + 0xf, 0x0, 0x2, + 0x5, 0x0, 0x2, + 0x0, 0x3, + 0x4, + 0x2, + 0x4, 0x3, + 0x5, 0x1, 0x1, - 0x3, - 0x3, - 0x0, - 0x3, 0x1, + 0x7, 0x0, - 0xa, + 0x7, + 0x2, 0x0, - 0x1, + 0x0, + 0x6, 0x0, 0x0, 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x3, + 0x0, + 0x3, + 0x0, 0x1, 0x2, + 0x7, 0x1, + 0x7, + 0x3, 0x1, + 0x0, + 0x2, 0x2, 0x0, 0x5, + 0x0, + 0x3, + 0x0, + 0x0, 0x2, 0x1, - 0x7, + 0x1, + 0x1, + 0x2, + 0x2, 0x2, - 0x3, 0x0, + 0x1, 0x4, - 0x3, 0x2, 0x1, 0x2, + 0x3, + 0x0, + 0x2, + 0x2, + 0x4, + 0x2, 0x1, - 0x1, + 0x2, + 0x2, 0x0, 0x0, 0x1, 0x0, - 0x1, + 0x2, 0x0, - 0x1, + 0x7, 0x1, 0x0, - 0x3, - 0x1, - 0x1, 0x1, + 0x4, + 0x3, + 0x3, 0x1, - 0x2, + 0x5, 0x1, 0x0, 0x0, - 0x6, + 0x3, 0x0, 0x1, - 0x1, + 0x6, 0x1, 0x0, - 0x4, - 0x4, + 0x2, 0xd, + 0x1, 0x0, 0x0, 0x4, 0x0, + 0xf, 0x2, - 0x3, 0x0, - 0x3, + 0xa, + 0x2, + 0x1, + 0x0, 0x1, - 0xc, 0x0, + 0x4, 0x2, 0x0, 0x3, - 0x1, - 0x3, 0x0, 0x2, - 0x5, - 0xb, 0x0, + 0x7, + 0x2, 0x1, 0x0, 0x0, - 0x1, - 0x0, 0x3, 0x0, - 0x0, 0x4, 0x0, 0x0, - 0x2, - 0x2, - 0x3, - 0x1, + 0xb, + 0x0, + 0x0, + 0xa, + 0x5, + 0x9, 0x1, 0x0, + 0x3, 0x1, 0x0, + 0xc, 0x0, - 0x2, 0x0, 0x0, 0x0, @@ -19778,243 +19907,247 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x1, 0x0, 0x2, - 0x5, - 0x3, - 0x0, - 0x1, - 0x5, 0x1, + 0x2, 0x0, 0x1, + 0x3, + 0x2, + 0x0, + 0x7, 0x0, 0x0, - 0x5, + 0x3, 0x0, 0x0, - 0x8, + 0x6, 0x2, 0x0, 0x0, - 0x3, + 0x6, 0x0, 0x0, - 0x3, + 0x4, + 0x2, + 0x1, + 0x1, 0x0, + 0x7, 0x2, + 0x4, + 0x1, + 0x5, 0x0, 0x0, 0x1, + 0x2, 0x0, 0x2, + 0x3, + 0x8, 0x1, + 0x6, 0x2, - 0x0, - 0x0, 0x1, - 0x0, - 0x0, 0x1, 0x0, 0x3, - 0x4, + 0x5, + 0x0, 0x2, - 0x6, 0x1, - 0x6, + 0x1, 0x3, 0x0, - 0x2, - 0x7, 0x3, + 0x7, 0x1, - 0x1, - 0x0, - 0x2, 0x0, 0x1, 0x0, - 0x1, 0x0, 0x0, + 0x3, 0x0, 0x1, - 0x0, - 0x2, - 0x7, - 0x3, 0x1, - 0xa, - 0x2, - 0x0, 0x1, + 0x1, + 0x6, + 0x5, + 0x0, + 0x5, 0x4, 0x0, - 0x3, + 0x0, 0x3, 0x1, 0x2, 0x0, - 0xd, - 0x2, 0x0, - 0x1, + 0x2, 0x0, + 0x2, + 0x2, 0x0, 0x2, 0x0, - 0x1, + 0x4, 0x1, 0x0, 0x2, - 0x5, + 0x0, 0x4, 0x1, 0x1, - 0x0, + 0x4, + 0x2, 0x1, 0x0, - 0x0, + 0x1, 0x2, - 0x3, 0x1, + 0x3, 0x0, 0x0, 0x1, - 0x1, - 0x2, + 0x0, + 0xb, 0x2, 0x0, 0x0, - 0x7, - 0x4, + 0x3, + 0x3, + 0x5, 0x1, 0x1, + 0x0, + 0x1, 0x2, - 0x2, - 0x2, - 0x4, 0x1, 0x0, 0x0, 0x0, - 0x3, + 0x8, 0x1, + 0x4, 0x3, - 0x2, 0x0, - 0x2, + 0x7, 0x1, + 0x3, 0x1, - 0x2, 0x0, - 0x4, - 0x4, 0x2, + 0x3, + 0x3, 0x1, 0x0, 0x1, 0x1, - 0x3, 0x1, 0x0, + 0x2, 0x0, - 0x6, 0x1, 0x1, 0x1, + 0x4, + 0x2, + 0x5, + 0x0, 0x1, 0x1, 0x0, - 0x2, - 0x3, - 0x3, - 0x2, + 0x1, 0x2, 0x0, 0x0, 0x0, - 0x1, 0x0, + 0x3, 0x1, 0x2, 0x1, + 0x3, 0x1, - 0xa, - 0x4, + 0x0, + 0x5, 0x2, - 0x1, + 0x4, 0x0, 0x3, 0x0, 0x0, - 0x2, - 0x5, - 0x5, + 0x1, + 0x3, + 0x7, 0x0, 0x6, 0x4, 0x0, - 0x9, + 0x1, + 0x2, 0x2, 0x3, - 0x4, - 0x9, + 0x5, 0x0, - 0x1, - 0x1, + 0x8, + 0x3, 0x3, - 0x1, 0x2, + 0x1, 0x7, - 0xb, + 0x2, 0x1, 0x1, 0x1, 0x1, - 0x5, - 0x2, 0x0, - 0x2, - 0x6, - 0x2, - 0x4, + 0x8, 0x0, + 0x1, + 0x3, 0x0, + 0x2, 0x1, + 0x0, 0x1, + 0x2, 0x0, 0x0, - 0x1, + 0x6, + 0x7, 0x1, 0x0, - 0x2, + 0x3, 0x0, 0x0, 0x0, - 0x5, + 0x1, 0x2, 0x0, 0x0, 0x1, - 0x0, 0x1, - 0x4, + 0x1, 0x0, 0x1, - 0x3, + 0x4, + 0x2, 0x0, 0x0, - 0x5, + 0x1, 0x0, 0x0, 0x0, - 0x4, - 0x1, - 0x1, 0x5, - 0x1, + 0x2, 0x3, 0x1, + 0x2, + 0x0, + 0x6, 0x1, 0x0, 0x1, @@ -20022,16 +20155,16 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0x1, + 0x2, 0x0, - 0x4, - 0x1, + 0x2, + 0x3, 0x0, 0x2, - 0x4, + 0x7, 0x1, 0x0, - 0x2, + 0x0, 0x2, 0x0, 0x0, @@ -20039,210 +20172,214 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x3, + 0x1, 0x0, 0x0, - 0x3, + 0x2, 0x0, 0x1, 0x0, 0x4, - 0x6, + 0x2, 0x0, + 0x11, 0x5, - 0x1, + 0x4, + 0x0, + 0x4, 0x0, 0x0, + 0x2, + 0x0, + 0x7, + 0x0, 0x1, 0x0, 0x0, + 0x1, + 0x5, + 0x1, 0x2, 0x2, + 0xe, 0x0, - 0x2, - 0x1, 0x0, 0x2, - 0x2, 0x1, - 0x2, - 0x9, - 0x5, - 0x0, 0x0, + 0x1, 0x0, 0x3, + 0x1, + 0x2, + 0x1, 0x0, + 0xa, 0x1, + 0x4, 0x0, 0x5, 0x1, - 0x8, 0x1, - 0x0, - 0x2, 0x1, 0x2, - 0x0, - 0x5, - 0x2, 0x1, 0x1, - 0x3, - 0x2, 0x1, - 0x5, 0x0, 0x0, - 0x3, - 0x3, 0x1, + 0x8, 0x1, - 0x2, 0x1, 0x0, + 0x1, 0x0, 0x0, - 0x3, + 0x0, + 0x0, + 0x1, 0x3, 0x1, + 0xf, 0x1, - 0x3, + 0x2, 0x1, 0x1, - 0x5, 0x0, 0x0, 0x2, - 0x2, - 0x0, - 0x0, - 0x0, 0x1, - 0x2, - 0x3, - 0x0, - 0x2, 0x0, - 0x2, - 0x4, - 0x3, - 0x2, - 0x2, 0x0, 0x3, - 0xc, 0x0, 0x1, + 0x0, + 0x0, 0x1, 0x0, - 0x2, 0x5, + 0x7, + 0x2, 0x2, + 0x6, 0x0, - 0x3, 0x1, 0x0, + 0x2, 0x1, + 0x4, + 0x0, + 0x2, 0x1, - 0x5, 0x3, 0x2, + 0x2, + 0x1, 0x0, 0x3, - 0x0, - 0x4, 0x2, - 0x0, + 0x4, + 0x3, 0x1, + 0x0, 0x1, 0x0, - 0x2, 0x1, 0x1, 0x3, 0x0, 0x1, - 0x1, - 0x1, - 0x0, - 0x2, - 0x0, 0x0, 0x2, + 0x6, + 0x5, 0x1, + 0x9, 0x0, - 0x5, - 0x2, + 0x3, + 0x1, 0x0, + 0x6, 0x0, - 0x1, - 0x1, 0x0, 0x3, 0x0, + 0x1, 0x0, 0x2, 0x2, - 0x1, - 0x3, 0x0, 0x3, - 0x3, - 0x2, 0x1, + 0x0, 0x1, 0x0, + 0x0, + 0x8, 0x1, 0x2, - 0x3, 0x1, 0x0, 0x2, - 0x7, + 0x4, 0x1, + 0x2, + 0x1, + 0x5, + 0x0, + 0x1, + 0x2, + 0x2, 0x1, 0x0, - 0x3, 0x1, 0x1, 0x2, 0x1, 0x0, - 0xb, + 0x2, + 0x3, + 0x1, 0x1, + 0x3, 0x0, - 0x6, + 0x1, + 0x1, 0x0, - 0x3, - 0xc, 0x5, 0x0, - 0x4, - 0xa, 0x2, + 0x6, + 0x1, 0x0, - 0x8, - 0x2, + 0x4, + 0x0, + 0x1, 0x0, 0x0, - 0x3, 0x1, 0x2, + 0x0, + 0x3, + 0x0, + 0x1, 0x1, 0x0, 0x0, 0x2, 0x0, 0x2, - 0x4, + 0x0, 0x1, 0x0, 0x0, 0x0, - 0x4, + 0x2, 0x0, - 0x9, + 0x0, + 0x1, 0x3, 0x2, 0x0, @@ -20250,239 +20387,243 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x1, 0x0, - 0x3, - 0x0, + 0x4, 0x0, 0x0, 0x1, - 0x0, 0x1, 0x0, 0x2, + 0x0, 0x2, - 0x5, + 0x1, + 0x1, + 0x1, + 0x0, 0x0, - 0x5, 0x0, 0x0, 0x0, + 0xb, + 0x4, 0x0, 0x1, - 0x3, - 0x3, 0x0, + 0x1, + 0x5, 0x0, 0x1, 0x1, 0x0, - 0x2, - 0x3, - 0x0, - 0x1, + 0x5, 0x1, 0x0, + 0x2, 0x4, - 0x0, - 0x1, 0x1, 0x1, - 0x3, 0x2, - 0x7, + 0x1, + 0x1, + 0x1, 0x0, 0x0, 0x0, 0x0, - 0x2, + 0x0, + 0x6, 0x0, 0x2, - 0x2, - 0x2, + 0x3, + 0x0, 0x1, 0x2, - 0x2, - 0x5, + 0x3, + 0x0, 0x0, + 0x3, + 0x2, 0x4, - 0x8, 0x0, - 0x1, 0x3, - 0x5, 0x0, - 0x1, 0x0, - 0x4, + 0x1, 0x0, 0x3, - 0x1, 0x0, - 0x4, + 0xd, 0x2, 0x0, - 0x0, - 0x5, 0x3, + 0x1, + 0x0, + 0x0, + 0x1, + 0x1, 0x3, 0x0, 0x1, 0x0, 0x4, - 0x3, - 0x3, - 0x2, + 0xd, + 0x4, 0x1, - 0x3, + 0x6, + 0x2, 0x3, 0x0, - 0x2, 0x3, - 0x2, 0x1, + 0x0, 0x2, 0x1, + 0x2, 0x0, + 0x1, 0x3, - 0xc, 0x1, + 0x2, + 0x0, 0x1, 0x2, 0x0, 0x3, - 0x0, - 0x2, + 0x1, 0x1, 0x0, - 0x4, - 0x4, 0x1, 0x2, - 0x0, 0x1, - 0x0, - 0x3, 0x3, - 0x3, - 0x1, 0x2, 0x0, + 0x0, + 0x1, + 0x1, + 0x0, + 0x1, 0x1, - 0x12, 0x3, + 0x4, + 0x1, 0x2, + 0x3, 0x0, 0x2, - 0xa, - 0x5, + 0x3, + 0x2, 0x1, 0x1, + 0x7, 0x2, - 0xd, 0x0, - 0x2, + 0x1, 0x0, 0x0, 0x2, 0x0, - 0x1, 0x2, - 0x4, - 0x3, + 0x5, + 0x1, + 0x1, 0x0, 0x0, 0x1, 0x1, - 0x1, + 0x2, 0x0, 0x1, - 0x1, + 0x3, 0x0, 0x1, - 0x5, + 0x2, + 0x0, 0x0, + 0x5, 0x0, 0x2, - 0x1, 0x0, 0x1, - 0xb, 0x0, 0x1, - 0x8, + 0x3, 0x1, 0x0, 0x0, + 0x3, + 0x5, + 0x5, 0x0, 0x1, - 0x0, - 0x0, + 0x3, 0x1, 0x2, - 0x1, 0x0, 0x0, 0x3, - 0x6, - 0x1, + 0x2, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x4, - 0x1, 0x0, 0x1, + 0x6, + 0x0, 0x1, 0x1, + 0x2, 0x1, 0x0, - 0x2, - 0x2, 0x1, 0x4, - 0x8, 0x1, + 0x2, + 0x1, + 0x8, 0x1, 0x1, 0x0, 0x0, - 0x2, + 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x2, + 0x3, 0x0, - 0x4, - 0x1, - 0x2, 0x2, + 0x1, + 0x7, + 0x1, 0x0, 0x6, 0x0, 0x1, 0x0, 0x0, - 0x4, - 0x0, 0x1, 0x0, - 0x1, + 0x6, + 0x3, + 0x2, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x1, - 0x1, - 0x2, 0x0, - 0x1, + 0x3, 0x0, + 0x1, 0x0, 0x1, - 0x3, + 0x1, + 0x1, 0x1, 0x0, 0x0, @@ -20490,3954 +20631,4019 @@ pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0x2, + 0x4, + 0x0, + 0x1, 0x0, + 0x3, 0x2, - 0x4, - 0x5, 0x0, - 0x6, 0x0, 0x0, - 0x5, - 0x2, 0x3, + 0x8, + 0x7, 0x0, 0x0, 0x0, 0x2, - 0x2, + 0x1, + 0x0, 0x0, 0x0, 0x0, 0x2, - 0x3, 0x0, 0x1, - 0x8, - 0xa, - 0x3, - 0x0, + 0x2, 0x0, 0x1, 0x0, + 0x0, 0x1, - 0x3, 0x1, 0x2, + 0x3, + 0x1, 0x1, 0x0, - 0x4, + 0x2, + 0x7, 0x4, 0x0, 0x0, - 0x1, + 0x6, + 0x0, 0x0, 0x0, 0x0, 0x1, - 0x8, + 0x0, + 0x2, 0x1, 0x0, - 0x3, - 0x4, - 0x3, 0x2, 0x1, + 0x3, 0x1, - 0x4, + 0x2, 0x0, 0x1, - 0x1, + 0x4, + 0x2, + 0x2, 0x1, 0x0, - 0x1, - 0xc, + 0x2, 0x0, 0x0, 0x0, - 0x3, - 0x3, 0x1, - 0x7, - 0x3, + 0x0, + 0x6, + 0x8, + 0x5, 0x1, 0x0, - 0x3, + 0x8, 0x0, 0x6, - 0x2, - 0x0, 0x1, 0x0, - 0x2, + 0xc, + 0x3, + 0x5, 0x0, - 0x4, - 0x4, 0x2, 0x1, - 0x1, 0x5, 0x1, 0x1, - 0x1, - 0x2, - 0x3, - 0x0, + 0x4, 0x3, 0x1, + 0x1, + 0x5, + 0x6, + 0x1, + 0x2, + 0x7, 0x3, 0x2, 0x0, - 0xf, + 0x0, + 0x1, 0x0, 0x1, 0x2, - 0x5, 0x1, 0x1, - 0x0, - 0x2, 0x1, + 0x0, 0x1, + 0x2, + 0x2, 0x0, - 0x4, - 0x3, - 0x3, + 0x2, 0x3, - 0x4, 0x1, 0x1, 0x0, 0x1, + 0x0, 0x1, - 0x1, + 0x5, + 0x5, + 0x2, 0x0, 0x0, 0x1, - 0x1, 0x2, + 0x4, 0x1, - 0x7, 0x0, - 0x6, - 0x6, - 0xc, + 0x0, 0x1, 0x3, - 0x3, - 0x0, + 0x8, 0x1, - 0x2, + 0x6, + 0x0, + 0x0, + 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, - 0x0, 0x1, 0x0, - 0x6, - 0x7, + 0x5, + 0x0, 0x1, - 0x6, + 0x0, + 0x5, 0x1, - 0x2, - 0x4, 0x4, - 0x3, - 0x2, - 0x0, + 0x1, + 0x8, 0x0, + 0x1, 0x4, 0x0, - 0x1, - 0x2, 0x0, - 0x3, 0x2, 0x0, + 0x3, + 0x1, 0x0, 0x1, + 0x2, + 0x2, 0x0, - 0x3, + 0x2, 0x0, 0x0, 0x1, 0x0, 0x5, 0x3, + 0x1, + 0x2, 0x3, - 0x0, 0x1, + 0xc, + 0x3, 0x0, - 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, + 0x3, 0x0, 0x1, - 0x1, - 0x1, + 0x5, + 0x3, + 0x2, 0x1, 0x0, - 0x1, - 0x1, + 0x3, + 0x2, 0x0, ]; pub(crate) const COMPATIBILITY_DECOMPOSED_KV: &[(u32, (u16, u16))] = &[ - (0xfee5, (3971, 1)), - (0x332a, (1837, 3)), - (0x1d40e, (4305, 1)), - (0xfc8f, (2976, 2)), - (0xff18, (4032, 1)), + (0x1d5e5, (4752, 1)), + (0x1d430, (4339, 1)), + (0xfca0, (3015, 2)), + (0x1d769, (5138, 1)), + (0xfe55, (3808, 1)), (0xfd72, (3438, 3)), (0xb2, (6, 1)), - (0x1d5c5, (4720, 1)), - (0x1d43f, (4354, 1)), + (0x333b, (1909, 5)), + (0xfbae, (2585, 1)), (0x1d727, (5072, 1)), - (0x3256, (1432, 2)), - (0x3289, (1514, 1)), + (0x246d, (573, 2)), + (0x332c, (1846, 4)), (0x1d79a, (5187, 1)), - (0x24e1, (830, 1)), - (0xfc9e, (3011, 2)), - (0x207d, (332, 1)), - (0xff66, (4110, 1)), - (0xff47, (4079, 1)), + (0xfd81, (3483, 3)), + (0xff07, (4015, 1)), + (0x1d76b, (5140, 1)), + (0x2fb1, (1034, 1)), + (0x1d4ef, (4518, 1)), (0x3193, (1179, 1)), (0xfbec, (2621, 3)), (0x1d410, (4307, 1)), (0x2177, (527, 4)), - (0x107a1, (4266, 1)), - (0xfd63, (3393, 3)), - (0x330c, (1717, 4)), + (0xfcfa, (3200, 2)), + (0x1ee8e, (5451, 1)), + (0xfed8, (3958, 1)), (0x32b8, (1568, 2)), - (0x3218, (1274, 4)), - (0x1d703, (5036, 1)), + (0xfb7f, (2536, 1)), + (0x1d5f4, (4767, 1)), (0x33e0, (2351, 2)), + (0x1e055, (5324, 1)), (0xffac, (4180, 1)), (0x1e9a, (234, 2)), - (0xff9b, (4163, 1)), - (0x2101, (368, 3)), - (0x2f93, (1004, 1)), + (0xfdf7, (3716, 4)), + (0x1d493, (4437, 1)), + (0x2085, (340, 1)), (0x2148, (433, 1)), - (0x32cc, (1611, 2)), + (0x1d4e9, (4512, 1)), (0x1d73c, (5093, 1)), (0x1da8, (210, 1)), (0xfeba, (3928, 1)), - (0x1f127, (5519, 3)), (0x1d48e, (4432, 1)), - (0x1d531, (4579, 1)), - (0x1d623, (4814, 1)), - (0x2492, (679, 3)), - (0x1d798, (5185, 1)), - (0x1db8, (226, 1)), - (0x2fc2, (1051, 1)), - (0x1d594, (4671, 1)), + (0x1ee6c, (5422, 1)), + (0x1d628, (4819, 1)), + (0x1d6d1, (4986, 1)), + (0x2130, (413, 1)), + (0xff6c, (4116, 1)), + (0x1d7b4, (5213, 1)), + (0x1da4, (206, 1)), + (0x1e061, (5336, 1)), (0x3224, (1319, 3)), - (0xffdb, (4218, 1)), + (0x3229, (1334, 3)), (0x1d7ff, (5286, 1)), - (0x1d4bd, (4469, 1)), + (0x1d657, (4866, 1)), (0xfee9, (3975, 1)), - (0x2fa2, (1019, 1)), + (0x32f6, (1659, 1)), (0xfc13, (2716, 2)), - (0xff34, (4060, 1)), - (0xfda8, (3594, 3)), - (0x1d560, (4619, 1)), + (0x1d46e, (4400, 1)), + (0x2472, (583, 2)), + (0x1d6ba, (4963, 1)), (0xfd05, (3222, 2)), - (0xffb4, (4188, 1)), - (0x1d5a8, (4691, 1)), + (0x33d7, (2328, 2)), + (0xfc17, (2724, 2)), (0x2170, (513, 1)), - (0x1ee75, (5368, 1)), + (0xfd1c, (3268, 2)), (0x3382, (2123, 2)), - (0xff5d, (4101, 1)), - (0x1ee95, (5396, 1)), - (0x3325, (1824, 3)), - (0x1d672, (4893, 1)), - (0xfceb, (3167, 2)), + (0x1d764, (5133, 1)), + (0x1ee95, (5458, 1)), + (0x2f24, (893, 1)), + (0x32e5, (1642, 1)), + (0x1d409, (4300, 1)), (0x1d43, (157, 1)), - (0xfec2, (3936, 1)), - (0x2f15, (878, 1)), + (0x1d597, (4674, 1)), + (0x2f81, (986, 1)), (0xfc4a, (2826, 2)), - (0x1d6b3, (4956, 1)), + (0x1d713, (5052, 1)), (0x1d7a1, (5194, 1)), - (0x1d47b, (4413, 1)), + (0xff74, (4124, 1)), (0xff7d, (4133, 1)), - (0x1d4fb, (4530, 1)), - (0xfca7, (3029, 2)), - (0x2f7d, (982, 1)), + (0x2483, (638, 4)), + (0x3323, (1817, 3)), + (0x1e059, (5328, 1)), (0x1d558, (4611, 1)), + (0xfc37, (2788, 2)), (0x2f64, (957, 1)), - (0xfb78, (2529, 1)), + (0xfe58, (3811, 1)), (0x32ee, (1651, 1)), - (0x326e, (1466, 2)), + (0xfc6a, (2902, 2)), (0x1d466, (4392, 1)), - (0xfd5c, (3372, 3)), (0x207e, (333, 1)), - (0x1078c, (4245, 1)), - (0x1ee37, (5335, 1)), - (0x24d7, (820, 1)), - (0x1eeb6, (5422, 1)), - (0x1d576, (4641, 1)), - (0x2f27, (896, 1)), + (0x1e050, (5319, 1)), + (0x1d5ed, (4760, 1)), + (0xfc97, (2992, 3)), + (0x1d791, (5178, 1)), + (0x1d7bd, (5222, 1)), + (0x314d, (1112, 1)), + (0x33aa, (2219, 3)), (0xfc0c, (2702, 2)), - (0x325e, (1448, 2)), - (0xfc40, (2806, 2)), - (0x1d772, (5147, 1)), - (0x1d5cd, (4728, 1)), + (0x2f47, (928, 1)), + (0x3230, (1355, 3)), + (0xfdc6, (3684, 3)), + (0x1d614, (4799, 1)), (0x3291, (1522, 1)), - (0x2f26, (895, 1)), - (0x2e9f, (855, 1)), - (0x1d467, (4393, 1)), - (0x33cf, (2309, 2)), - (0x3251, (1422, 2)), - (0xfb8e, (2551, 1)), - (0x1d65e, (4873, 1)), - (0x1db5, (223, 1)), - (0x1d5b6, (4705, 1)), - (0x313e, (1097, 1)), - (0xffd4, (4213, 1)), - (0x1d56c, (4631, 1)), - (0xfe4d, (3801, 1)), - (0x1d426, (4329, 1)), + (0xfe31, (3771, 1)), + (0x1d706, (5039, 1)), + (0xfe78, (3842, 2)), + (0x325a, (1440, 2)), + (0x2f84, (989, 1)), + (0xfca1, (3017, 2)), + (0x24bb, (792, 1)), + (0x2094, (354, 1)), + (0x1d4f8, (4527, 1)), + (0xfcfe, (3208, 2)), + (0x1d487, (4425, 1)), + (0x1d6fd, (5030, 1)), + (0x1d559, (4612, 1)), + (0x2074, (323, 1)), (0x2112, (391, 1)), - (0xfe44, (3790, 1)), - (0x1d57a, (4645, 1)), + (0xfcd5, (3121, 2)), + (0x2f06, (863, 1)), (0x107ba, (4290, 1)), - (0x1dbf, (233, 1)), - (0xfb24, (2481, 1)), + (0xa7f4, (2443, 1)), + (0x24bf, (796, 1)), (0x1d49c, (4446, 1)), - (0xfc34, (2782, 2)), - (0x1d579, (4644, 1)), - (0x1f220, (5606, 1)), - (0xfec1, (3935, 1)), + (0x1d63c, (4839, 1)), + (0x32a2, (1539, 1)), + (0x1f220, (5668, 1)), + (0x1d60f, (4794, 1)), (0x32d5, (1626, 1)), (0xfcec, (3169, 2)), - (0x2f89, (994, 1)), - (0x33c1, (2276, 2)), - (0xfc03, (2682, 3)), + (0xfc49, (2824, 2)), + (0xfe70, (3830, 2)), + (0x2f45, (926, 1)), (0x33b8, (2258, 2)), - (0x248a, (662, 2)), + (0x2e2, (85, 1)), + (0x2fba, (1043, 1)), (0x32c6, (1596, 2)), - (0x208c, (347, 1)), - (0x1d680, (4907, 1)), - (0x1d58c, (4663, 1)), + (0x1ee87, (5445, 1)), + (0xffb3, (4187, 1)), (0xfb71, (2522, 1)), - (0x3039, (1074, 1)), - (0x2138, (420, 1)), - (0x320c, (1228, 3)), - (0x1d46d, (4399, 1)), + (0xff0b, (4019, 1)), + (0xfd26, (3288, 2)), + (0xfc63, (2881, 3)), + (0x3131, (1084, 1)), + (0xff6f, (4119, 1)), (0x24b9, (790, 1)), (0x32b1, (1554, 2)), - (0x1d66a, (4885, 1)), - (0x2475, (590, 3)), - (0x1d403, (4294, 1)), - (0x1db6, (224, 1)), - (0x1d473, (4405, 1)), + (0xfda0, (3570, 3)), + (0x1d72e, (5079, 1)), + (0x1d64d, (4856, 1)), + (0xfb8f, (2552, 1)), + (0x1e03c, (5299, 1)), (0xfd39, (3326, 2)), (0xfd8b, (3513, 3)), (0x1079a, (4259, 1)), (0xfb95, (2558, 1)), (0x107af, (4280, 1)), - (0xff35, (4061, 1)), - (0x209b, (361, 1)), - (0x319e, (1190, 1)), + (0x1f16c, (5642, 2)), + (0x1d793, (5180, 1)), (0x1d437, (4346, 1)), - (0x10788, (4241, 1)), - (0x1ee22, (5319, 1)), + (0x3282, (1507, 1)), + (0xbe, (21, 3)), + (0x2c7d, (853, 1)), (0xfec8, (3942, 1)), - (0x1d52d, (4575, 1)), - (0xfd79, (3459, 3)), + (0xfc99, (2998, 3)), + (0x337d, (2111, 2)), (0x3290, (1521, 1)), - (0x32ef, (1652, 1)), (0x2f0d, (870, 1)), - (0x1d6a1, (4940, 1)), - (0x1d6b8, (4961, 1)), - (0xfc70, (2914, 2)), - (0xfcb6, (3059, 2)), - (0x2f11, (874, 1)), - (0x1d781, (5162, 1)), - (0x1d6d1, (4986, 1)), - (0x3305, (1692, 3)), + (0x1d6be, (4967, 1)), + (0x1d5c6, (4721, 1)), + (0xff38, (4064, 1)), + (0xfda9, (3597, 3)), + (0x1d690, (4923, 1)), + (0x1d42d, (4336, 1)), + (0x1d524, (4566, 1)), + (0x3f5, (108, 1)), + (0x1d68f, (4922, 1)), (0x1d5af, (4698, 1)), - (0x1d431, (4340, 1)), + (0xfd5e, (3378, 3)), (0xfef7, (3993, 3)), (0x33e8, (2367, 2)), - (0xfcc5, (3089, 2)), - (0x24a9, (748, 3)), - (0x1d38, (147, 1)), - (0xfb9a, (2563, 1)), - (0xfb21, (2478, 1)), - (0x1f245, (5649, 3)), - (0x33ee, (2384, 3)), - (0x1d685, (4912, 1)), + (0x1d4cc, (4483, 1)), + (0x1d42f, (4338, 1)), + (0xfe10, (3757, 1)), + (0x1d57e, (4649, 1)), + (0x107b7, (4287, 1)), + (0x1d499, (4443, 1)), + (0x1ee0f, (5363, 1)), + (0xfc96, (2990, 2)), (0x1d4d2, (4489, 1)), - (0x328a, (1515, 1)), - (0x1d694, (4927, 1)), - (0x1d7b9, (5218, 1)), + (0xffe9, (4229, 1)), + (0xffa5, (4173, 1)), + (0x3299, (1530, 1)), (0x1d5c4, (4719, 1)), - (0x1d6b6, (4959, 1)), - (0x2f4d, (934, 1)), + (0xfe5c, (3815, 1)), + (0x17f, (34, 1)), (0x1d7ea, (5265, 1)), - (0x33d0, (2311, 2)), + (0x1d4b0, (4458, 1)), (0x1d5be, (4713, 1)), (0x33d9, (2334, 3)), (0x32e7, (1644, 1)), - (0x1d4e3, (4506, 1)), + (0x1d6e2, (5003, 1)), + (0xffad, (4181, 1)), (0xfcae, (3043, 2)), - (0x3147, (1106, 1)), - (0x2121, (403, 3)), - (0x1d561, (4620, 1)), - (0x1d41e, (4321, 1)), + (0xfcda, (3131, 2)), + (0xfc1b, (2732, 2)), + (0x2f62, (955, 1)), + (0x320a, (1222, 3)), (0x3f9, (109, 1)), - (0xff86, (4142, 1)), (0xfdc1, (3669, 3)), - (0xff20, (4040, 1)), - (0xfedd, (3963, 1)), - (0x1f228, (5614, 1)), - (0x1d6ae, (4951, 1)), - (0xff65, (4109, 1)), - (0xfc78, (2930, 2)), - (0xfdaf, (3615, 3)), - (0x1f11b, (5483, 3)), - (0xfc51, (2840, 2)), - (0x3223, (1316, 3)), - (0x2f3f, (920, 1)), - (0x1d4e9, (4512, 1)), + (0x2f72, (971, 1)), + (0x316d, (1144, 1)), + (0x322b, (1340, 3)), + (0x2157, (457, 3)), + (0x1d659, (4868, 1)), + (0x1d3c, (150, 1)), + (0x333e, (1923, 4)), + (0x217e, (541, 1)), + (0x1f11b, (5545, 3)), + (0x1ee74, (5429, 1)), + (0x1d458, (4378, 1)), + (0xfbfa, (2663, 3)), (0xfeb3, (3921, 1)), (0xfb5f, (2504, 1)), + (0x2fc9, (1058, 1)), (0x315a, (1125, 1)), - (0xedd, (126, 2)), - (0x2e0, (83, 1)), + (0x1d4a9, (4452, 1)), + (0xfd31, (3310, 2)), (0x3139, (1092, 1)), - (0x1c4, (35, 3)), + (0x1db0, (218, 1)), (0x1d4f3, (4522, 1)), - (0x24c8, (805, 1)), - (0xfd1a, (3264, 2)), - (0xfbdd, (2601, 2)), - (0xfe57, (3810, 1)), - (0x1ee94, (5395, 1)), - (0x1d6d7, (4992, 1)), - (0xfdf5, (3708, 4)), - (0x1f13c, (5549, 1)), + (0xfccf, (3109, 2)), + (0xfb80, (2537, 1)), + (0xfc6e, (2910, 2)), + (0x1d768, (5137, 1)), + (0x2b6, (68, 1)), + (0x333a, (1905, 4)), + (0x1d7c9, (5234, 1)), + (0x1f13c, (5611, 1)), (0x1d6a2, (4941, 1)), (0x2006, (281, 1)), (0x1d445, (4360, 1)), - (0x2fc4, (1053, 1)), - (0x2f0a, (867, 1)), - (0x3180, (1163, 1)), - (0x2f14, (877, 1)), - (0xfe6a, (3828, 1)), - (0x1d765, (5134, 1)), - (0xfe59, (3812, 1)), + (0x1d763, (5132, 1)), + (0x1d5fa, (4773, 1)), + (0x3241, (1406, 3)), + (0xfe4a, (3795, 2)), + (0x326d, (1465, 1)), + (0x1d6c2, (4971, 1)), + (0xfd7d, (3471, 3)), (0x3370, (2080, 3)), - (0x1d718, (5057, 1)), + (0x1d6bb, (4964, 1)), (0x1d78f, (5176, 1)), - (0xfb00, (2451, 2)), - (0x1d6ac, (4949, 1)), + (0x1d4e6, (4509, 1)), + (0xff12, (4026, 1)), (0xfb05, (2463, 2)), - (0x1ee1b, (5313, 1)), - (0x216a, (504, 2)), - (0x1d628, (4819, 1)), - (0x32a3, (1540, 1)), - (0x3366, (2050, 3)), - (0x1d514, (4552, 1)), + (0x1ee1b, (5375, 1)), + (0x1d609, (4788, 1)), + (0xfe79, (3844, 2)), + (0xfbf6, (2651, 3)), + (0x1d780, (5161, 1)), + (0xfd38, (3324, 2)), (0x1d4de, (4501, 1)), (0x3182, (1165, 1)), - (0x1d546, (4597, 1)), - (0x1d7f0, (5271, 1)), - (0x1d458, (4378, 1)), - (0xfba4, (2573, 2)), - (0x3225, (1322, 3)), - (0x1ee15, (5307, 1)), - (0x1d4af, (4457, 1)), - (0xfc7e, (2942, 2)), - (0x1d6f4, (5021, 1)), - (0x1d7ed, (5268, 1)), - (0x1d5fd, (4776, 1)), - (0x3240, (1403, 3)), - (0x3295, (1526, 1)), - (0x2fc8, (1057, 1)), - (0x1d4d9, (4496, 1)), - (0x1d57c, (4647, 1)), - (0x1ee79, (5371, 1)), - (0xfd8c, (3516, 3)), + (0xfe48, (3792, 1)), + (0xfe5e, (3817, 1)), + (0x1ee1c, (5376, 1)), + (0x3319, (1774, 6)), + (0x323f, (1400, 3)), + (0x2f03, (860, 1)), + (0x1d566, (4625, 1)), + (0xfcf3, (3184, 3)), + (0x1d581, (4652, 1)), + (0x1d6eb, (5012, 1)), + (0x1e047, (5310, 1)), + (0x3301, (1675, 4)), + (0x2fa8, (1025, 1)), + (0x249b, (706, 3)), + (0xff70, (4120, 1)), + (0x1f219, (5661, 1)), + (0x1d441, (4356, 1)), + (0xfce9, (3163, 2)), (0x32cd, (1613, 3)), + (0x1d70d, (5046, 1)), (0xff61, (4105, 1)), - (0x210f, (388, 1)), + (0x2496, (691, 3)), (0x1d416, (4313, 1)), - (0xff90, (4152, 1)), + (0x3390, (2154, 2)), (0x1d756, (5119, 1)), - (0x1d78b, (5172, 1)), - (0xfd13, (3250, 2)), + (0x1e04a, (5313, 1)), + (0xfc6b, (2904, 2)), (0xfc50, (2838, 2)), - (0x24af, (766, 3)), (0x1d572, (4637, 1)), - (0xfc87, (2960, 2)), - (0x1d629, (4820, 1)), - (0x1d693, (4926, 1)), - (0x24ca, (807, 1)), - (0x1f21e, (5604, 1)), + (0xffce, (4209, 1)), + (0x2f12, (875, 1)), + (0xff95, (4157, 1)), + (0xfb99, (2562, 1)), + (0xff46, (4078, 1)), + (0xfdb7, (3639, 3)), (0x2156, (454, 3)), - (0x1d452, (4373, 1)), - (0x203c, (306, 2)), - (0x1d46a, (4396, 1)), - (0x10781, (4235, 1)), - (0x3226, (1325, 3)), - (0x1d72e, (5079, 1)), - (0x1d621, (4812, 1)), - (0xfb8d, (2550, 1)), - (0x1d510, (4548, 1)), - (0x3239, (1382, 3)), + (0xff52, (4090, 1)), + (0x1f241, (5699, 3)), + (0x1d40f, (4306, 1)), + (0x1d440, (4355, 1)), + (0x3f1, (105, 1)), + (0x2078, (327, 1)), + (0x1d66c, (4887, 1)), + (0x1f13e, (5613, 1)), + (0xfc24, (2750, 2)), + (0xfe96, (3892, 1)), (0x1d460, (4386, 1)), (0x1d6c9, (4978, 1)), (0x3330, (1865, 3)), (0x2f95, (1006, 1)), - (0x1fbf4, (5667, 1)), - (0xff9a, (4162, 1)), - (0x1d635, (4832, 1)), + (0x1d71e, (5063, 1)), + (0x1d51e, (4560, 1)), + (0x10782, (4236, 1)), (0xfc26, (2754, 2)), - (0x1d763, (5132, 1)), - (0x32bf, (1582, 2)), - (0xfd53, (3345, 3)), - (0xfc5d, (2864, 2)), + (0xfd1e, (3272, 2)), + (0x2145, (430, 1)), + (0x327b, (1492, 2)), + (0xfcbc, (3071, 2)), (0xff39, (4065, 1)), (0xfc9c, (3007, 2)), - (0x321e, (1301, 6)), - (0xfb01, (2453, 2)), - (0x212c, (410, 1)), - (0x1d7b6, (5215, 1)), - (0x1d67, (192, 1)), - (0xfe41, (3787, 1)), - (0x1f12a, (5528, 3)), - (0x32b2, (1556, 2)), + (0xfe62, (3821, 1)), + (0x1d41c, (4319, 1)), + (0x1d691, (4924, 1)), + (0x1d488, (4426, 1)), + (0x1ee4f, (5406, 1)), + (0x1d5e4, (4751, 1)), + (0x1e03d, (5300, 1)), + (0xfd55, (3351, 3)), (0xfcbd, (3073, 2)), (0x3297, (1528, 1)), - (0x1d5d2, (4733, 1)), - (0x1d607, (4786, 1)), - (0xff97, (4159, 1)), - (0x1d53c, (4589, 1)), - (0x32cb, (1608, 3)), - (0x1eeaf, (5415, 1)), - (0xfcdd, (3137, 2)), - (0x33fa, (2420, 3)), - (0xfd6e, (3426, 3)), - (0x3369, (2059, 3)), - (0x3265, (1457, 1)), + (0x1d5e0, (4747, 1)), + (0x3192, (1178, 1)), + (0x32d2, (1623, 1)), + (0x2f9e, (1015, 1)), + (0xfd1a, (3264, 2)), + (0x32e6, (1643, 1)), + (0x1eeaf, (5477, 1)), + (0x24d6, (819, 1)), + (0xfef4, (3986, 1)), + (0x1ee72, (5428, 1)), + (0x1d5d3, (4734, 1)), + (0xfd0c, (3236, 2)), (0x1d66b, (4886, 1)), - (0xfc07, (2692, 2)), - (0x32eb, (1648, 1)), - (0xfd56, (3354, 3)), + (0xff5a, (4098, 1)), + (0xfe57, (3810, 1)), + (0xfb6a, (2515, 1)), (0x1d44c, (4367, 1)), - (0x1d68c, (4919, 1)), - (0x10787, (4240, 1)), + (0x2474, (587, 3)), + (0xfdb3, (3627, 3)), (0xfb92, (2555, 1)), - (0xff44, (4076, 1)), - (0xfc23, (2748, 2)), - (0x1d570, (4635, 1)), - (0x1ee52, (5346, 1)), + (0x2098, (358, 1)), + (0x1d5a9, (4692, 1)), + (0x24b6, (787, 1)), + (0x1d626, (4817, 1)), (0xab69, (2450, 1)), - (0x3140, (1099, 1)), - (0xfd70, (3432, 3)), - (0xfeac, (3914, 1)), + (0x1d630, (4827, 1)), + (0xfb6c, (2517, 1)), + (0x1d76f, (5144, 1)), (0x3155, (1120, 1)), - (0xfc14, (2718, 2)), - (0xfc2d, (2768, 2)), + (0xfe97, (3893, 1)), + (0x1dbb, (229, 1)), (0x33bd, (2268, 2)), (0x1d54c, (4600, 1)), - (0xfbff, (2672, 1)), - (0x3d0, (95, 1)), - (0x1d574, (4639, 1)), - (0x1f112, (5456, 3)), - (0x1f21a, (5600, 1)), - (0x247f, (622, 4)), + (0x2124, (408, 1)), + (0x33d2, (2315, 3)), + (0x3236, (1373, 3)), + (0x1f112, (5518, 3)), + (0x1d37, (146, 1)), + (0x132, (24, 2)), (0x329e, (1535, 1)), - (0x1f22f, (5621, 1)), - (0xfeae, (3916, 1)), - (0x107b5, (4285, 1)), + (0x1d65a, (4869, 1)), + (0xfdf8, (3720, 4)), + (0x385, (92, 3)), (0x2f71, (970, 1)), - (0x1d4c0, (4472, 1)), - (0xfe13, (3760, 1)), - (0x1d489, (4427, 1)), + (0x1ee61, (5415, 1)), + (0xfe3d, (3783, 1)), + (0x3153, (1118, 1)), (0xfccc, (3103, 2)), (0x3203, (1201, 3)), - (0x1d476, (4408, 1)), - (0x3309, (1708, 3)), + (0xfe3f, (3785, 1)), + (0x1d550, (4604, 1)), + (0x1d6e9, (5010, 1)), (0x1d675, (4896, 1)), - (0xfcf6, (3192, 2)), - (0x1d524, (4566, 1)), - (0xfe9f, (3901, 1)), + (0x3f4, (107, 1)), + (0x1d53e, (4591, 1)), + (0x315c, (1127, 1)), (0x32ac, (1549, 1)), (0x24cd, (810, 1)), - (0x1d51b, (4558, 1)), (0xffe6, (4227, 1)), - (0xffc7, (4204, 1)), - (0x2003, (278, 1)), - (0xaa, (3, 1)), + (0x3166, (1137, 1)), + (0x1ee6d, (5423, 1)), + (0x24d3, (816, 1)), (0xffee, (4234, 1)), (0x1d777, (5152, 1)), + (0xff55, (4093, 1)), (0x1d5de, (4745, 1)), - (0x3324, (1820, 4)), - (0xfba9, (2580, 1)), - (0x215b, (469, 3)), - (0x329c, (1533, 1)), - (0x2fd4, (1069, 1)), - (0x2f87, (992, 1)), + (0x1d593, (4670, 1)), + (0x1ee2b, (5386, 1)), + (0x1d486, (4424, 1)), + (0xfd71, (3435, 3)), + (0xfef9, (3999, 3)), (0x326a, (1462, 1)), + (0x33d6, (2325, 3)), (0x3345, (1947, 3)), - (0x1ee5b, (5350, 1)), - (0xfd50, (3336, 3)), - (0x1d472, (4404, 1)), + (0x2d9, (73, 2)), + (0xfbe4, (2609, 1)), + (0x3149, (1108, 1)), (0x1d40d, (4304, 1)), - (0x2f4a, (931, 1)), + (0x1f235, (5689, 1)), (0x1d6de, (4999, 1)), - (0xfcc8, (3095, 2)), - (0x1d7c2, (5227, 1)), - (0x2fa3, (1020, 1)), - (0xfd59, (3363, 3)), + (0x677, (116, 2)), + (0x1d656, (4865, 1)), + (0x1d3d, (151, 1)), + (0x1d6f0, (5017, 1)), (0xfe34, (3774, 1)), (0x1d69c, (4935, 1)), - (0x1d501, (4536, 1)), - (0x2005, (280, 1)), + (0xfe76, (3838, 2)), + (0x1daf, (217, 1)), (0x1c5, (38, 3)), - (0x1078b, (4244, 1)), - (0x323d, (1394, 3)), - (0xaf, (4, 2)), + (0x1d739, (5090, 1)), + (0x33e4, (2359, 2)), + (0x1d6ed, (5014, 1)), (0x1d6d8, (4993, 1)), - (0x1d4ac, (4455, 1)), + (0xfc81, (2948, 2)), (0xfecd, (3947, 1)), - (0x3395, (2168, 2)), - (0x1d67a, (4901, 1)), - (0x1d74a, (5107, 1)), + (0x1d726, (5071, 1)), + (0x1e051, (5320, 1)), + (0xfc2c, (2766, 2)), (0x1d6f3, (5020, 1)), - (0x10793, (4252, 1)), - (0x322e, (1349, 3)), + (0xfc3b, (2796, 2)), + (0xfce7, (3159, 2)), (0x33b1, (2244, 2)), - (0x3154, (1119, 1)), + (0x2161, (484, 2)), (0xfe89, (3875, 2)), - (0x1d786, (5167, 1)), + (0x1d63f, (4842, 1)), + (0x1d5c9, (4724, 1)), (0x3266, (1458, 1)), - (0x1d4b8, (4466, 1)), - (0x1d7b2, (5211, 1)), - (0x1d5e2, (4749, 1)), - (0xffdc, (4219, 1)), - (0xffd7, (4216, 1)), - (0x1f139, (5546, 1)), - (0x1d49, (163, 1)), - (0x1d7e1, (5256, 1)), - (0xfd0a, (3232, 2)), + (0xfd00, (3212, 2)), + (0x1d4c, (166, 1)), + (0x1d7e3, (5258, 1)), + (0x1d62b, (4822, 1)), + (0xfdae, (3612, 3)), + (0x339c, (2182, 2)), + (0xfc8c, (2970, 2)), + (0x1d449, (4364, 1)), (0xffe2, (4222, 1)), - (0x336d, (2071, 3)), - (0xfbda, (2598, 1)), - (0x247d, (614, 4)), + (0x222f, (551, 2)), + (0xfc62, (2878, 3)), + (0x1d70a, (5043, 1)), (0x2fb3, (1036, 1)), - (0x1f242, (5640, 3)), - (0x3244, (1415, 1)), - (0xfece, (3948, 1)), - (0x24ac, (757, 3)), - (0xfc92, (2982, 2)), - (0x2470, (579, 2)), - (0x1eea3, (5405, 1)), + (0x1f239, (5693, 1)), + (0x32dc, (1633, 1)), + (0x1d7ad, (5206, 1)), + (0x3303, (1684, 3)), + (0x248b, (664, 2)), + (0x3168, (1139, 1)), + (0xfdf0, (3690, 3)), (0xff8b, (4147, 1)), - (0x1079e, (4263, 1)), + (0x1d5c1, (4716, 1)), (0x320f, (1238, 4)), - (0x1f118, (5474, 3)), - (0x1f133, (5540, 1)), - (0x1d78c, (5173, 1)), - (0x1d5a5, (4688, 1)), - (0x1d776, (5151, 1)), - (0xfec3, (3937, 1)), - (0xff9e, (4166, 1)), - (0x2f92, (1003, 1)), - (0x1d58, (177, 1)), - (0xfda1, (3573, 3)), - (0x3207, (1213, 3)), + (0x1f145, (5620, 1)), + (0x1f118, (5536, 3)), + (0xffa0, (4168, 1)), + (0x335a, (2022, 2)), + (0x1d632, (4829, 1)), + (0x33eb, (2375, 3)), + (0x2120, (401, 2)), + (0x24da, (823, 1)), + (0xff28, (4048, 1)), + (0xfeaa, (3912, 1)), + (0x2fad, (1030, 1)), (0x20a8, (363, 2)), - (0x1d4b2, (4460, 1)), - (0x2c7d, (853, 1)), - (0x3312, (1741, 4)), - (0x1ee35, (5333, 1)), - (0x1d486, (4424, 1)), - (0xfdfb, (3745, 8)), - (0xfb93, (2556, 1)), + (0x33f3, (2399, 3)), + (0x32e2, (1639, 1)), + (0x3318, (1770, 4)), + (0x1ee35, (5395, 1)), + (0x1d5cd, (4728, 1)), + (0x325f, (1450, 2)), + (0x3365, (2047, 3)), (0x1d4f, (168, 1)), - (0xff22, (4042, 1)), - (0x1d406, (4297, 1)), + (0x24e7, (836, 1)), + (0xfc76, (2926, 2)), + (0xfedd, (3963, 1)), (0xfcca, (3099, 2)), - (0x1d7c4, (5229, 1)), - (0x1f14e, (5571, 3)), - (0x1ee89, (5385, 1)), - (0x1d68d, (4920, 1)), - (0x1d73b, (5092, 1)), - (0x1d79f, (5192, 1)), + (0x208b, (346, 1)), + (0x1f14e, (5633, 3)), + (0x1ee89, (5447, 1)), + (0x217d, (540, 1)), + (0x1d770, (5145, 1)), + (0x1d4b8, (4466, 1)), (0xfca5, (3025, 2)), - (0x2084, (339, 1)), - (0xff13, (4027, 1)), + (0x1d701, (5034, 1)), + (0x3253, (1426, 2)), (0xfe8e, (3884, 1)), - (0x1d6b2, (4955, 1)), + (0xfc56, (2850, 2)), (0x1d469, (4395, 1)), - (0x3284, (1509, 1)), - (0x3343, (1940, 4)), - (0x3322, (1814, 3)), + (0x3394, (2165, 3)), + (0xfbe2, (2607, 1)), + (0x2048, (312, 2)), (0xfcf9, (3198, 2)), - (0xfcfa, (3200, 2)), - (0x1d6ff, (5032, 1)), - (0x1d7f3, (5274, 1)), + (0xeb3, (122, 2)), + (0x2fc7, (1056, 1)), + (0x3376, (2095, 2)), + (0x10784, (4238, 1)), (0x1d6ad, (4950, 1)), - (0x2f78, (977, 1)), (0xff80, (4136, 1)), - (0x2486, (650, 4)), - (0x32c2, (1588, 2)), + (0x1d498, (4442, 1)), + (0x1f141, (5616, 1)), (0x33a5, (2205, 2)), (0x1d683, (4910, 1)), - (0x32d1, (1622, 1)), - (0x1d5c9, (4724, 1)), + (0xfdba, (3648, 3)), + (0x2110, (389, 1)), + (0x1d6dc, (4997, 1)), (0x1d4bf, (4471, 1)), - (0xfc11, (2712, 2)), - (0x32df, (1636, 1)), - (0x1d7bd, (5222, 1)), - (0x2f56, (943, 1)), + (0x1d7d6, (5245, 1)), + (0x1f226, (5674, 1)), + (0x1d60d, (4792, 1)), (0x2025, (290, 2)), + (0x1f247, (5717, 3)), (0xfe90, (3886, 1)), - (0xfd0f, (3242, 2)), - (0x24da, (823, 1)), - (0x33d4, (2320, 2)), - (0x1d648, (4851, 1)), - (0xfc41, (2808, 2)), - (0x328e, (1519, 1)), + (0x330d, (1721, 4)), + (0xfb5a, (2499, 1)), + (0x2fa7, (1024, 1)), + (0x33bb, (2264, 2)), + (0x1d70b, (5044, 1)), + (0x2dd, (81, 2)), (0x1d795, (5182, 1)), - (0xffa0, (4168, 1)), - (0xff4a, (4082, 1)), - (0x319c, (1188, 1)), - (0xfd86, (3498, 3)), - (0xfe3f, (3785, 1)), - (0x1d582, (4653, 1)), - (0xfc9b, (3004, 3)), - (0x3243, (1412, 3)), - (0xfccf, (3109, 2)), - (0x1db9, (227, 1)), - (0x1d7da, (5249, 1)), - (0x3334, (1881, 6)), - (0xfe51, (3805, 1)), - (0x33c5, (2286, 2)), + (0x2488, (658, 2)), + (0xfc4c, (2830, 2)), + (0x1d599, (4676, 1)), + (0xfce3, (3151, 2)), + (0x1d5bb, (4710, 1)), + (0x2f8c, (997, 1)), + (0x1d7fe, (5285, 1)), + (0x1d42c, (4335, 1)), + (0xff78, (4128, 1)), + (0x1d67a, (4901, 1)), + (0x1d72c, (5077, 1)), + (0xff68, (4112, 1)), + (0x317a, (1157, 1)), + (0x1d70f, (5048, 1)), (0x32c9, (1602, 3)), - (0x24d5, (818, 1)), - (0x1d7b5, (5214, 1)), + (0xedd, (126, 2)), + (0x1d5f1, (4764, 1)), (0x1d4c2, (4474, 1)), - (0x1d5d0, (4731, 1)), - (0xfe49, (3793, 2)), - (0xfed6, (3956, 1)), + (0xff24, (4044, 1)), + (0xff9a, (4162, 1)), + (0x1d671, (4892, 1)), (0xffcf, (4210, 1)), - (0x1d571, (4636, 1)), - (0xfdf2, (3696, 4)), - (0xfc28, (2758, 2)), - (0x1d5ae, (4697, 1)), + (0x2f0b, (868, 1)), + (0x32cc, (1611, 2)), + (0x1d6fa, (5027, 1)), + (0x1d616, (4801, 1)), (0xfb15, (2471, 2)), - (0x1fc0, (242, 2)), + (0xfee7, (3973, 1)), (0xff96, (4158, 1)), + (0x3d2, (97, 1)), (0x1d5d9, (4740, 1)), - (0x336f, (2077, 3)), (0x1ffd, (271, 2)), - (0x2f2b, (900, 1)), - (0x1d47d, (4415, 1)), + (0xfbb1, (2589, 2)), + (0xfca3, (3021, 2)), (0x2f7f, (984, 1)), (0x2f42, (923, 1)), - (0x1d647, (4850, 1)), - (0xff6f, (4119, 1)), - (0x334a, (1964, 6)), - (0x331b, (1786, 4)), - (0xfca2, (3019, 2)), - (0xfd62, (3390, 3)), - (0x1d57b, (4646, 1)), - (0x107a4, (4269, 1)), + (0xfc27, (2756, 2)), + (0x1eea7, (5470, 1)), + (0x212d, (411, 1)), + (0x1d35, (144, 1)), + (0x1e05c, (5331, 1)), + (0xfcb2, (3051, 2)), + (0xfc7e, (2942, 2)), + (0x2f9d, (1014, 1)), (0x33f9, (2417, 3)), - (0x1f11d, (5489, 3)), + (0x1d606, (4785, 1)), (0x1d55b, (4614, 1)), (0x1d62f, (4826, 1)), (0x2f9f, (1016, 1)), + (0x1dbc, (230, 1)), (0xff3b, (4067, 1)), - (0x1d4ff, (4534, 1)), - (0xfe3a, (3780, 1)), - (0xffed, (4233, 1)), + (0x32d8, (1629, 1)), + (0x1d568, (4627, 1)), (0x33e5, (2361, 2)), + (0x2f82, (987, 1)), (0xfea7, (3909, 1)), - (0x1d4fd, (4532, 1)), - (0x337c, (2109, 2)), - (0xfba7, (2578, 1)), - (0xfcb9, (3065, 2)), + (0x1d55d, (4616, 1)), + (0x1d4ac, (4455, 1)), + (0x24b2, (775, 3)), + (0xfd37, (3322, 2)), (0x2f80, (985, 1)), - (0xfb6c, (2517, 1)), (0x1d4df, (4502, 1)), - (0x1d45f, (4385, 1)), - (0x1d7b3, (5212, 1)), + (0xfb73, (2524, 1)), + (0xfdc7, (3687, 3)), + (0x1d48, (162, 1)), (0xfbb0, (2587, 2)), - (0x2026, (292, 3)), - (0x1ee03, (5290, 1)), - (0xff7e, (4134, 1)), - (0x314a, (1109, 1)), - (0x1d625, (4816, 1)), - (0x322d, (1346, 3)), - (0x1ee7b, (5373, 1)), - (0xfc0a, (2698, 2)), - (0x314d, (1112, 1)), + (0x1d704, (5037, 1)), + (0x1d481, (4419, 1)), + (0x2f5b, (948, 1)), + (0x1e034, (5291, 1)), + (0x2b2, (64, 1)), + (0x1d41d, (4320, 1)), + (0xfcce, (3107, 2)), + (0x33a8, (2213, 4)), (0x1d6e4, (5005, 1)), - (0x3135, (1088, 1)), + (0x1d7c7, (5232, 1)), (0x32b6, (1564, 2)), - (0x3208, (1216, 3)), + (0x3218, (1274, 4)), (0xfdf9, (3724, 3)), - (0x1d636, (4833, 1)), - (0xfcea, (3165, 2)), - (0x2f60, (953, 1)), - (0x2002, (277, 1)), - (0x1d788, (5169, 1)), - (0x32e5, (1642, 1)), - (0x1079d, (4262, 1)), - (0x1eebb, (5427, 1)), - (0x1d4f4, (4523, 1)), - (0x1da6, (208, 1)), - (0x1d450, (4371, 1)), - (0x1d670, (4891, 1)), - (0x2dd, (81, 2)), + (0xfd07, (3226, 2)), + (0xff69, (4113, 1)), + (0x3196, (1182, 1)), + (0x1d7ec, (5267, 1)), + (0xfcde, (3139, 2)), + (0x3274, (1478, 2)), + (0xfd11, (3246, 2)), + (0xfdb9, (3645, 3)), + (0xfccd, (3105, 2)), + (0x2fa2, (1019, 1)), + (0xfb21, (2478, 1)), + (0x1d401, (4292, 1)), + (0x1ee0d, (5361, 1)), + (0x338d, (2148, 2)), (0xfd36, (3320, 2)), (0xfc44, (2814, 2)), - (0x1eeb5, (5421, 1)), - (0xfcf2, (3181, 3)), - (0xfd10, (3244, 2)), - (0xfc8d, (2972, 2)), - (0xfd09, (3230, 2)), - (0xff16, (4030, 1)), - (0x107b9, (4289, 1)), - (0x3384, (2127, 2)), - (0xfc0e, (2706, 2)), - (0x2147, (432, 1)), - (0x335d, (2028, 2)), + (0x1d573, (4638, 1)), + (0x327c, (1494, 5)), + (0x1d787, (5168, 1)), + (0x2f1d, (886, 1)), + (0x1d4ca, (4481, 1)), + (0x2f32, (907, 1)), + (0x1d443, (4358, 1)), + (0xfec5, (3939, 1)), + (0x1f237, (5691, 1)), + (0xfb9f, (2568, 1)), + (0x332e, (1855, 6)), + (0x24cc, (809, 1)), (0x2162, (486, 3)), - (0xfd0e, (3240, 2)), - (0x1d5ad, (4696, 1)), + (0xffb6, (4190, 1)), (0xfb9b, (2564, 1)), - (0xfeb9, (3927, 1)), + (0x1fce, (250, 3)), (0x318e, (1177, 1)), + (0x32fa, (1663, 1)), (0x32db, (1632, 1)), - (0x1d74d, (5110, 1)), - (0x319a, (1186, 1)), + (0xfee5, (3971, 1)), + (0xfe41, (3787, 1)), (0x1d5df, (4746, 1)), - (0x1f108, (5444, 2)), - (0x1d6f5, (5022, 1)), - (0xff8e, (4150, 1)), - (0x1d441, (4356, 1)), + (0x33f6, (2408, 3)), + (0x1d585, (4656, 1)), + (0xfd92, (3528, 3)), (0x1d5b, (180, 1)), - (0xff10, (4024, 1)), - (0x1d71e, (5063, 1)), + (0x1078a, (4243, 1)), + (0x337a, (2105, 2)), + (0xfdc3, (3675, 3)), (0x1078e, (4247, 1)), - (0x33cd, (2305, 2)), (0xff63, (4107, 1)), - (0xfdb4, (3630, 3)), - (0x1d4d, (167, 1)), - (0x1f22c, (5618, 1)), - (0xfc89, (2964, 2)), + (0xfedf, (3965, 1)), + (0xfd5c, (3372, 3)), + (0x1e043, (5306, 1)), + (0x1d47b, (4413, 1)), + (0xfe18, (3765, 1)), (0x1d7c5, (5230, 1)), - (0xff5e, (4102, 1)), - (0x1d417, (4314, 1)), - (0xfb73, (2524, 1)), - (0x2f13, (876, 1)), - (0x1d783, (5164, 1)), - (0x2155, (451, 3)), - (0x1d6dc, (4997, 1)), - (0x1d7a2, (5195, 1)), - (0x33d3, (2318, 2)), - (0x1d5c7, (4722, 1)), - (0xfd9c, (3558, 3)), + (0xfbda, (2598, 1)), + (0x1d59d, (4680, 1)), + (0x1e058, (5327, 1)), + (0x216a, (504, 2)), + (0x1d798, (5185, 1)), + (0x1ee37, (5397, 1)), + (0xfc22, (2746, 2)), + (0x3171, (1148, 1)), + (0xfd66, (3402, 3)), + (0x1eea2, (5466, 1)), + (0xfb88, (2545, 1)), (0x1d6b4, (4957, 1)), - (0xfd1e, (3272, 2)), + (0x32e3, (1640, 1)), (0x208e, (349, 1)), - (0xfe98, (3894, 1)), - (0x1d69f, (4938, 1)), - (0xfe7b, (3848, 2)), - (0x1d456, (4376, 1)), - (0x1d6ab, (4948, 1)), + (0x3223, (1316, 3)), + (0x3137, (1090, 1)), + (0x222c, (546, 2)), + (0x2f8b, (996, 1)), + (0x1f11a, (5542, 3)), (0xfc4f, (2836, 2)), (0x1d52b, (4573, 1)), - (0x1d50d, (4545, 1)), - (0x1d47f, (4417, 1)), + (0xfba5, (2575, 2)), + (0x1d465, (4391, 1)), (0xff50, (4088, 1)), - (0x33b4, (2250, 2)), - (0xff9f, (4167, 1)), - (0x213c, (425, 1)), - (0xfd75, (3447, 3)), - (0x2f74, (973, 1)), - (0xfc93, (2984, 2)), - (0x1d491, (4435, 1)), - (0xfc2c, (2766, 2)), + (0xff2b, (4051, 1)), + (0xfc60, (2872, 3)), + (0x326e, (1466, 2)), + (0xfb78, (2529, 1)), + (0x2080, (335, 1)), + (0xfe37, (3777, 1)), + (0x1f243, (5705, 3)), + (0xfb01, (2453, 2)), (0x32a1, (1538, 1)), (0x1d6d9, (4994, 1)), - (0xfed2, (3952, 1)), - (0x10794, (4253, 1)), - (0x314c, (1111, 1)), - (0x1d523, (4565, 1)), - (0x1db4, (222, 1)), - (0x1d569, (4628, 1)), - (0x316c, (1143, 1)), - (0x1d5dd, (4744, 1)), - (0x2a76, (849, 3)), + (0x2007, (282, 1)), + (0x321a, (1282, 4)), + (0x1d730, (5081, 1)), + (0xfb7a, (2531, 1)), + (0x3175, (1152, 1)), + (0x2136, (418, 1)), + (0x3355, (2007, 2)), + (0x32b5, (1562, 2)), + (0xfe3b, (3781, 1)), + (0xfd2a, (3296, 2)), (0x24ad, (760, 3)), - (0x1d7bc, (5221, 1)), - (0x331f, (1800, 4)), - (0x1d4f1, (4520, 1)), - (0x1d678, (4899, 1)), + (0x1d471, (4403, 1)), + (0x3272, (1474, 2)), + (0x1d77b, (5156, 1)), + (0xfd68, (3408, 3)), (0x1d65d, (4872, 1)), - (0x1f138, (5545, 1)), - (0x33b6, (2254, 2)), + (0x1f138, (5607, 1)), + (0x1e066, (5341, 1)), (0x217c, (539, 1)), - (0x2f70, (969, 1)), (0x1d586, (4657, 1)), - (0xbd, (18, 3)), - (0x1d4ed, (4516, 1)), - (0x1d52f, (4577, 1)), - (0x3299, (1530, 1)), + (0x1d785, (5166, 1)), + (0x1d73d, (5094, 1)), + (0xfd53, (3345, 3)), + (0x208c, (347, 1)), + (0x3326, (1827, 3)), (0x1d517, (4554, 1)), - (0x1ee6f, (5363, 1)), + (0x1ee6f, (5425, 1)), (0xfcb0, (3047, 2)), - (0x675, (112, 2)), - (0x328d, (1518, 1)), - (0x3337, (1895, 3)), - (0x334b, (1970, 3)), - (0xfed0, (3950, 1)), - (0x3131, (1084, 1)), - (0xff17, (4031, 1)), - (0x1f22d, (5619, 1)), - (0xfd73, (3441, 3)), - (0x1d78a, (5171, 1)), - (0x1d454, (4375, 1)), + (0xfe19, (3766, 3)), + (0xfb25, (2482, 1)), + (0xff3c, (4068, 1)), + (0xfc7f, (2944, 2)), + (0x1d680, (4907, 1)), + (0xff47, (4079, 1)), + (0x3361, (2036, 2)), + (0x1d5e7, (4754, 1)), + (0x1e031, (5288, 1)), + (0x10791, (4250, 1)), + (0x1f125, (5575, 3)), (0x1d716, (5055, 1)), - (0x1d5ce, (4729, 1)), - (0xfc4b, (2828, 2)), - (0x332b, (1840, 6)), - (0x1f16a, (5576, 2)), + (0xfe11, (3758, 1)), + (0x1d7cb, (5236, 1)), + (0x316a, (1141, 1)), + (0x1f16a, (5638, 2)), (0x1d7af, (5208, 1)), - (0xff6b, (4115, 1)), - (0x1f218, (5598, 1)), - (0x1d4f2, (4521, 1)), - (0xfb6d, (2518, 1)), - (0x211d, (400, 1)), - (0xfeaa, (3912, 1)), - (0xfed1, (3951, 1)), - (0xfc9d, (3009, 2)), - (0x1d7fe, (5285, 1)), + (0xfc2b, (2764, 2)), + (0xff1e, (4038, 1)), + (0x2fa6, (1023, 1)), + (0xfd6c, (3420, 3)), + (0x2116, (394, 2)), + (0x3327, (1830, 2)), + (0xfc21, (2744, 2)), + (0x1d30, (139, 1)), + (0x1d6fe, (5031, 1)), (0xfc3c, (2798, 2)), (0xfbf7, (2654, 3)), - (0x1d653, (4862, 1)), + (0x1d66e, (4889, 1)), (0xfe36, (3776, 1)), - (0x3205, (1207, 3)), - (0x3220, (1307, 3)), - (0x1d7dc, (5251, 1)), - (0x2f00, (857, 1)), - (0x1d658, (4867, 1)), - (0x1d5f0, (4763, 1)), - (0x1f201, (5586, 2)), - (0xfd24, (3284, 2)), - (0x1d707, (5040, 1)), + (0x1d600, (4779, 1)), + (0x32c4, (1592, 2)), + (0xfcee, (3173, 2)), + (0xfea8, (3910, 1)), + (0x1d7cf, (5238, 1)), + (0x1e05d, (5332, 1)), + (0x1d682, (4909, 1)), + (0x2498, (697, 3)), + (0xfedc, (3962, 1)), (0x1d6ec, (5013, 1)), (0x2f1e, (887, 1)), - (0xfcba, (3067, 2)), - (0x1d541, (4593, 1)), - (0x33f8, (2414, 3)), + (0x1d69d, (4936, 1)), + (0xfc55, (2848, 2)), + (0x1ee97, (5460, 1)), (0x1d5bf, (4714, 1)), - (0x1fbf7, (5670, 1)), - (0x337a, (2105, 2)), - (0x107a5, (4270, 1)), - (0x1d7a0, (5193, 1)), - (0x1d71b, (5060, 1)), - (0xfe5e, (3817, 1)), - (0x1d519, (4556, 1)), - (0x1fbf9, (5672, 1)), + (0x207f, (334, 1)), + (0x1eeb4, (5482, 1)), + (0xfc38, (2790, 2)), + (0x1da7, (209, 1)), + (0x1d705, (5038, 1)), + (0x1d720, (5065, 1)), + (0x215b, (469, 3)), + (0x1d4fc, (4531, 1)), + (0x1e03f, (5302, 1)), (0x1d59a, (4677, 1)), - (0xff3e, (4070, 1)), - (0x1f143, (5556, 1)), - (0x1d4a5, (4450, 1)), + (0xfcfd, (3206, 2)), + (0x10781, (4235, 1)), (0x2f9c, (1013, 1)), - (0x1d4c, (166, 1)), - (0x1d650, (4859, 1)), - (0xff21, (4041, 1)), - (0x24b4, (781, 3)), + (0x1d5b3, (4702, 1)), + (0x1d7a4, (5197, 1)), + (0x107a7, (4272, 1)), + (0xfb90, (2553, 1)), + (0x1d490, (4434, 1)), (0x1d543, (4595, 1)), (0x2f6a, (963, 1)), - (0xfeb5, (3923, 1)), + (0x3366, (2050, 3)), (0x1d414, (4311, 1)), - (0x1d6df, (5000, 1)), - (0x13f, (28, 2)), - (0x334d, (1978, 4)), - (0x334e, (1982, 4)), - (0x1d5e9, (4756, 1)), - (0xfc7d, (2940, 2)), - (0xfbe3, (2608, 1)), - (0x24d2, (815, 1)), + (0x1d633, (4830, 1)), + (0x335f, (2032, 2)), + (0x32a8, (1545, 1)), + (0x33cf, (2309, 2)), + (0xfefc, (4007, 2)), + (0x1d6a3, (4942, 1)), + (0xffba, (4194, 1)), + (0x1078d, (4246, 1)), (0x1d6c4, (4973, 1)), - (0xfc96, (2990, 2)), + (0x1e044, (5307, 1)), (0x1d4aa, (4453, 1)), - (0x1d578, (4643, 1)), - (0x1f104, (5436, 2)), + (0x1d595, (4672, 1)), + (0x3331, (1868, 3)), (0x1d7f7, (5278, 1)), - (0x3278, (1486, 2)), - (0xfc25, (2752, 2)), - (0x1d75b, (5124, 1)), - (0x1dbd, (231, 1)), - (0x1d42c, (4335, 1)), + (0x1d6fb, (5028, 1)), + (0x1d49, (163, 1)), + (0x1d49e, (4447, 1)), + (0x1d411, (4308, 1)), + (0x2107, (380, 1)), (0x205f, (320, 1)), + (0x1e038, (5295, 1)), (0xfb4f, (2487, 2)), - (0xfcad, (3041, 2)), - (0x2fba, (1043, 1)), - (0xfb76, (2527, 1)), + (0x1ee9a, (5463, 1)), + (0x1d43c, (4351, 1)), (0x32ad, (1550, 1)), - (0x1eea8, (5409, 1)), + (0x1d468, (4394, 1)), (0x3184, (1167, 1)), (0x3162, (1133, 1)), - (0x1d9f, (201, 1)), - (0xffce, (4209, 1)), - (0x249a, (703, 3)), + (0x2f69, (962, 1)), + (0xfe81, (3859, 2)), + (0x1ee05, (5353, 1)), (0xfea5, (3907, 1)), - (0xfe40, (3786, 1)), + (0x32ba, (1572, 2)), + (0x32f0, (1653, 1)), (0x1d7d9, (5248, 1)), - (0x1d3f, (153, 1)), - (0xfe83, (3863, 2)), + (0x1d4c0, (4472, 1)), (0xfea3, (3905, 1)), - (0x3389, (2138, 4)), - (0x1d7f6, (5277, 1)), - (0xff98, (4160, 1)), - (0x1ee8f, (5390, 1)), - (0x1ee0f, (5301, 1)), - (0x1fc1, (244, 3)), - (0xfbe1, (2606, 1)), + (0x321d, (1294, 7)), + (0x1d6c7, (4976, 1)), + (0x1fcf, (253, 3)), + (0x33bf, (2272, 2)), + (0x1d718, (5057, 1)), + (0x10790, (4249, 1)), + (0x1d501, (4536, 1)), (0x1d610, (4795, 1)), + (0x32e0, (1637, 1)), (0xfd21, (3278, 2)), - (0xfd99, (3549, 3)), - (0x1d598, (4675, 1)), - (0xfcf7, (3194, 2)), - (0x1ee18, (5310, 1)), + (0x1d6db, (4996, 1)), + (0x1f13d, (5612, 1)), + (0x3038, (1073, 1)), + (0x33a7, (2210, 3)), (0xfd25, (3286, 2)), - (0x2024, (289, 1)), + (0x1d7e1, (5256, 1)), (0xffbd, (4197, 1)), - (0x1ee8c, (5387, 1)), - (0x2faf, (1032, 1)), - (0xfeb2, (3920, 1)), - (0x1d7f1, (5272, 1)), - (0x3232, (1361, 3)), - (0x325c, (1444, 2)), + (0x1ee8c, (5449, 1)), + (0x1ee08, (5356, 1)), + (0x33c3, (2282, 2)), + (0x1d51a, (4557, 1)), + (0x32bf, (1582, 2)), (0x249e, (715, 3)), - (0x1f210, (5589, 1)), - (0x1d4d5, (4492, 1)), - (0x337d, (2111, 2)), + (0x33c8, (2295, 2)), + (0x1f210, (5651, 1)), + (0x2179, (533, 1)), + (0x3222, (1313, 3)), (0x1d782, (5163, 1)), (0x10789, (4242, 1)), - (0x1d6b9, (4962, 1)), - (0x1d43d, (4352, 1)), + (0x3305, (1692, 3)), + (0xfe3a, (3780, 1)), (0x1d631, (4828, 1)), (0x3199, (1185, 1)), - (0xfe85, (3867, 2)), - (0xfc3d, (2800, 2)), + (0xffd4, (4213, 1)), + (0x209c, (362, 1)), (0x3247, (1418, 1)), (0xfc88, (2962, 2)), - (0x1d402, (4293, 1)), - (0x1d9c, (198, 1)), - (0x1d7dd, (5252, 1)), + (0xffb9, (4193, 1)), + (0x1d46c, (4398, 1)), + (0x1d636, (4833, 1)), (0x315f, (1130, 1)), (0xfb8b, (2548, 1)), - (0xab5d, (2447, 1)), - (0x1d6bf, (4968, 1)), - (0x1d4b4, (4462, 1)), + (0xb5, (10, 1)), + (0x1d419, (4316, 1)), + (0xfed5, (3955, 1)), + (0x1d6ca, (4979, 1)), (0x339e, (2186, 2)), - (0x1f111, (5453, 3)), (0x1d641, (4844, 1)), - (0xfe63, (3822, 1)), - (0x32fa, (1663, 1)), - (0x1ee36, (5334, 1)), - (0x1d49b, (4445, 1)), - (0x2f03, (860, 1)), - (0xa7f9, (2445, 1)), - (0x1079c, (4261, 1)), - (0xfdba, (3648, 3)), + (0x1d6af, (4952, 1)), + (0x3288, (1513, 1)), + (0x2154, (448, 3)), + (0xfe8d, (3883, 1)), + (0x1d40b, (4302, 1)), + (0x1d607, (4786, 1)), + (0xff26, (4046, 1)), + (0x1d758, (5121, 1)), (0xfc4e, (2834, 2)), (0x3364, (2044, 3)), - (0x1d490, (4434, 1)), - (0xffec, (4232, 1)), - (0x33db, (2339, 2)), - (0x2e1, (84, 1)), - (0x1d5ec, (4759, 1)), + (0x1d4f5, (4524, 1)), + (0x2fc6, (1055, 1)), + (0x1d5dc, (4743, 1)), + (0xfc5e, (2866, 3)), + (0xff36, (4062, 1)), (0x24c5, (802, 1)), - (0x3168, (1139, 1)), + (0x1d587, (4658, 1)), (0x2091, (351, 1)), + (0x1d750, (5113, 1)), (0x24b0, (769, 3)), - (0x1d568, (4627, 1)), - (0x1f122, (5504, 3)), - (0x1d52e, (4576, 1)), + (0x1f122, (5566, 3)), + (0x3339, (1902, 3)), + (0x1e054, (5323, 1)), (0x1d511, (4549, 1)), - (0x2fb1, (1034, 1)), - (0x3320, (1804, 5)), + (0x3335, (1887, 3)), (0xffaa, (4178, 1)), - (0x3164, (1135, 1)), - (0x1d5e0, (4747, 1)), + (0x1f240, (5696, 3)), + (0x1d612, (4797, 1)), + (0x1d553, (4606, 1)), (0x1d5aa, (4693, 1)), - (0x3352, (1996, 2)), - (0x1d4ec, (4515, 1)), + (0xaa, (3, 1)), + (0xff62, (4106, 1)), (0x24de, (827, 1)), - (0x32a4, (1541, 1)), - (0x24e2, (831, 1)), - (0x1d505, (4540, 1)), + (0x1d7e2, (5257, 1)), + (0xfe6a, (3828, 1)), (0x2f6f, (968, 1)), - (0x2f5a, (947, 1)), - (0xff68, (4112, 1)), + (0xfd59, (3363, 3)), + (0x1f1, (56, 2)), + (0x1d33, (142, 1)), (0x1078f, (4248, 1)), - (0x2f23, (892, 1)), - (0xfcd0, (3111, 2)), - (0x3298, (1529, 1)), - (0x3287, (1512, 1)), - (0x1d53b, (4588, 1)), + (0x1d536, (4584, 1)), + (0x2f0a, (867, 1)), + (0x3244, (1415, 1)), + (0x246e, (575, 2)), + (0xfc85, (2956, 2)), (0x32f3, (1656, 1)), - (0x1d70c, (5045, 1)), + (0x1fbf4, (5729, 1)), (0x1d643, (4846, 1)), (0xfba0, (2569, 1)), - (0x3157, (1122, 1)), - (0xfe3e, (3784, 1)), + (0x1db1, (219, 1)), + (0x1d457, (4377, 1)), (0x1d7d7, (5246, 1)), (0x3172, (1149, 1)), - (0x1d70a, (5043, 1)), - (0xff60, (4104, 1)), - (0x3138, (1091, 1)), - (0x1d5a, (179, 1)), - (0x1d676, (4897, 1)), - (0x2048, (312, 2)), + (0x33b2, (2246, 2)), + (0x107aa, (4275, 1)), + (0x2f16, (879, 1)), + (0x1d731, (5082, 1)), + (0x1d725, (5070, 1)), + (0xfbf4, (2645, 3)), (0x33f5, (2405, 3)), - (0x2466, (562, 1)), - (0x1d43e, (4353, 1)), + (0x339d, (2184, 2)), + (0xfcc4, (3087, 2)), (0xfc1c, (2734, 2)), - (0x1d70d, (5046, 1)), - (0x213f, (428, 1)), - (0xfc39, (2792, 2)), - (0x1d608, (4787, 1)), - (0x335c, (2026, 2)), + (0xff11, (4025, 1)), + (0x1d76d, (5142, 1)), + (0x1d61c, (4807, 1)), + (0x1d733, (5084, 1)), + (0x1d5c7, (4722, 1)), (0xff81, (4137, 1)), (0x2122, (406, 2)), - (0x1d61a, (4805, 1)), - (0x1d75e, (5127, 1)), - (0x1d493, (4437, 1)), - (0xfb9e, (2567, 1)), - (0x1ee72, (5366, 1)), + (0x1d4ae, (4456, 1)), + (0x1f21d, (5665, 1)), + (0x1d47f, (4417, 1)), + (0x1d757, (5120, 1)), + (0xbc, (15, 3)), + (0x1d621, (4812, 1)), (0xffe4, (4225, 1)), (0xfec9, (3943, 1)), - (0xfe58, (3811, 1)), - (0x1ee84, (5380, 1)), + (0x1ee84, (5442, 1)), + (0xfd98, (3546, 3)), (0x3161, (1132, 1)), - (0x1d6ba, (4963, 1)), - (0x1d7bf, (5224, 1)), + (0x213f, (428, 1)), (0x1d9e, (200, 1)), - (0x1f236, (5628, 1)), - (0xff6c, (4116, 1)), - (0x2fcc, (1061, 1)), - (0x1d4cc, (4483, 1)), - (0x1ee0b, (5297, 1)), - (0x1d77d, (5158, 1)), - (0x1d5e8, (4755, 1)), + (0x1d619, (4804, 1)), + (0x1d4d6, (4493, 1)), + (0x1d5c0, (4715, 1)), + (0x2f7b, (980, 1)), + (0x1ee0b, (5359, 1)), + (0x1d746, (5103, 1)), + (0xfceb, (3167, 2)), + (0xfef3, (3985, 1)), (0xfcf4, (3187, 3)), - (0x1d4ce, (4485, 1)), - (0x1ee83, (5379, 1)), - (0x1d70b, (5044, 1)), - (0x1d4f6, (4525, 1)), - (0x32dd, (1634, 1)), - (0xfe56, (3809, 1)), - (0x3264, (1456, 1)), - (0x1ee64, (5355, 1)), - (0x316e, (1145, 1)), - (0x1d790, (5177, 1)), - (0x339b, (2180, 2)), - (0x3281, (1506, 1)), - (0x1d54, (173, 1)), + (0xfe7a, (3846, 2)), + (0x215c, (472, 3)), + (0x1d4fd, (4532, 1)), + (0xfba7, (2578, 1)), + (0xfd3c, (3332, 2)), + (0x1d46a, (4396, 1)), + (0x2163, (489, 2)), + (0x1ee64, (5417, 1)), + (0x1d692, (4925, 1)), + (0x1d648, (4851, 1)), + (0x1d482, (4420, 1)), + (0x1d576, (4641, 1)), + (0x1d717, (5056, 1)), (0xfe30, (3769, 2)), - (0x3211, (1246, 4)), - (0x24ab, (754, 3)), + (0x1f232, (5686, 1)), + (0xfc77, (2928, 2)), (0x1d668, (4883, 1)), - (0x3271, (1472, 2)), + (0x2146, (431, 1)), (0xa8, (1, 2)), - (0x1d61, (186, 1)), + (0xfb93, (2556, 1)), (0x1d5ef, (4762, 1)), - (0xfed8, (3958, 1)), - (0x1d5e1, (4748, 1)), - (0x33e1, (2353, 2)), - (0x2ef3, (856, 1)), + (0xfbfd, (2670, 1)), + (0x107ab, (4276, 1)), + (0x1e063, (5338, 1)), + (0x1d470, (4402, 1)), (0x3356, (2009, 6)), - (0x3331, (1868, 3)), - (0xfd6d, (3423, 3)), - (0xfd74, (3444, 3)), + (0x1d4c5, (4476, 1)), + (0xfbe7, (2612, 1)), + (0x24ea, (839, 1)), + (0x1d519, (4556, 1)), (0x1d654, (4863, 1)), - (0x107ac, (4277, 1)), + (0x2f6d, (966, 1)), (0x1d518, (4555, 1)), - (0x2f47, (928, 1)), - (0x3230, (1355, 3)), + (0x1d639, (4836, 1)), (0xfd52, (3342, 3)), - (0x1d7a9, (5202, 1)), + (0x1d79f, (5192, 1)), + (0x1d775, (5150, 1)), (0x3371, (2083, 3)), - (0x1d601, (4780, 1)), - (0xfe93, (3889, 1)), + (0x1e048, (5311, 1)), (0x1d7ce, (5237, 1)), - (0x1d6fc, (5029, 1)), + (0xff65, (4109, 1)), (0x33a0, (2191, 3)), - (0x2f4c, (933, 1)), - (0xfc31, (2776, 2)), + (0x313e, (1097, 1)), + (0x1d60a, (4789, 1)), (0x1d591, (4668, 1)), - (0xfc85, (2956, 2)), - (0xfb53, (2492, 1)), - (0xfb55, (2494, 1)), - (0xfebd, (3931, 1)), - (0x2f58, (945, 1)), + (0x1e04d, (5316, 1)), + (0x1d5c5, (4720, 1)), + (0x327a, (1490, 2)), + (0x1d68, (193, 1)), + (0xff71, (4121, 1)), (0x1d42e, (4337, 1)), - (0x1d697, (4930, 1)), - (0x1f141, (5554, 1)), - (0x1ee2e, (5327, 1)), + (0x1d77a, (5155, 1)), + (0xfe44, (3790, 1)), + (0x1f132, (5601, 1)), + (0x1d5f6, (4769, 1)), (0x1d77c, (5157, 1)), - (0xfe9d, (3899, 1)), + (0x1d66f, (4890, 1)), (0x1d7f5, (5276, 1)), - (0x1eeae, (5414, 1)), (0xfcd7, (3125, 2)), - (0x1d480, (4418, 1)), - (0x1d6e8, (5009, 1)), - (0x33fe, (2432, 3)), - (0x1d734, (5085, 1)), - (0xfc47, (2820, 2)), - (0xfd37, (3322, 2)), - (0x1d57, (176, 1)), - (0x24b7, (788, 1)), - (0x1d612, (4797, 1)), - (0xfe4a, (3795, 2)), - (0x1d48, (162, 1)), - (0x1ee70, (5364, 1)), - (0x1fbf6, (5669, 1)), - (0x1cc, (54, 2)), - (0x1d599, (4676, 1)), + (0x3188, (1171, 1)), + (0x1d7a0, (5193, 1)), + (0xfbe5, (2610, 1)), + (0xff8d, (4149, 1)), + (0x107a1, (4266, 1)), + (0x1d44e, (4369, 1)), + (0x1d528, (4570, 1)), + (0x2fc4, (1053, 1)), + (0x2024, (289, 1)), + (0x10fc, (135, 1)), + (0xfdb0, (3618, 3)), + (0xfcb4, (3055, 2)), + (0x330c, (1717, 4)), + (0x316b, (1142, 1)), + (0x1f111, (5515, 3)), + (0x2fb8, (1041, 1)), (0x3385, (2129, 2)), - (0x1d6c3, (4972, 1)), + (0x1da9, (211, 1)), (0x1d73a, (5091, 1)), - (0x32b9, (1570, 2)), - (0x107ae, (4279, 1)), + (0x3293, (1524, 1)), + (0x1d4cf, (4486, 1)), (0x32d6, (1627, 1)), - (0xffcd, (4208, 1)), - (0xfbb1, (2589, 2)), - (0x1f14d, (5569, 2)), - (0x3137, (1090, 1)), - (0xfdf8, (3720, 4)), - (0xfcfc, (3204, 2)), + (0x338b, (2144, 2)), + (0x314a, (1109, 1)), + (0x1f14d, (5631, 2)), + (0x1e9b, (236, 2)), + (0x1d64a, (4853, 1)), + (0x1d7da, (5249, 1)), (0xfb17, (2475, 2)), (0x1d761, (5130, 1)), (0x2097, (357, 1)), - (0xfca3, (3021, 2)), - (0x2f24, (893, 1)), - (0x1f13f, (5552, 1)), + (0x1fc0, (242, 2)), + (0x33e3, (2357, 2)), + (0x1d6b3, (4956, 1)), (0x1d5b4, (4703, 1)), (0xfd17, (3258, 2)), (0xfc2a, (2762, 2)), - (0x1ee6c, (5360, 1)), + (0x1d76a, (5139, 1)), (0x1d68a, (4917, 1)), - (0x2f16, (879, 1)), - (0x33fb, (2423, 3)), - (0x336a, (2062, 3)), - (0x3186, (1169, 1)), - (0xfd1c, (3268, 2)), + (0x1e039, (5296, 1)), + (0xfbe9, (2614, 1)), + (0x1f107, (5504, 2)), + (0x107a4, (4269, 1)), + (0x216d, (510, 1)), + (0x2092, (352, 1)), (0xff3d, (4069, 1)), - (0x1ee92, (5393, 1)), - (0xfea2, (3904, 1)), - (0x1d413, (4310, 1)), - (0x329b, (1532, 1)), - (0xffb2, (4186, 1)), - (0xfe12, (3759, 1)), - (0xfbd3, (2591, 1)), - (0xff59, (4097, 1)), - (0x1ee91, (5392, 1)), - (0x1fbf0, (5663, 1)), - (0x3329, (1834, 3)), - (0x1d6ef, (5016, 1)), + (0x107b3, (4283, 1)), + (0x2f51, (938, 1)), + (0xfc59, (2856, 2)), + (0x1d529, (4571, 1)), + (0x3237, (1376, 3)), + (0x3215, (1262, 4)), + (0x2465, (561, 1)), + (0x1d735, (5086, 1)), + (0x107b9, (4289, 1)), + (0xfed3, (3953, 1)), + (0x203c, (306, 2)), (0x2f9b, (1012, 1)), - (0x1da0, (202, 1)), - (0xfe86, (3869, 2)), + (0x2f66, (959, 1)), + (0xfd75, (3447, 3)), + (0x1d634, (4831, 1)), (0xe33, (120, 2)), - (0x1d6d6, (4991, 1)), + (0x1dba, (228, 1)), (0xfd5a, (3366, 3)), (0x2494, (685, 3)), - (0x1d6cb, (4980, 1)), - (0x1d5d1, (4732, 1)), - (0x328c, (1517, 1)), + (0x315d, (1128, 1)), + (0x1d509, (4543, 1)), + (0x1d797, (5184, 1)), (0x334f, (1986, 3)), - (0x309c, (1078, 2)), (0x1d7fb, (5282, 1)), - (0x33a8, (2213, 4)), - (0x3323, (1817, 3)), + (0x2463, (559, 1)), + (0xff02, (4010, 1)), + (0xfb61, (2506, 1)), (0x33ec, (2378, 3)), - (0x1d770, (5145, 1)), - (0x1078a, (4243, 1)), + (0x1d5f7, (4770, 1)), (0x33ae, (2231, 5)), + (0xfc89, (2964, 2)), (0x1d738, (5089, 1)), - (0x2f10, (873, 1)), - (0x1f22a, (5616, 1)), + (0x1e030, (5287, 1)), + (0x1f22a, (5678, 1)), (0x2f4b, (932, 1)), - (0x246b, (569, 2)), - (0x1d67f, (4906, 1)), - (0x3348, (1958, 4)), - (0xff24, (4044, 1)), + (0x3302, (1679, 5)), + (0x1d4d, (167, 1)), + (0x1d4d7, (4494, 1)), + (0xfc4d, (2832, 2)), (0x1d4e5, (4508, 1)), (0x1d542, (4594, 1)), - (0x248c, (666, 2)), - (0x107a7, (4272, 1)), - (0xfbf1, (2636, 3)), - (0x2fa5, (1022, 1)), - (0x1d521, (4563, 1)), - (0xfd11, (3246, 2)), - (0x24b5, (784, 3)), + (0x3336, (1890, 5)), + (0x2fb6, (1039, 1)), + (0x2fa1, (1018, 1)), + (0x1d71a, (5059, 1)), + (0xfca4, (3023, 2)), + (0x1d618, (4803, 1)), + (0xfcc2, (3083, 2)), (0x1dac, (214, 1)), (0xfcb8, (3063, 2)), - (0x1d713, (5052, 1)), + (0xfb7c, (2533, 1)), (0x317f, (1162, 1)), - (0x1d5f8, (4771, 1)), - (0xfdb2, (3624, 3)), + (0x1d7e0, (5255, 1)), + (0xffc6, (4203, 1)), (0x3150, (1115, 1)), - (0xfef5, (3987, 3)), - (0xfed4, (3954, 1)), - (0x2479, (602, 3)), - (0x1ee5d, (5351, 1)), + (0x3276, (1482, 2)), + (0x328d, (1518, 1)), + (0x32bc, (1576, 2)), + (0x133, (26, 2)), + (0x1f245, (5711, 3)), (0x213e, (427, 1)), - (0x1d412, (4309, 1)), - (0x2f1b, (884, 1)), - (0xff2b, (4051, 1)), - (0x2488, (658, 2)), - (0xfc2f, (2772, 2)), - (0x1d498, (4442, 1)), - (0x2f7a, (979, 1)), + (0xfb66, (2511, 1)), + (0x2f89, (994, 1)), + (0x1f12e, (5597, 2)), + (0x1d4f1, (4520, 1)), + (0xfc91, (2980, 2)), + (0xff53, (4091, 1)), (0x3306, (1695, 3)), (0x2473, (585, 2)), - (0xfc8b, (2968, 2)), - (0xfb9f, (2568, 1)), + (0x1dae, (216, 1)), + (0xfbac, (2583, 1)), + (0x33b4, (2250, 2)), (0x3214, (1258, 4)), - (0x2230, (553, 3)), - (0x1d651, (4860, 1)), - (0x2f2c, (901, 1)), - (0xfc1e, (2738, 2)), - (0x1d64f, (4858, 1)), + (0x32c2, (1588, 2)), + (0x24ca, (807, 1)), + (0x1d533, (4581, 1)), + (0x33f8, (2414, 3)), + (0xff44, (4076, 1)), (0x1d4f7, (4526, 1)), - (0x3158, (1123, 1)), + (0x1078c, (4245, 1)), (0xffca, (4205, 1)), - (0x3000, (1071, 1)), - (0x1db0, (218, 1)), - (0x32ec, (1649, 1)), - (0xfeed, (3979, 1)), - (0x3372, (2086, 2)), - (0x1f134, (5541, 1)), - (0x1ee2c, (5325, 1)), - (0xff4f, (4087, 1)), + (0xfe17, (3764, 1)), + (0xfbe1, (2606, 1)), + (0xfc32, (2778, 2)), + (0x1d625, (4816, 1)), + (0x140, (30, 2)), + (0xfeab, (3913, 1)), + (0x1d6d3, (4988, 1)), + (0x1d7a8, (5201, 1)), (0xfb5d, (2502, 1)), - (0x1d4eb, (4514, 1)), - (0x1d645, (4848, 1)), + (0x3220, (1307, 3)), + (0x24a5, (736, 3)), (0x1d4b3, (4461, 1)), - (0x322f, (1352, 3)), - (0x1d5fe, (4777, 1)), + (0x107ad, (4278, 1)), + (0x3399, (2176, 2)), (0x2f36, (911, 1)), - (0x33cb, (2301, 2)), - (0x2f28, (897, 1)), - (0xff26, (4046, 1)), - (0x1d74f, (5112, 1)), - (0xfd66, (3402, 3)), - (0x1d5a2, (4685, 1)), - (0x2d6f, (854, 1)), + (0xfc74, (2922, 2)), + (0x1d5a5, (4688, 1)), + (0x2fc3, (1052, 1)), + (0x1e06c, (5347, 1)), + (0x32d9, (1630, 1)), + (0x1d544, (4596, 1)), + (0x3221, (1310, 3)), (0x1d512, (4550, 1)), - (0x3379, (2102, 3)), - (0xfcee, (3173, 2)), - (0x1d750, (5113, 1)), - (0xfba8, (2579, 1)), - (0x385, (92, 3)), + (0xfece, (3948, 1)), + (0xfcf7, (3194, 2)), + (0xfb82, (2539, 1)), + (0x1d6b8, (4961, 1)), + (0x3194, (1180, 1)), (0xffe5, (4226, 1)), - (0x323c, (1391, 3)), - (0x1fbf1, (5664, 1)), + (0x32e8, (1645, 1)), + (0x24af, (766, 3)), + (0x1fbf1, (5726, 1)), (0xfbfc, (2669, 1)), - (0x33b0, (2242, 2)), - (0xfdb1, (3621, 3)), - (0xfdbf, (3663, 3)), - (0x330e, (1725, 4)), - (0x1d5a1, (4684, 1)), - (0x1db3, (221, 1)), - (0x1ee4d, (5342, 1)), + (0xb3, (7, 1)), + (0x24c6, (803, 1)), + (0x1d749, (5106, 1)), + (0xfd9a, (3552, 3)), + (0x1d4b5, (4463, 1)), + (0xfede, (3964, 1)), (0x1d6e7, (5008, 1)), (0x2f48, (929, 1)), - (0x1d66e, (4889, 1)), + (0x1d4e3, (4506, 1)), + (0x1eea6, (5469, 1)), (0x2f97, (1008, 1)), - (0x1d797, (5184, 1)), + (0x24a8, (745, 3)), (0x1d562, (4621, 1)), - (0xff52, (4090, 1)), - (0x1d7b4, (5213, 1)), - (0xfca9, (3033, 2)), - (0x1d63b, (4838, 1)), - (0x2f39, (914, 1)), + (0x2102, (371, 1)), + (0x1d61b, (4806, 1)), + (0x3176, (1153, 1)), + (0x1d60, (185, 1)), (0x1d698, (4931, 1)), - (0x2174, (521, 1)), - (0xfd20, (3276, 2)), - (0x1d69d, (4936, 1)), - (0x24e8, (837, 1)), - (0x213d, (426, 1)), + (0xfed9, (3959, 1)), + (0x1d61f, (4810, 1)), + (0x1ee6a, (5421, 1)), + (0xfd09, (3230, 2)), + (0x1d561, (4620, 1)), + (0x1d4e1, (4504, 1)), (0x1d7f4, (5275, 1)), - (0x1d779, (5154, 1)), - (0x3215, (1262, 4)), - (0xfb28, (2485, 1)), - (0x33f4, (2402, 3)), - (0x1d624, (4815, 1)), - (0x1d577, (4642, 1)), - (0xfbd5, (2593, 1)), - (0xfedc, (3962, 1)), + (0x2f68, (961, 1)), + (0x1eeb3, (5481, 1)), + (0x1e062, (5337, 1)), + (0x2fbe, (1047, 1)), + (0x2047, (310, 2)), + (0xff23, (4043, 1)), + (0xfe77, (3840, 2)), + (0x1d75b, (5124, 1)), (0x1d4b9, (4467, 1)), (0x33ba, (2262, 2)), - (0x2fb0, (1033, 1)), - (0x325f, (1450, 2)), + (0x2482, (634, 4)), (0xffb0, (4184, 1)), - (0xfcef, (3175, 2)), - (0x1f221, (5607, 1)), - (0x1d691, (4924, 1)), - (0x1d6dd, (4998, 1)), - (0x2f46, (927, 1)), + (0x3164, (1135, 1)), + (0x24d1, (814, 1)), + (0x24db, (824, 1)), + (0x1d5bc, (4711, 1)), + (0x3396, (2170, 2)), + (0x1d590, (4667, 1)), (0x1d5da, (4741, 1)), - (0x1d5c1, (4716, 1)), - (0x1d526, (4568, 1)), - (0x338d, (2148, 2)), + (0x1d454, (4375, 1)), + (0x1ee24, (5382, 1)), + (0x2134, (416, 1)), (0x1d7a5, (5198, 1)), - (0xffbe, (4198, 1)), + (0x1e056, (5325, 1)), (0x32f7, (1660, 1)), - (0x1f14a, (5563, 2)), - (0xff28, (4048, 1)), - (0xff69, (4113, 1)), + (0xfe72, (3834, 2)), + (0x1e04c, (5315, 1)), + (0xfef0, (3982, 1)), (0x2f0f, (872, 1)), - (0x1d4d7, (4494, 1)), + (0x2f88, (993, 1)), (0x1d4cd, (4484, 1)), - (0x1ee2d, (5326, 1)), - (0xa0, (0, 1)), - (0x1d726, (5071, 1)), + (0x1d54b, (4599, 1)), + (0x1d7ba, (5219, 1)), + (0x1fbf, (240, 2)), (0xffeb, (4231, 1)), - (0xfdf1, (3693, 3)), - (0xfe16, (3763, 1)), - (0x1d754, (5117, 1)), + (0x1d5ee, (4761, 1)), + (0xff72, (4122, 1)), + (0x1f218, (5660, 1)), + (0x3234, (1367, 3)), (0x1d7ef, (5270, 1)), - (0x2116, (394, 2)), - (0x33c9, (2297, 2)), - (0x1d71d, (5062, 1)), - (0xfea8, (3910, 1)), + (0x1d425, (4328, 1)), + (0x1d6ce, (4983, 1)), + (0x1ee83, (5441, 1)), + (0x1e04f, (5318, 1)), (0x1d483, (4421, 1)), - (0x1d6a0, (4939, 1)), - (0x1d443, (4358, 1)), + (0xff73, (4123, 1)), (0xff1c, (4036, 1)), - (0x1d4c6, (4477, 1)), - (0x2fd5, (1070, 1)), + (0x33f2, (2396, 3)), + (0x217b, (536, 3)), + (0x2004, (279, 1)), (0x1d6a4, (4943, 1)), - (0xfb6a, (2515, 1)), - (0xfb06, (2465, 2)), - (0xfc2b, (2764, 2)), - (0x1f125, (5513, 3)), - (0x2fb7, (1040, 1)), - (0x2111, (390, 1)), - (0x2fbe, (1047, 1)), - (0x1d705, (5038, 1)), + (0x326f, (1468, 2)), + (0xfc57, (2852, 2)), + (0x32f2, (1655, 1)), + (0x1d646, (4849, 1)), + (0x1d412, (4309, 1)), + (0x249a, (703, 3)), + (0x1f127, (5581, 3)), (0x330b, (1714, 3)), - (0x1d463, (4389, 1)), + (0xfc5c, (2862, 2)), + (0x2f46, (927, 1)), (0x1d40a, (4301, 1)), - (0x1d4dc, (4499, 1)), - (0x1d537, (4585, 1)), + (0x24d8, (821, 1)), + (0x1d77e, (5159, 1)), (0xfd3a, (3328, 2)), - (0x1d78, (196, 1)), + (0x1d64, (189, 1)), (0x315e, (1129, 1)), - (0xfbdf, (2604, 1)), - (0xff01, (4009, 1)), - (0x3216, (1266, 4)), - (0x1d4c8, (4479, 1)), - (0xfce5, (3155, 2)), + (0x319d, (1189, 1)), + (0x1ee3b, (5399, 1)), + (0xfb26, (2483, 1)), + (0x1d4fe, (4533, 1)), + (0x2480, (626, 4)), (0x216e, (511, 1)), - (0x2011, (286, 1)), - (0x1d593, (4670, 1)), - (0x1d728, (5073, 1)), - (0x1d7d4, (5243, 1)), - (0x1ee13, (5305, 1)), - (0x1d48a, (4428, 1)), + (0x1e03b, (5298, 1)), + (0x1d6b6, (4959, 1)), + (0xbd, (18, 3)), + (0x1d42, (156, 1)), + (0x24a1, (724, 3)), + (0x33df, (2348, 3)), (0xffb5, (4189, 1)), - (0x1d77b, (5156, 1)), - (0xffd3, (4212, 1)), - (0x1c6, (41, 3)), - (0x1d778, (5153, 1)), - (0x1d690, (4923, 1)), - (0xfefc, (4007, 2)), - (0x1d4c3, (4475, 1)), - (0xfd6c, (3420, 3)), - (0x32f2, (1655, 1)), + (0x1e042, (5305, 1)), + (0xfc9a, (3001, 3)), + (0x1d5eb, (4758, 1)), + (0xfcbf, (3077, 2)), + (0xfd58, (3360, 3)), + (0x2464, (560, 1)), + (0xfe3c, (3782, 1)), + (0x3246, (1417, 1)), + (0x2a0c, (840, 4)), + (0xfdb4, (3630, 3)), (0xfd96, (3540, 3)), (0x1d407, (4298, 1)), - (0x1d6eb, (5012, 1)), (0x3257, (1434, 2)), (0x207a, (329, 1)), + (0x3d5, (102, 1)), (0x336b, (2065, 3)), - (0x1d75c, (5125, 1)), - (0xff0e, (4022, 1)), - (0xffe9, (4229, 1)), + (0x32d0, (1621, 1)), + (0x1eeae, (5476, 1)), (0x1d5d5, (4736, 1)), - (0x1d6db, (4996, 1)), - (0x1d451, (4372, 1)), - (0x1d74c, (5109, 1)), - (0x1f1, (56, 2)), + (0x1eead, (5475, 1)), + (0x2f1a, (883, 1)), + (0xfee0, (3966, 1)), + (0x2fa3, (1020, 1)), + (0x1eeb2, (5480, 1)), (0xfbf5, (2648, 3)), - (0x1d43c, (4351, 1)), + (0x1e067, (5342, 1)), (0x3174, (1151, 1)), - (0xfd68, (3408, 3)), (0xfbe0, (2605, 1)), - (0x1f144, (5557, 1)), + (0x1ee51, (5407, 1)), + (0xff3f, (4071, 1)), (0x3165, (1136, 1)), - (0x1da5, (207, 1)), - (0xfc90, (2978, 2)), - (0x1d55c, (4615, 1)), - (0xfc24, (2750, 2)), + (0x323d, (1394, 3)), + (0x1d72d, (5078, 1)), + (0x1d79b, (5188, 1)), + (0x1d4b6, (4464, 1)), (0xfc54, (2846, 2)), - (0xfc2e, (2770, 2)), - (0x1d634, (4831, 1)), - (0x1d759, (5122, 1)), + (0x2fb0, (1033, 1)), + (0x3228, (1331, 3)), + (0x1d3a, (149, 1)), (0x3213, (1254, 4)), - (0x1d43b, (4350, 1)), - (0x2f57, (944, 1)), - (0x1d7ba, (5219, 1)), - (0x1daf, (217, 1)), - (0xfb96, (2559, 1)), + (0x1e065, (5340, 1)), + (0x1d4ff, (4534, 1)), + (0x1d734, (5085, 1)), + (0x1d78b, (5172, 1)), + (0xa69d, (2439, 1)), (0x2f96, (1007, 1)), - (0x317a, (1157, 1)), - (0x1f11f, (5495, 3)), - (0x1d6a3, (4942, 1)), - (0x1d41, (155, 1)), - (0x1f124, (5510, 3)), - (0x2f17, (880, 1)), - (0x3272, (1474, 2)), + (0xfc39, (2792, 2)), + (0x1f14c, (5629, 2)), + (0xfedb, (3961, 1)), + (0x2495, (688, 3)), + (0x1f124, (5572, 3)), + (0x1d7dc, (5251, 1)), + (0x1e053, (5322, 1)), (0x2f9a, (1011, 1)), (0xfd61, (3387, 3)), - (0x1d5ee, (4761, 1)), - (0x1eeab, (5411, 1)), + (0xfd02, (3216, 2)), + (0x1eeab, (5473, 1)), (0x1079f, (4264, 1)), - (0xf77, (129, 3)), - (0xfd1f, (3274, 2)), - (0x24c3, (800, 1)), + (0x1ee86, (5444, 1)), + (0xfd9b, (3555, 3)), + (0x1d50f, (4547, 1)), (0xfc8e, (2974, 2)), - (0x2499, (700, 3)), + (0x1d513, (4551, 1)), (0x1d54f, (4603, 1)), - (0x1d33, (142, 1)), - (0xff15, (4029, 1)), + (0x2173, (519, 2)), + (0x2f5a, (947, 1)), + (0x1d78c, (5173, 1)), (0x1d767, (5136, 1)), - (0x33ce, (2307, 2)), (0xfdab, (3603, 3)), + (0x2f01, (858, 1)), (0xfc3f, (2804, 2)), - (0x1d5e6, (4753, 1)), - (0x33a9, (2217, 2)), - (0x325a, (1440, 2)), + (0x33c6, (2288, 4)), + (0x1d6c0, (4969, 1)), + (0xfb98, (2561, 1)), (0x3151, (1116, 1)), - (0x3335, (1887, 3)), - (0x1d702, (5035, 1)), + (0x1ee09, (5357, 1)), + (0xfd8a, (3510, 3)), (0xff4d, (4085, 1)), - (0xffe8, (4228, 1)), - (0xba, (14, 1)), - (0xfc12, (2714, 2)), - (0xff03, (4011, 1)), - (0xfe31, (3771, 1)), - (0x1d419, (4316, 1)), - (0x32b3, (1558, 2)), + (0x1d729, (5074, 1)), + (0xfeb4, (3922, 1)), + (0xfba4, (2573, 2)), + (0x1d6b9, (4962, 1)), + (0x1d6d0, (4985, 1)), + (0x318d, (1176, 1)), + (0x1f10a, (5510, 2)), (0x2017, (287, 2)), - (0xfee7, (3973, 1)), - (0x24a5, (736, 3)), - (0x132, (24, 2)), + (0x1f121, (5563, 3)), + (0x1d41f, (4322, 1)), (0x1d415, (4312, 1)), (0x319b, (1187, 1)), + (0x1d6dd, (4998, 1)), (0x337f, (2115, 4)), - (0x313c, (1095, 1)), - (0x1d769, (5138, 1)), - (0x3394, (2165, 3)), + (0x3260, (1452, 1)), + (0x1fbf6, (5731, 1)), (0xfb7b, (2532, 1)), - (0xff4b, (4083, 1)), - (0x1d522, (4564, 1)), + (0x1d752, (5115, 1)), + (0x2f50, (937, 1)), (0xfebf, (3933, 1)), + (0x1d658, (4867, 1)), (0xfdfa, (3727, 18)), - (0x1f231, (5623, 1)), + (0x336e, (2074, 3)), (0xff51, (4089, 1)), - (0x1d65a, (4869, 1)), - (0x1d7c6, (5231, 1)), - (0xfeb8, (3926, 1)), - (0xfeee, (3980, 1)), - (0x1ee61, (5353, 1)), + (0xfc16, (2722, 2)), + (0x1d5d, (182, 1)), + (0x24b8, (789, 1)), + (0xab5d, (2447, 1)), + (0x1d41b, (4318, 1)), (0xfb68, (2513, 1)), - (0x1f103, (5434, 2)), - (0x1d45a, (4380, 1)), - (0x1d54d, (4601, 1)), - (0xffc5, (4202, 1)), - (0xfcff, (3210, 2)), + (0x1f103, (5496, 2)), + (0x2f53, (940, 1)), + (0x3352, (1996, 2)), + (0x1d5f9, (4772, 1)), + (0x1d494, (4438, 1)), (0x1d52c, (4574, 1)), (0x24e6, (835, 1)), - (0x1ee2b, (5324, 1)), - (0x3316, (1759, 6)), - (0x1d58b, (4662, 1)), - (0xfdf6, (3712, 4)), - (0xff43, (4075, 1)), + (0x2faf, (1032, 1)), + (0x32c1, (1586, 2)), + (0x2b3, (65, 1)), + (0xfec1, (3935, 1)), + (0x1f147, (5622, 1)), (0x384, (90, 2)), - (0x1d61c, (4807, 1)), + (0x24ba, (791, 1)), (0xff87, (4143, 1)), - (0x2092, (352, 1)), - (0x2f37, (912, 1)), - (0x1f248, (5658, 3)), + (0x1d669, (4884, 1)), + (0xff35, (4061, 1)), + (0xfefb, (4005, 2)), (0x1d7fa, (5281, 1)), - (0x215e, (478, 3)), - (0x1d731, (5082, 1)), - (0xfd5e, (3378, 3)), - (0x1f219, (5599, 1)), + (0x1d50, (169, 1)), + (0xfef2, (3984, 1)), + (0x3245, (1416, 1)), + (0x1d78a, (5171, 1)), (0xfb75, (2526, 1)), - (0x1d5b9, (4708, 1)), - (0x10784, (4238, 1)), + (0x1ee91, (5454, 1)), + (0x33e9, (2369, 3)), + (0x2139, (421, 1)), (0x3258, (1436, 2)), - (0x32bd, (1578, 2)), + (0x3287, (1512, 1)), (0x317d, (1160, 1)), (0x24ae, (763, 3)), - (0x33be, (2270, 2)), - (0xfc99, (2998, 3)), + (0xff98, (4160, 1)), (0x1d596, (4673, 1)), - (0x1d4f8, (4527, 1)), - (0xfdb0, (3618, 3)), - (0x3282, (1507, 1)), + (0x1d6b0, (4953, 1)), + (0x1e069, (5344, 1)), + (0x1f22c, (5680, 1)), + (0xff42, (4074, 1)), (0xffbb, (4195, 1)), - (0xfeec, (3978, 1)), - (0x1d6f7, (5024, 1)), - (0x2f82, (987, 1)), - (0xfb04, (2460, 3)), - (0x2f5e, (951, 1)), - (0x1d637, (4834, 1)), - (0x1d5ea, (4757, 1)), - (0x1d6fd, (5030, 1)), + (0xff1d, (4037, 1)), + (0x1d503, (4538, 1)), + (0x1d6e1, (5002, 1)), + (0xfcc7, (3093, 2)), + (0xff60, (4104, 1)), + (0x1ee5d, (5413, 1)), + (0x1f115, (5527, 3)), (0x1d4c9, (4480, 1)), (0x1d567, (4626, 1)), - (0x3d2, (97, 1)), + (0x1d67e, (4905, 1)), (0x33ed, (2381, 3)), + (0x1e068, (5343, 1)), (0xfda6, (3588, 3)), - (0x24bf, (796, 1)), + (0x33ca, (2299, 2)), (0x1d7f8, (5279, 1)), (0x33ef, (2387, 3)), - (0x1d659, (4868, 1)), - (0x1d7c9, (5234, 1)), + (0xfd50, (3336, 3)), + (0x248e, (670, 2)), (0xfcd4, (3119, 2)), - (0xfb83, (2540, 1)), - (0x2472, (583, 2)), - (0x1d4ee, (4517, 1)), - (0xffe0, (4220, 1)), + (0xfe98, (3894, 1)), + (0x32a7, (1544, 1)), + (0xffa9, (4177, 1)), (0x2172, (516, 3)), - (0xfe69, (3827, 1)), - (0x2f1f, (888, 1)), + (0x1d5a, (179, 1)), + (0xff27, (4047, 1)), + (0x1dad, (215, 1)), (0x1d766, (5135, 1)), - (0x107a6, (4271, 1)), (0x24df, (828, 1)), + (0xfeae, (3916, 1)), (0xfe35, (3775, 1)), - (0xfd7c, (3468, 3)), - (0xffea, (4230, 1)), + (0x1d5a3, (4686, 1)), + (0x1d650, (4859, 1)), (0x1d62a, (4821, 1)), (0x1d4dd, (4500, 1)), - (0x1eea5, (5406, 1)), + (0xff5b, (4099, 1)), (0x1d464, (4390, 1)), - (0x2080, (335, 1)), - (0x33af, (2236, 6)), + (0xfc34, (2782, 2)), + (0x1d6bc, (4965, 1)), (0x1d71c, (5061, 1)), - (0x1ee9a, (5401, 1)), - (0xfe5d, (3816, 1)), - (0xff76, (4126, 1)), - (0xff71, (4121, 1)), + (0x2128, (409, 1)), + (0xfb74, (2525, 1)), + (0xfced, (3171, 2)), + (0xa69c, (2438, 1)), (0x2a74, (844, 3)), - (0x1d764, (5133, 1)), - (0xff23, (4043, 1)), - (0x1d5ed, (4760, 1)), - (0xfefb, (4005, 2)), - (0x2fb6, (1039, 1)), + (0xfef8, (3996, 3)), + (0x1d63a, (4837, 1)), + (0xfcb5, (3057, 2)), + (0x1d435, (4344, 1)), + (0x1ee69, (5420, 1)), (0x2036, (301, 2)), (0x1fbd, (238, 2)), (0x1d5fb, (4774, 1)), + (0x1d5b9, (4708, 1)), (0xfd57, (3357, 3)), - (0x1d59c, (4679, 1)), (0x318b, (1174, 1)), - (0x1d4a2, (4449, 1)), - (0xfcde, (3139, 2)), - (0x2110, (389, 1)), + (0xfdf5, (3708, 4)), + (0xfe7c, (3850, 2)), + (0xfc9b, (3004, 3)), (0xfd14, (3252, 2)), - (0x1d6e3, (5004, 1)), - (0xfd8d, (3519, 3)), + (0x1d51b, (4558, 1)), + (0x1ee67, (5418, 1)), + (0x338a, (2142, 2)), (0xff40, (4072, 1)), - (0x2f5f, (952, 1)), (0xfb50, (2489, 1)), - (0xff45, (4077, 1)), - (0x1ee17, (5309, 1)), - (0xfe9a, (3896, 1)), - (0x1d4cf, (4486, 1)), - (0x1d63, (188, 1)), + (0x1d4c7, (4478, 1)), + (0x1079c, (4261, 1)), + (0x1ee17, (5371, 1)), + (0x1f190, (5644, 2)), + (0x1d5f0, (4763, 1)), + (0x32b3, (1558, 2)), (0x1d7d5, (5244, 1)), - (0x327d, (1499, 4)), (0xfe64, (3823, 1)), - (0x2f84, (989, 1)), + (0xfb8e, (2551, 1)), + (0xfc07, (2692, 2)), (0xfb58, (2497, 1)), - (0x1d592, (4669, 1)), - (0x336c, (2068, 3)), - (0x3202, (1198, 3)), - (0x1d5e5, (4752, 1)), - (0x1d45, (159, 1)), - (0x1d708, (5041, 1)), - (0xfe11, (3758, 1)), + (0x1d75c, (5125, 1)), + (0x2168, (501, 2)), + (0x1d745, (5102, 1)), + (0x1ee4e, (5405, 1)), + (0x2fcc, (1061, 1)), + (0x1d781, (5162, 1)), + (0x313c, (1095, 1)), (0x1fde, (259, 3)), (0x2fbd, (1046, 1)), - (0xfd95, (3537, 3)), - (0xfb67, (2512, 1)), - (0xa69d, (2439, 1)), + (0x1d5d4, (4735, 1)), + (0x1d500, (4535, 1)), + (0xfc80, (2946, 2)), (0x33a3, (2199, 3)), (0x1d502, (4537, 1)), - (0xfc59, (2856, 2)), + (0x32d1, (1622, 1)), (0xfd97, (3543, 3)), - (0x2fbb, (1044, 1)), + (0x1d489, (4427, 1)), (0xffd6, (4215, 1)), (0xfcc3, (3085, 2)), (0x2493, (682, 3)), (0x1d6c6, (4975, 1)), - (0xfe10, (3757, 1)), - (0x1d585, (4656, 1)), - (0x1d75a, (5123, 1)), - (0x1ee05, (5291, 1)), + (0x208d, (348, 1)), + (0xfb06, (2465, 2)), + (0x319c, (1188, 1)), + (0x1da1, (203, 1)), (0xff1b, (4035, 1)), - (0xfb99, (2562, 1)), + (0xfee1, (3967, 1)), (0xfc65, (2887, 3)), - (0x10798, (4257, 1)), - (0x24be, (795, 1)), + (0xfc14, (2718, 2)), + (0xfea2, (3904, 1)), (0xfb91, (2554, 1)), - (0x1f12d, (5533, 2)), - (0xfc63, (2881, 3)), - (0x1c8, (46, 2)), + (0x3350, (1989, 3)), + (0x1d6c8, (4977, 1)), + (0x1d677, (4898, 1)), (0x10783, (4237, 1)), (0x1da3, (205, 1)), (0x1d51, (170, 1)), (0x3261, (1453, 1)), - (0xfe72, (3834, 2)), + (0xfc78, (2930, 2)), + (0x3363, (2041, 3)), (0x2f3c, (917, 1)), - (0xfdf3, (3700, 4)), - (0x1d3c, (150, 1)), - (0xfd92, (3528, 3)), - (0x1d5cf, (4730, 1)), + (0x2f27, (896, 1)), + (0x32a3, (1540, 1)), + (0x1fbf5, (5730, 1)), (0x2b4, (66, 1)), - (0xfd6a, (3414, 3)), - (0xfcc2, (3083, 2)), - (0x2149, (434, 1)), - (0x1d655, (4864, 1)), + (0x3286, (1511, 1)), + (0x2f17, (880, 1)), + (0x1d5cc, (4727, 1)), + (0x1f230, (5684, 1)), + (0xfb03, (2457, 3)), (0x24ce, (811, 1)), - (0xfe18, (3765, 1)), - (0xfb52, (2491, 1)), - (0x1f123, (5507, 3)), - (0x2460, (556, 1)), - (0xfbf0, (2633, 3)), - (0xfb6b, (2516, 1)), + (0x2f30, (905, 1)), + (0xfd60, (3384, 3)), + (0x1f123, (5569, 3)), + (0x1d532, (4580, 1)), + (0x1f21e, (5666, 1)), (0x3353, (1998, 4)), - (0x330f, (1729, 4)), - (0x333e, (1923, 4)), + (0x1d9b, (197, 1)), + (0x1f104, (5498, 2)), + (0x1f21b, (5663, 1)), (0xfe52, (3806, 1)), - (0x1d557, (4610, 1)), + (0xfd3b, (3330, 2)), (0x2f61, (954, 1)), (0xfc00, (2673, 3)), - (0x1f129, (5525, 3)), + (0x1ee71, (5427, 1)), (0x3f0, (104, 1)), - (0x1ee0d, (5299, 1)), - (0x1d55, (174, 1)), - (0xff6d, (4117, 1)), - (0x1d6a8, (4945, 1)), - (0xff5f, (4103, 1)), - (0x1ee96, (5397, 1)), + (0x1d7e4, (5259, 1)), + (0xfc5d, (2864, 2)), + (0x1d670, (4891, 1)), + (0xfe33, (3773, 1)), + (0x1d57d, (4648, 1)), + (0xfe6b, (3829, 1)), (0x3233, (1364, 3)), - (0xfb23, (2480, 1)), + (0x2f21, (890, 1)), (0xfc15, (2720, 2)), (0x1d55f, (4618, 1)), - (0x2faa, (1027, 1)), - (0x1d7aa, (5203, 1)), - (0x322b, (1340, 3)), - (0x326b, (1463, 1)), + (0xfd64, (3396, 3)), + (0x1d49a, (4444, 1)), + (0xfe7b, (3848, 2)), + (0x1d762, (5131, 1)), (0x1d6e0, (5001, 1)), - (0x1d433, (4342, 1)), + (0xfeb5, (3923, 1)), (0x1d46b, (4397, 1)), - (0xfd22, (3280, 2)), + (0x1db6, (224, 1)), (0x3141, (1100, 1)), - (0x2124, (408, 1)), - (0x3296, (1527, 1)), - (0x1d60e, (4793, 1)), - (0xfd30, (3308, 2)), - (0x1d7e9, (5264, 1)), + (0xfe9c, (3898, 1)), + (0x1d484, (4422, 1)), + (0x329d, (1534, 1)), + (0x1d530, (4578, 1)), + (0xfd32, (3312, 2)), (0xfc5f, (2869, 3)), - (0xfd01, (3214, 2)), + (0x1ee7b, (5435, 1)), (0xf0c, (128, 1)), - (0x24ea, (839, 1)), - (0xfebc, (3930, 1)), + (0x1d56f, (4634, 1)), + (0x1d6aa, (4947, 1)), + (0x33dc, (2341, 2)), (0x24e3, (832, 1)), - (0x1d76c, (5141, 1)), - (0x1f22e, (5620, 1)), - (0x1d626, (4817, 1)), - (0x1eead, (5413, 1)), + (0x1f22e, (5682, 1)), + (0x1d4b7, (4465, 1)), + (0x1d5d1, (4732, 1)), (0x1d7a6, (5199, 1)), - (0xfe70, (3830, 2)), - (0x1d7c7, (5232, 1)), - (0xfd35, (3318, 2)), + (0x2f4e, (935, 1)), + (0x1d6ae, (4951, 1)), + (0x3f2, (106, 1)), + (0x3280, (1505, 1)), (0x1d3e, (152, 1)), - (0x1d492, (4436, 1)), - (0xfe3b, (3781, 1)), - (0x2088, (343, 1)), + (0xfbef, (2630, 3)), + (0x1f102, (5494, 2)), (0xfe54, (3807, 1)), - (0xffc4, (4201, 1)), - (0x1d6be, (4967, 1)), - (0xfb9d, (2566, 1)), + (0x3263, (1455, 1)), + (0xff9b, (4163, 1)), + (0x1d584, (4655, 1)), + (0x3351, (1992, 4)), (0x3156, (1121, 1)), - (0x3357, (2015, 3)), (0xfbf2, (2639, 3)), (0xfb02, (2455, 2)), - (0x1ee1c, (5314, 1)), - (0xfd28, (3292, 2)), - (0xfb57, (2496, 1)), - (0x1d67c, (4903, 1)), - (0x676, (114, 2)), + (0x317b, (1158, 1)), + (0x314c, (1111, 1)), + (0x1c6, (41, 3)), + (0x1d73f, (5096, 1)), + (0x1ee4d, (5404, 1)), (0x1d53, (172, 1)), - (0xfc17, (2724, 2)), - (0x1fdd, (256, 3)), + (0x33d1, (2313, 2)), + (0x1d58a, (4661, 1)), + (0xfd83, (3489, 3)), (0x2178, (531, 2)), (0x1d751, (5114, 1)), - (0xfb7c, (2533, 1)), + (0xfd77, (3453, 3)), (0x1d479, (4411, 1)), (0x215d, (475, 3)), - (0x1f239, (5631, 1)), - (0x32c3, (1590, 2)), - (0xfc38, (2790, 2)), - (0x1d465, (4391, 1)), + (0xfd87, (3501, 3)), + (0x318a, (1173, 1)), + (0x1d43f, (4354, 1)), (0x2fcd, (1062, 1)), + (0x1d4f0, (4519, 1)), (0x1d59, (178, 1)), (0x1d65f, (4874, 1)), - (0x1d66c, (4887, 1)), - (0x24e9, (838, 1)), + (0x3393, (2162, 3)), + (0x1ee92, (5455, 1)), (0xa770, (2440, 1)), - (0xfd18, (3260, 2)), - (0xfe5a, (3813, 1)), + (0xfd0b, (3234, 2)), + (0x208a, (345, 1)), (0xfe80, (3858, 1)), - (0x1d603, (4782, 1)), + (0x1d7f3, (5274, 1)), (0xfd0d, (3238, 2)), (0x1d54a, (4598, 1)), - (0xfe79, (3844, 2)), + (0x1d699, (4932, 1)), (0xfe92, (3888, 1)), - (0x217b, (536, 3)), - (0x1d62, (187, 1)), - (0xfb89, (2546, 1)), - (0x2f3d, (918, 1)), - (0x327a, (1490, 2)), - (0xff4c, (4084, 1)), + (0xfe4c, (3799, 2)), + (0x1d653, (4862, 1)), + (0x1e04b, (5314, 1)), + (0x1d5b8, (4707, 1)), + (0x1d45a, (4380, 1)), + (0x335b, (2024, 2)), (0x1d789, (5170, 1)), (0xa7f2, (2441, 1)), - (0x2497, (694, 3)), + (0x1eea3, (5467, 1)), (0xff7c, (4132, 1)), - (0xfcaa, (3035, 2)), + (0x2176, (524, 3)), (0xffa6, (4174, 1)), (0xff57, (4095, 1)), - (0x1d581, (4652, 1)), - (0xff2d, (4053, 1)), - (0x1d5a6, (4689, 1)), - (0x1d4be, (4470, 1)), - (0x1ee7e, (5375, 1)), - (0xffa1, (4169, 1)), - (0x1d7de, (5253, 1)), - (0x1d499, (4443, 1)), - (0xffcb, (4206, 1)), - (0x1ee54, (5347, 1)), + (0x1ee79, (5433, 1)), + (0x1d5ae, (4697, 1)), + (0x1d46f, (4401, 1)), + (0x2da, (75, 2)), + (0x2f4d, (934, 1)), + (0xfdc5, (3681, 3)), + (0x3384, (2127, 2)), + (0x24c0, (797, 1)), + (0x1d57c, (4647, 1)), + (0x1d7b0, (5209, 1)), (0x1d5cb, (4726, 1)), - (0xfd2f, (3306, 2)), + (0x1d783, (5164, 1)), (0x1d4e8, (4511, 1)), - (0x1f105, (5438, 2)), + (0x1d58e, (4665, 1)), (0xff0d, (4021, 1)), - (0xfe6b, (3829, 1)), - (0x1d4b0, (4458, 1)), - (0x1d7e8, (5263, 1)), + (0x1d644, (4847, 1)), + (0x24c4, (801, 1)), + (0x2f52, (939, 1)), (0x1d68e, (4921, 1)), - (0x1d60a, (4789, 1)), - (0x1d5ab, (4694, 1)), + (0x1d50d, (4545, 1)), + (0xfb6b, (2516, 1)), + (0x2fcb, (1060, 1)), (0xff32, (4058, 1)), - (0x1f13e, (5551, 1)), (0xffab, (4179, 1)), - (0xfeca, (3944, 1)), - (0x1d774, (5149, 1)), - (0xfef2, (3984, 1)), - (0xfc46, (2818, 2)), - (0x1d408, (4299, 1)), - (0x33bf, (2272, 2)), - (0x1d664, (4879, 1)), - (0x1f224, (5610, 1)), + (0x316c, (1143, 1)), + (0x2070, (321, 1)), + (0xfd8d, (3519, 3)), + (0xfe74, (3836, 2)), + (0x2131, (414, 1)), + (0xff64, (4108, 1)), + (0x339b, (2180, 2)), + (0x1e06a, (5345, 1)), + (0x1f224, (5672, 1)), (0x1d405, (4296, 1)), - (0x3277, (1484, 2)), + (0xff49, (4081, 1)), (0xff37, (4063, 1)), - (0x33e9, (2369, 3)), - (0x2f08, (865, 1)), + (0x2075, (324, 1)), + (0xfebe, (3932, 1)), (0xfee8, (3974, 1)), - (0x1d7a3, (5196, 1)), - (0xfc64, (2884, 3)), - (0x1ee59, (5349, 1)), - (0x33a4, (2202, 3)), - (0x24a2, (727, 3)), - (0xfbfa, (2663, 3)), - (0x33a2, (2196, 3)), - (0xfb81, (2538, 1)), + (0xa7f8, (2444, 1)), + (0x1d7be, (5223, 1)), + (0x1d9d, (199, 1)), + (0x107b6, (4286, 1)), + (0x2f79, (978, 1)), + (0x1f212, (5653, 1)), + (0xfcdf, (3141, 3)), + (0x1d5a1, (4684, 1)), (0xfcc9, (3097, 2)), - (0x1d51c, (4559, 1)), - (0x1d508, (4542, 1)), - (0x3326, (1827, 3)), - (0x2168, (501, 2)), - (0x32c1, (1586, 2)), + (0x1ee11, (5365, 1)), + (0x339f, (2188, 3)), + (0xfb83, (2540, 1)), + (0x1f131, (5600, 1)), + (0xff08, (4016, 1)), (0xfe9e, (3900, 1)), (0xfe39, (3779, 1)), - (0x249d, (712, 3)), - (0x1d743, (5100, 1)), - (0x1ee31, (5330, 1)), - (0xfd1d, (3270, 2)), - (0x1d699, (4932, 1)), + (0x3386, (2131, 2)), + (0xfd6f, (3429, 3)), + (0x1d58b, (4662, 1)), + (0x1d5f3, (4766, 1)), + (0x1d5f, (184, 1)), (0xfc30, (2774, 2)), - (0x32b7, (1566, 2)), - (0x3274, (1478, 2)), + (0x33fa, (2420, 3)), + (0x1ee5b, (5412, 1)), + (0x2478, (599, 3)), (0x1d747, (5104, 1)), - (0xfe37, (3777, 1)), (0xfcf8, (3196, 2)), - (0xfcda, (3131, 2)), + (0x1d667, (4882, 1)), (0x1d796, (5183, 1)), - (0x2f2a, (899, 1)), - (0x3292, (1523, 1)), + (0x2011, (286, 1)), + (0x1f144, (5619, 1)), (0xfd3d, (3334, 2)), - (0xfb85, (2542, 1)), - (0xfcb5, (3057, 2)), - (0x1d6c2, (4971, 1)), - (0x2098, (358, 1)), + (0x3270, (1470, 2)), + (0x326c, (1464, 1)), + (0x1d5c8, (4723, 1)), + (0x1d68c, (4919, 1)), + (0xfdfb, (3745, 8)), (0xfdb6, (3636, 3)), - (0xfe4f, (3803, 1)), (0x2095, (355, 1)), - (0xfd85, (3495, 3)), - (0x2487, (654, 4)), - (0x1ee88, (5384, 1)), + (0x3219, (1278, 4)), + (0x2499, (700, 3)), + (0x1ee52, (5408, 1)), + (0x2dc, (79, 2)), (0x210e, (387, 1)), - (0xfe4b, (3797, 2)), + (0x1d5ce, (4729, 1)), (0x1d687, (4914, 1)), - (0xfbeb, (2618, 3)), - (0x2b8, (70, 1)), + (0x1d702, (5035, 1)), + (0x2093, (353, 1)), (0x1d615, (4800, 1)), (0x2f0c, (869, 1)), (0x3185, (1168, 1)), (0x1d42a, (4333, 1)), - (0x1cb, (52, 2)), - (0x1d428, (4331, 1)), + (0x247b, (608, 3)), + (0xfeee, (3980, 1)), (0x10785, (4239, 1)), - (0x3283, (1508, 1)), (0x209a, (360, 1)), - (0x1d47c, (4414, 1)), - (0xff5a, (4098, 1)), - (0x2f01, (858, 1)), - (0x3176, (1153, 1)), - (0xfc43, (2812, 2)), - (0xff5c, (4100, 1)), - (0x1d722, (5067, 1)), + (0xfb72, (2523, 1)), + (0x33e2, (2355, 2)), + (0xfc75, (2924, 2)), + (0x24d2, (815, 1)), + (0x1e05b, (5330, 1)), + (0x212c, (410, 1)), + (0x247f, (622, 4)), + (0x1d45e, (4384, 1)), (0xfee3, (3969, 1)), - (0x1d720, (5065, 1)), - (0x1d600, (4779, 1)), + (0x2f19, (882, 1)), + (0x321e, (1301, 6)), (0x2f05, (862, 1)), - (0x1d47e, (4416, 1)), - (0xfc80, (2946, 2)), - (0x1ee6a, (5359, 1)), + (0xfb16, (2473, 2)), + (0x3142, (1101, 1)), + (0x107a5, (4270, 1)), (0x2001, (276, 1)), - (0x1ee34, (5332, 1)), - (0xfd55, (3351, 3)), - (0x1d4c1, (4473, 1)), + (0xfc84, (2954, 2)), + (0x1d55c, (4615, 1)), + (0x1d7c4, (5229, 1)), (0x2fa0, (1017, 1)), - (0x1f109, (5446, 2)), - (0x1d5dc, (4743, 1)), - (0x3339, (1902, 3)), + (0x1f143, (5618, 1)), + (0x2f8f, (1000, 1)), + (0x24c9, (806, 1)), + (0x32c5, (1594, 2)), (0x248f, (672, 2)), - (0x247a, (605, 3)), - (0xab5e, (2448, 1)), - (0x2a75, (847, 2)), - (0x1d7e6, (5261, 1)), - (0x2f12, (875, 1)), - (0x24a4, (733, 3)), - (0x1d62b, (4822, 1)), - (0x2f90, (1001, 1)), - (0x32ff, (1668, 2)), + (0xff84, (4140, 1)), + (0x3324, (1820, 4)), + (0xfcb7, (3061, 2)), + (0x1e041, (5304, 1)), + (0x24d9, (822, 1)), + (0xfd16, (3256, 2)), + (0x3251, (1422, 2)), + (0xfc92, (2982, 2)), (0xfe8f, (3885, 1)), - (0x1f13b, (5548, 1)), + (0xfdc4, (3678, 3)), (0x2f1c, (885, 1)), - (0xfce1, (3147, 2)), - (0xfc6d, (2908, 2)), + (0x1f22b, (5679, 1)), + (0x1d5db, (4742, 1)), (0x2f41, (922, 1)), (0xfd1b, (3266, 2)), (0x3217, (1270, 4)), - (0xfb77, (2528, 1)), - (0xfe87, (3871, 2)), + (0x1f250, (5723, 1)), + (0x3321, (1809, 5)), + (0x2f40, (921, 1)), (0x2fca, (1059, 1)), - (0xff8d, (4149, 1)), - (0x33b2, (2246, 2)), - (0x2fd1, (1066, 1)), + (0x107a6, (4271, 1)), + (0x1d589, (4660, 1)), (0x3136, (1089, 1)), + (0xfc7d, (2940, 2)), (0xfb87, (2544, 1)), - (0x1d485, (4423, 1)), - (0x1d6f9, (5026, 1)), + (0xfc0e, (2706, 2)), + (0x1f106, (5502, 2)), (0x2f65, (958, 1)), - (0xfcc4, (3087, 2)), - (0x1d550, (4604, 1)), - (0x3170, (1147, 1)), - (0x1d484, (4422, 1)), - (0x217d, (540, 1)), - (0x1d48f, (4433, 1)), - (0x1d45e, (4384, 1)), - (0x1f216, (5596, 1)), - (0x107aa, (4275, 1)), + (0xfe56, (3809, 1)), + (0xfb9c, (2565, 1)), + (0xfee4, (3970, 1)), + (0x1ee06, (5354, 1)), + (0x1d6d2, (4987, 1)), + (0x1d45d, (4383, 1)), + (0x1d660, (4875, 1)), + (0x1f216, (5658, 1)), + (0x1d400, (4291, 1)), (0xfb13, (2467, 2)), - (0x2fc1, (1050, 1)), - (0xff7f, (4135, 1)), - (0xfb03, (2457, 3)), - (0x32f9, (1662, 1)), - (0x32d8, (1629, 1)), + (0xfc6f, (2912, 2)), + (0xfca7, (3029, 2)), + (0xfe13, (3760, 1)), + (0xfe4b, (3797, 2)), + (0x1d78d, (5174, 1)), (0xff2e, (4054, 1)), - (0x1d4e6, (4509, 1)), - (0x2161, (484, 2)), - (0xfe5b, (3814, 1)), - (0xfd15, (3254, 2)), - (0xa69c, (2438, 1)), - (0xfef6, (3990, 3)), + (0x2f6b, (964, 1)), + (0xfbe6, (2611, 1)), + (0x1d4f6, (4525, 1)), + (0x107a8, (4273, 1)), + (0x328b, (1516, 1)), + (0x1d5c, (181, 1)), (0x246a, (567, 2)), - (0x3314, (1751, 2)), - (0x2f7b, (980, 1)), + (0xfcb9, (3065, 2)), + (0xfbd6, (2594, 1)), (0x33f7, (2411, 3)), (0xfd08, (3228, 2)), - (0x1d7d0, (5239, 1)), - (0x32dc, (1633, 1)), + (0x32c7, (1598, 2)), + (0x1d684, (4911, 1)), + (0x1eea1, (5465, 1)), (0xfd78, (3456, 3)), - (0x33cc, (2303, 2)), - (0x1f225, (5611, 1)), - (0xfcf3, (3184, 3)), - (0x333b, (1909, 5)), - (0x1ee0c, (5298, 1)), - (0x1d64e, (4857, 1)), - (0x1d73e, (5095, 1)), - (0xfd2d, (3302, 2)), - (0x1f11c, (5486, 3)), - (0x1f229, (5615, 1)), - (0xfd7b, (3465, 3)), + (0x1ee80, (5438, 1)), + (0x1f225, (5673, 1)), + (0x1eeb6, (5484, 1)), + (0x1ee0c, (5360, 1)), + (0xab5c, (2446, 1)), + (0xfb5c, (2501, 1)), + (0x322e, (1349, 3)), + (0xfc4b, (2828, 2)), + (0x24c7, (804, 1)), + (0x3360, (2034, 2)), (0x1d737, (5088, 1)), - (0xfc5a, (2858, 2)), - (0x2f54, (941, 1)), - (0x1d35, (144, 1)), - (0x1d5d6, (4737, 1)), - (0x2f1a, (883, 1)), - (0x1d771, (5146, 1)), - (0x2083, (338, 1)), - (0x1d753, (5116, 1)), - (0x1d516, (4553, 1)), - (0xfdc6, (3684, 3)), - (0x32ce, (1616, 2)), - (0x1d69e, (4937, 1)), - (0x339f, (2188, 3)), - (0xfecf, (3949, 1)), + (0x33d0, (2311, 2)), + (0xfc90, (2978, 2)), + (0x1eeb0, (5478, 1)), + (0xfda1, (3573, 3)), + (0x3375, (2093, 2)), + (0x2f00, (857, 1)), + (0xfb9a, (2563, 1)), + (0x322a, (1337, 3)), + (0x32a9, (1546, 1)), + (0x1d472, (4404, 1)), + (0x1d4d4, (4491, 1)), + (0x1f221, (5669, 1)), + (0xff7b, (4131, 1)), + (0x1d46, (160, 1)), + (0xffb1, (4185, 1)), (0x1d436, (4345, 1)), - (0xb9, (13, 1)), - (0x1f101, (5430, 2)), - (0xfbf9, (2660, 3)), - (0x2154, (448, 3)), + (0x3298, (1529, 1)), + (0xfc43, (2812, 2)), + (0xfc31, (2776, 2)), + (0x1d679, (4900, 1)), (0x315b, (1126, 1)), - (0x10791, (4250, 1)), - (0x1d434, (4343, 1)), + (0x1d712, (5051, 1)), (0xfe99, (3895, 1)), + (0xfed1, (3951, 1)), (0x339a, (2178, 2)), (0x1d4a6, (4451, 1)), - (0x1d470, (4402, 1)), - (0x1d6b0, (4953, 1)), - (0xfd02, (3216, 2)), - (0x2fc6, (1055, 1)), - (0x2f5d, (950, 1)), - (0x1eeb4, (5420, 1)), - (0x3237, (1376, 3)), - (0x1da7, (209, 1)), - (0x1d7e3, (5258, 1)), - (0xfb60, (2505, 1)), + (0xfbd5, (2593, 1)), + (0x210a, (383, 1)), + (0xfb96, (2559, 1)), + (0x2f8e, (999, 1)), + (0x1d7a9, (5202, 1)), + (0xfb5e, (2503, 1)), + (0x10793, (4252, 1)), + (0x2f56, (943, 1)), + (0x207d, (332, 1)), + (0x1f227, (5675, 1)), (0xfc94, (2986, 2)), - (0x1d63f, (4842, 1)), + (0x1d4d3, (4490, 1)), (0xfd67, (3405, 3)), - (0x1d710, (5049, 1)), + (0xff09, (4017, 1)), (0x1d5a4, (4687, 1)), - (0xfe38, (3778, 1)), - (0x1eeb2, (5418, 1)), - (0xfce8, (3161, 2)), + (0x1e06d, (5348, 1)), + (0x1d39, (148, 1)), + (0x3210, (1242, 4)), (0x1d721, (5066, 1)), (0xff91, (4153, 1)), - (0x32e2, (1639, 1)), - (0x212d, (411, 1)), - (0x1eea7, (5408, 1)), - (0x1f130, (5537, 1)), + (0x1d62d, (4824, 1)), + (0x1d7c0, (5225, 1)), + (0x1f213, (5654, 2)), + (0x1f130, (5599, 1)), + (0x1d4d5, (4492, 1)), (0x1db2, (220, 1)), - (0x1d730, (5081, 1)), (0x2f98, (1009, 1)), - (0x1d7d3, (5242, 1)), - (0xfc27, (2756, 2)), - (0x247b, (608, 3)), - (0x210a, (383, 1)), - (0x1d478, (4410, 1)), - (0xfc97, (2992, 3)), + (0x1d56a, (4629, 1)), + (0x2477, (596, 3)), + (0x1d526, (4568, 1)), + (0x2475, (590, 3)), + (0x107b8, (4288, 1)), + (0x1f242, (5702, 3)), (0x587, (110, 2)), - (0xfc45, (2816, 2)), - (0x3311, (1737, 4)), + (0x1d7b3, (5212, 1)), + (0x2076, (325, 1)), (0x1d6f2, (5019, 1)), - (0x314b, (1110, 1)), - (0x2f69, (962, 1)), + (0xfdbc, (3654, 3)), + (0x24a6, (739, 3)), + (0x33d4, (2320, 2)), (0x1d4d8, (4495, 1)), - (0x1f211, (5590, 1)), - (0x319f, (1191, 1)), - (0x1d6c1, (4970, 1)), - (0x1f121, (5501, 3)), - (0x323f, (1400, 3)), - (0x1d66d, (4888, 1)), + (0x320c, (1228, 3)), + (0x1d57b, (4646, 1)), + (0x1ee15, (5369, 1)), + (0x24a4, (733, 3)), + (0x2149, (434, 1)), (0xfbf8, (2657, 3)), (0x2f04, (861, 1)), (0x1d5ca, (4725, 1)), - (0x2f29, (898, 1)), - (0x316b, (1142, 1)), - (0xfe50, (3804, 1)), - (0xbc, (15, 3)), - (0x215a, (466, 3)), + (0x1d57, (176, 1)), + (0xff22, (4042, 1)), + (0x1d68b, (4918, 1)), + (0x1d7b5, (5214, 1)), + (0x1d4c8, (4479, 1)), + (0x2088, (343, 1)), (0x3340, (1929, 5)), - (0x33e3, (2357, 2)), + (0x1d507, (4541, 1)), (0x325d, (1446, 2)), - (0xfc74, (2922, 2)), + (0x1d5fe, (4777, 1)), (0x317c, (1159, 1)), - (0xfe68, (3826, 1)), - (0xfcbb, (3069, 2)), - (0x1d58a, (4661, 1)), - (0xfc8c, (2970, 2)), - (0x24c6, (803, 1)), - (0x1f110, (5450, 3)), - (0x3253, (1426, 2)), - (0x3178, (1155, 1)), - (0x24b8, (789, 1)), - (0xfd9b, (3555, 3)), + (0x1ee47, (5401, 1)), + (0x33b0, (2242, 2)), + (0x1d786, (5167, 1)), + (0xfc83, (2952, 2)), + (0x1d444, (4359, 1)), + (0x32f1, (1654, 1)), + (0x3152, (1117, 1)), + (0xff13, (4027, 1)), + (0xfe38, (3778, 1)), + (0x1d4ec, (4515, 1)), (0xfd7e, (3474, 3)), - (0x3038, (1073, 1)), - (0x1d76f, (5144, 1)), - (0x1f148, (5561, 1)), - (0x222c, (546, 2)), - (0x1d4e7, (4510, 1)), - (0xffad, (4181, 1)), - (0x24bc, (793, 1)), - (0xff5b, (4099, 1)), - (0x1d663, (4878, 1)), - (0x1d5b1, (4700, 1)), - (0x1f226, (5612, 1)), - (0x3183, (1166, 1)), - (0x329d, (1534, 1)), - (0xffa9, (4177, 1)), - (0x215c, (472, 3)), - (0x1dbc, (230, 1)), + (0x336f, (2077, 3)), + (0x3d0, (95, 1)), + (0x1d7f1, (5272, 1)), + (0x1f251, (5724, 1)), + (0x1db3, (221, 1)), + (0x1d514, (4552, 1)), + (0x33fb, (2423, 3)), + (0xfbf1, (2636, 3)), + (0xfd84, (3492, 3)), + (0x1fbf3, (5728, 1)), + (0x328a, (1515, 1)), + (0x24ab, (754, 3)), + (0x1d7e7, (5262, 1)), + (0x335c, (2026, 2)), + (0xff85, (4141, 1)), + (0x1d4bd, (4469, 1)), (0xfdb5, (3633, 3)), - (0x1d5f9, (4772, 1)), - (0x2f0b, (868, 1)), - (0x326c, (1464, 1)), - (0x1d482, (4420, 1)), - (0xfc20, (2742, 2)), + (0xfdf2, (3696, 4)), + (0xfe83, (3863, 2)), + (0x1fdd, (256, 3)), + (0xfc7b, (2936, 2)), + (0x319a, (1186, 1)), (0x3275, (1480, 2)), - (0x208d, (348, 1)), - (0x2f2f, (904, 1)), - (0x1d422, (4325, 1)), - (0x1d6e9, (5010, 1)), + (0xfd20, (3276, 2)), + (0x1d402, (4293, 1)), + (0xff67, (4111, 1)), + (0x1d7dd, (5252, 1)), + (0xfc2e, (2770, 2)), (0xff04, (4012, 1)), - (0xfce3, (3151, 2)), - (0x1ee02, (5289, 1)), - (0xfe97, (3893, 1)), + (0x1eeb1, (5479, 1)), + (0x3317, (1765, 5)), (0x3367, (2053, 3)), + (0x1d652, (4861, 1)), (0x337e, (2113, 2)), - (0xbe, (21, 3)), - (0xfbfd, (2670, 1)), - (0x2461, (557, 1)), - (0x249f, (718, 3)), + (0x1d9c, (198, 1)), + (0x1079e, (4263, 1)), + (0x2f5f, (952, 1)), (0xfea6, (3908, 1)), - (0x1f21b, (5601, 1)), - (0x1ee90, (5391, 1)), + (0x1d66, (191, 1)), + (0x1ee90, (5453, 1)), + (0x1d723, (5068, 1)), (0x247e, (618, 4)), - (0x1d6c5, (4974, 1)), - (0x330a, (1711, 3)), - (0x1d535, (4583, 1)), - (0x1d46, (160, 1)), - (0xff78, (4128, 1)), - (0x3f2, (106, 1)), - (0x2086, (341, 1)), + (0x216b, (506, 3)), + (0x1d74c, (5109, 1)), + (0x1d68d, (4920, 1)), + (0x3211, (1246, 4)), + (0x1d77f, (5160, 1)), + (0xff86, (4142, 1)), + (0x2f18, (881, 1)), (0x3347, (1953, 5)), - (0x1d65, (190, 1)), - (0x1d775, (5150, 1)), - (0x3236, (1373, 3)), - (0xa7f4, (2443, 1)), - (0x2fc0, (1049, 1)), - (0x2f22, (891, 1)), - (0x1ee09, (5295, 1)), - (0x3197, (1183, 1)), - (0xeb3, (122, 2)), - (0x10790, (4249, 1)), + (0xfc72, (2918, 2)), + (0x1d496, (4440, 1)), + (0x1f129, (5587, 3)), + (0x210d, (386, 1)), + (0x1d40e, (4305, 1)), + (0x1d4e0, (4503, 1)), + (0x1d571, (4636, 1)), + (0x200a, (285, 1)), + (0x1d53d, (4590, 1)), (0x2099, (359, 1)), - (0xfb69, (2514, 1)), - (0x1fdf, (262, 3)), - (0x1d701, (5034, 1)), - (0xfcf0, (3177, 2)), - (0x1ee0a, (5296, 1)), - (0x3360, (2034, 2)), - (0x2f21, (890, 1)), - (0x1d6fe, (5031, 1)), - (0x3276, (1482, 2)), - (0xff1e, (4038, 1)), + (0x2a75, (847, 2)), + (0xfe40, (3786, 1)), + (0xfebd, (3931, 1)), + (0x1d44b, (4366, 1)), + (0x32d3, (1624, 1)), + (0x1d666, (4881, 1)), + (0xfbaa, (2581, 1)), + (0x2f7e, (983, 1)), + (0xff77, (4127, 1)), + (0xff25, (4045, 1)), + (0x1d693, (4926, 1)), (0xfeb6, (3924, 1)), (0x1d695, (4928, 1)), - (0x1d4f5, (4524, 1)), - (0x1da1, (203, 1)), + (0xffd5, (4214, 1)), + (0x1d491, (4435, 1)), (0x3359, (2020, 2)), - (0x1d5a7, (4690, 1)), - (0x1d504, (4539, 1)), - (0x1ee32, (5331, 1)), + (0x1d57f, (4650, 1)), + (0xffd7, (4216, 1)), + (0x1ee32, (5393, 1)), (0x3267, (1459, 1)), + (0xfd30, (3308, 2)), (0xfbed, (2624, 3)), - (0x1d536, (4584, 1)), - (0xff38, (4064, 1)), - (0x24b2, (775, 3)), - (0x1d6d3, (4988, 1)), + (0xfd94, (3534, 3)), + (0x3278, (1486, 2)), + (0xff97, (4159, 1)), (0x1d686, (4913, 1)), - (0x32a5, (1542, 1)), - (0x1d552, (4605, 1)), - (0x2fcf, (1064, 1)), - (0x1d6aa, (4947, 1)), - (0x331d, (1793, 3)), - (0xfd7f, (3477, 3)), + (0x1f108, (5506, 2)), + (0x2f2c, (901, 1)), + (0xfcd1, (3113, 2)), + (0x2468, (564, 1)), + (0xfe3e, (3784, 1)), + (0xff66, (4110, 1)), (0xff14, (4028, 1)), - (0x1d79c, (5189, 1)), - (0xfe71, (3832, 2)), - (0x248e, (670, 2)), + (0x1d74d, (5110, 1)), + (0x32f5, (1658, 1)), + (0x33cd, (2305, 2)), (0x2469, (565, 2)), - (0x1f230, (5622, 1)), - (0x1f113, (5459, 3)), - (0x1d481, (4419, 1)), + (0x32b4, (1560, 2)), + (0x1d65b, (4870, 1)), + (0x1f113, (5521, 3)), + (0x2155, (451, 3)), (0x1daa, (212, 1)), - (0x30ff, (1082, 2)), - (0x1d7cb, (5236, 1)), - (0xff31, (4057, 1)), - (0x339d, (2184, 2)), + (0xfed6, (3956, 1)), + (0x1d5bd, (4712, 1)), + (0x1e045, (5308, 1)), + (0xfdf3, (3700, 4)), (0xfb8c, (2549, 1)), - (0x2f5b, (948, 1)), - (0x2f62, (955, 1)), - (0x1d44, (158, 1)), + (0x1d7d4, (5243, 1)), + (0x2b8, (70, 1)), (0x1d565, (4624, 1)), - (0x2071, (322, 1)), - (0x247c, (611, 3)), - (0x1f142, (5555, 1)), - (0x10792, (4251, 1)), - (0x1d544, (4596, 1)), - (0x1d6fa, (5027, 1)), - (0x2d9, (73, 2)), - (0x1d573, (4638, 1)), - (0x2f5c, (949, 1)), - (0x1d7a7, (5200, 1)), + (0x2fd5, (1070, 1)), + (0x1d4af, (4457, 1)), + (0xfcf2, (3181, 3)), + (0x1f142, (5617, 1)), + (0x3195, (1181, 1)), + (0x1d56c, (4631, 1)), + (0xfd0e, (3240, 2)), + (0x1eeb7, (5485, 1)), + (0xff54, (4092, 1)), + (0x678, (118, 2)), + (0xfbee, (2627, 3)), (0x1d540, (4592, 1)), - (0xfdbb, (3651, 3)), + (0x33be, (2270, 2)), (0xfead, (3915, 1)), (0x1d40c, (4303, 1)), - (0x3362, (2038, 3)), - (0x1d61d, (4808, 1)), - (0x33d5, (2322, 3)), + (0xfb23, (2480, 1)), + (0xfee6, (3972, 1)), + (0xffa1, (4169, 1)), (0x1d674, (4895, 1)), (0x1d36, (145, 1)), - (0x1d5c8, (4723, 1)), - (0x1d724, (5069, 1)), - (0x1d400, (4291, 1)), + (0x2106, (377, 3)), + (0x3231, (1358, 3)), + (0x1ee59, (5411, 1)), (0x3338, (1898, 4)), (0x1d7c3, (5228, 1)), - (0x2fae, (1031, 1)), - (0x1d30, (139, 1)), - (0x33ea, (2372, 3)), - (0x1f234, (5626, 1)), - (0xffe1, (4221, 1)), + (0x107b5, (4285, 1)), + (0x2b0, (62, 1)), + (0xfc36, (2786, 2)), + (0x1f234, (5688, 1)), + (0x1d473, (4405, 1)), (0x313f, (1098, 1)), - (0x1d56d, (4632, 1)), - (0xfc0f, (2708, 2)), + (0xfd7b, (3465, 3)), + (0x3154, (1119, 1)), + (0x1ee31, (5392, 1)), (0xffae, (4182, 1)), - (0x3336, (1890, 5)), - (0x3355, (2007, 2)), - (0x1ee4b, (5341, 1)), - (0xff7b, (4131, 1)), + (0x1d4b, (165, 1)), + (0x1ee4b, (5403, 1)), + (0x1d672, (4893, 1)), (0x313b, (1094, 1)), - (0xffa7, (4175, 1)), - (0x1d6bc, (4965, 1)), + (0x1d7ae, (5207, 1)), + (0xfd35, (3318, 2)), (0x3200, (1192, 3)), - (0xfc0d, (2704, 2)), - (0x1d62e, (4825, 1)), - (0x3263, (1455, 1)), - (0x1d72b, (5076, 1)), - (0xfb61, (2506, 1)), + (0xff19, (4033, 1)), + (0x1d538, (4586, 1)), + (0x1f105, (5500, 2)), + (0x2f3a, (915, 1)), + (0xff2d, (4053, 1)), + (0x1ee03, (5352, 1)), (0x2fc5, (1054, 1)), - (0x2f19, (882, 1)), + (0xfc19, (2728, 2)), (0xfb27, (2484, 1)), - (0x1d4b1, (4459, 1)), - (0x1d44a, (4365, 1)), - (0x1ee2a, (5323, 1)), - (0x1d50e, (4546, 1)), + (0x2f31, (906, 1)), + (0x2a76, (849, 3)), + (0x1d655, (4864, 1)), + (0x1d47e, (4416, 1)), (0x246f, (577, 2)), - (0xab5f, (2449, 1)), - (0x1d4b7, (4465, 1)), - (0xfccb, (3101, 2)), - (0x321d, (1294, 7)), - (0xfd0b, (3234, 2)), - (0xfcab, (3037, 2)), - (0x3175, (1152, 1)), - (0xfeaf, (3917, 1)), - (0xff8a, (4146, 1)), + (0x2f13, (876, 1)), + (0x1f233, (5687, 1)), + (0x1d59f, (4682, 1)), + (0x2497, (694, 3)), + (0x2e9f, (855, 1)), + (0x32dd, (1634, 1)), + (0xfd28, (3292, 2)), + (0x1d7bb, (5220, 1)), + (0x1d7d2, (5241, 1)), (0x32e1, (1638, 1)), (0x1d69b, (4934, 1)), - (0x1f12e, (5535, 2)), - (0x3376, (2095, 2)), + (0x107ac, (4277, 1)), + (0xfc93, (2984, 2)), (0x2f34, (909, 1)), (0x2490, (674, 2)), - (0x1d439, (4348, 1)), - (0x2471, (581, 2)), - (0x2f30, (905, 1)), + (0xfb6e, (2519, 1)), + (0x1f12d, (5595, 2)), + (0xfba1, (2570, 1)), (0x1d48d, (4431, 1)), - (0x1d736, (5087, 1)), - (0xfd9e, (3564, 3)), - (0xfe88, (3873, 2)), - (0xfc21, (2744, 2)), - (0xfee6, (3972, 1)), - (0x140, (30, 2)), - (0x207f, (334, 1)), + (0x1f228, (5676, 1)), + (0x2471, (581, 2)), + (0xfb59, (2498, 1)), + (0xfec3, (3937, 1)), + (0x329a, (1531, 1)), + (0x33c9, (2297, 2)), + (0x1dbd, (231, 1)), (0x1d474, (4406, 1)), (0x1d673, (4894, 1)), - (0x107b4, (4284, 1)), - (0x2f72, (971, 1)), + (0xffe1, (4221, 1)), + (0x1d4c3, (4475, 1)), (0x1d649, (4852, 1)), - (0x1d7cf, (5238, 1)), - (0xfcd3, (3117, 2)), - (0x1f21c, (5602, 1)), - (0xfcd5, (3121, 2)), + (0xfed2, (3952, 1)), + (0x3205, (1207, 3)), + (0x1d537, (4585, 1)), + (0xfcd9, (3129, 2)), + (0x3140, (1099, 1)), (0x309f, (1080, 2)), - (0x1d7be, (5223, 1)), - (0x1f237, (5629, 1)), - (0x33df, (2348, 3)), - (0xff77, (4127, 1)), - (0x2175, (522, 2)), - (0x2107, (380, 1)), - (0xfca4, (3023, 2)), - (0xfc01, (2676, 3)), - (0xfc3a, (2794, 2)), - (0x1f2, (58, 2)), - (0xfef4, (3986, 1)), + (0xff58, (4096, 1)), + (0x1d707, (5040, 1)), + (0x1d5d8, (4739, 1)), + (0x2f5e, (951, 1)), + (0x329c, (1533, 1)), + (0x1ee8f, (5452, 1)), + (0x1f21a, (5662, 1)), + (0x1fc1, (244, 3)), + (0x1d71b, (5060, 1)), + (0x1ee29, (5384, 1)), + (0x2f5d, (950, 1)), (0x3346, (1950, 3)), - (0x328f, (1520, 1)), - (0x1d56, (175, 1)), - (0x3361, (2036, 2)), - (0x1f23a, (5632, 1)), - (0x1ee2f, (5328, 1)), - (0x1d5eb, (4758, 1)), - (0xfc9a, (3001, 3)), - (0x1d4e1, (4504, 1)), - (0xfd58, (3360, 3)), - (0x24c0, (797, 1)), - (0x3254, (1428, 2)), + (0x33cc, (2303, 2)), + (0x1d676, (4897, 1)), + (0x2fc1, (1050, 1)), + (0x1d604, (4783, 1)), + (0x1d4ed, (4516, 1)), + (0x1d508, (4542, 1)), + (0xfd5d, (3375, 3)), + (0x1d5a7, (4690, 1)), + (0x1e033, (5290, 1)), + (0xb8, (11, 2)), (0xffda, (4217, 1)), - (0x107b6, (4286, 1)), - (0x249c, (709, 3)), + (0x3273, (1476, 2)), + (0xff21, (4041, 1)), (0x24cf, (812, 1)), - (0x2153, (445, 3)), - (0x1d5f1, (4764, 1)), - (0x1ee8d, (5388, 1)), - (0x1d46f, (4401, 1)), - (0x2f8b, (996, 1)), - (0x2fd0, (1065, 1)), + (0x3332, (1871, 6)), + (0x1d413, (4310, 1)), + (0x249c, (709, 3)), + (0xff30, (4056, 1)), + (0x1ee68, (5419, 1)), + (0x1d5b0, (4699, 1)), + (0xfbd7, (2595, 1)), (0x3133, (1086, 1)), (0xfd33, (3314, 2)), - (0xfd87, (3501, 3)), - (0x3187, (1170, 1)), - (0xffba, (4194, 1)), - (0x1d50, (169, 1)), - (0x1d5cc, (4727, 1)), + (0xfc12, (2714, 2)), + (0x334a, (1964, 6)), + (0x1d48f, (4433, 1)), + (0xff17, (4031, 1)), + (0x13f, (28, 2)), (0x32c8, (1600, 2)), - (0xfb80, (2537, 1)), - (0x1d68b, (4918, 1)), - (0xfb74, (2525, 1)), + (0xfe63, (3822, 1)), + (0x1d6f7, (5024, 1)), + (0x33e6, (2363, 2)), (0x1d689, (4916, 1)), - (0x213b, (422, 3)), - (0xfbaf, (2586, 1)), + (0x1d7fc, (5283, 1)), + (0x2167, (497, 4)), (0x1da2, (204, 1)), - (0x1d4b, (165, 1)), + (0x1eea8, (5471, 1)), (0x3169, (1140, 1)), - (0xfed9, (3959, 1)), - (0x1ee97, (5398, 1)), - (0x1d446, (4361, 1)), - (0x1f190, (5582, 2)), - (0x1d411, (4308, 1)), - (0xfc61, (2875, 3)), + (0xaf, (4, 2)), + (0xfcb6, (3059, 2)), + (0xfbeb, (2618, 3)), + (0xfe61, (3820, 1)), + (0x1d6f5, (5022, 1)), + (0x3277, (1484, 2)), (0x321b, (1286, 4)), - (0x1d45c, (4382, 1)), - (0xfc9f, (3013, 2)), - (0xfb14, (2469, 2)), - (0x1f14c, (5567, 2)), - (0xfbee, (2627, 3)), - (0xfbe6, (2611, 1)), - (0x3d1, (96, 1)), - (0x1d5f, (184, 1)), - (0x3341, (1934, 3)), - (0x1d5db, (4742, 1)), - (0x1d6cf, (4984, 1)), - (0xff41, (4073, 1)), + (0xfc28, (2758, 2)), + (0x1d51c, (4559, 1)), + (0xff92, (4154, 1)), + (0x3395, (2168, 2)), + (0x1d5fd, (4776, 1)), + (0x1d722, (5067, 1)), + (0x2f99, (1010, 1)), + (0x33a4, (2202, 3)), + (0x3d6, (103, 1)), + (0x24e8, (837, 1)), + (0x212f, (412, 1)), + (0x1f201, (5648, 2)), (0xfec0, (3934, 1)), - (0x3396, (2170, 2)), + (0x1d67d, (4904, 1)), (0x33a1, (2194, 2)), - (0xfda7, (3591, 3)), + (0xfca6, (3027, 2)), (0x2f85, (990, 1)), + (0x37a, (88, 2)), (0x32cf, (1618, 3)), - (0xfcdc, (3135, 2)), - (0x3259, (1438, 2)), - (0x1d667, (4882, 1)), - (0xfdbc, (3654, 3)), - (0x32f0, (1653, 1)), - (0x33ca, (2299, 2)), + (0x1f200, (5646, 2)), + (0x2e4, (87, 1)), + (0x1d75e, (5127, 1)), + (0x1d4a5, (4450, 1)), + (0xfed0, (3950, 1)), + (0x3269, (1461, 1)), (0x1d55e, (4617, 1)), - (0xff9d, (4165, 1)), - (0xfc7f, (2944, 2)), + (0x1d439, (4348, 1)), (0x1d5b5, (4704, 1)), - (0xffb3, (4187, 1)), - (0x1f10a, (5448, 2)), - (0x1d748, (5105, 1)), - (0x24a3, (730, 3)), + (0xfc64, (2884, 3)), + (0xfeb0, (3918, 1)), + (0xfbd8, (2596, 1)), + (0x3147, (1106, 1)), + (0xfbe3, (2608, 1)), (0x2113, (392, 1)), - (0xfee1, (3967, 1)), - (0x1d64c, (4855, 1)), - (0xfcfd, (3206, 2)), + (0x1e05f, (5334, 1)), + (0x3368, (2056, 3)), (0xff4e, (4086, 1)), (0x1d6a9, (4946, 1)), - (0xffd5, (4214, 1)), - (0x2fd3, (1068, 1)), - (0x1d595, (4672, 1)), - (0x1ee12, (5304, 1)), - (0xfda2, (3576, 3)), - (0xfc67, (2893, 3)), - (0x2fb8, (1041, 1)), + (0xfb6d, (2518, 1)), + (0x332b, (1840, 6)), + (0x334c, (1973, 5)), + (0xfb52, (2491, 1)), + (0x1d426, (4329, 1)), + (0xab5f, (2449, 1)), + (0xfe5d, (3816, 1)), + (0x1d6bf, (4968, 1)), (0x1d6b5, (4958, 1)), - (0xfe48, (3792, 1)), + (0xfba6, (2577, 1)), (0x1ffe, (273, 2)), - (0x24bb, (792, 1)), - (0x216d, (510, 1)), - (0x1d6af, (4952, 1)), - (0x2173, (519, 2)), + (0xfbd4, (2592, 1)), + (0xfc6d, (2908, 2)), + (0xff20, (4040, 1)), + (0x1d5ab, (4694, 1)), (0x1d5f2, (4765, 1)), - (0xfb59, (2498, 1)), - (0x1d77e, (5159, 1)), + (0x325c, (1444, 2)), + (0xfe42, (3788, 1)), (0x3383, (2125, 2)), (0xfb22, (2479, 1)), - (0x24a8, (745, 3)), - (0x1d6c8, (4977, 1)), + (0x1d5ec, (4759, 1)), + (0x1d63e, (4841, 1)), (0xfc7a, (2934, 2)), - (0xfd8a, (3510, 3)), - (0x1d773, (5148, 1)), - (0xfc5e, (2866, 3)), - (0x1f213, (5592, 2)), + (0x1d4cb, (4482, 1)), + (0xfd9f, (3567, 3)), + (0x319f, (1191, 1)), + (0x1d521, (4563, 1)), (0x217f, (542, 1)), (0x3238, (1379, 3)), + (0x1d438, (4347, 1)), (0xffa4, (4172, 1)), - (0x1ee0e, (5300, 1)), - (0xfdb8, (3642, 3)), - (0x3196, (1182, 1)), + (0x24aa, (751, 3)), + (0xba, (14, 1)), (0xfc79, (2932, 2)), - (0x1d633, (4830, 1)), - (0x1d4d4, (4491, 1)), + (0xfe5b, (3814, 1)), + (0x1ee02, (5351, 1)), (0x32fb, (1664, 1)), (0x2d8, (71, 2)), - (0x1d5ff, (4778, 1)), - (0x3d5, (102, 1)), - (0x2103, (372, 2)), + (0x32da, (1631, 1)), + (0x338c, (2146, 2)), + (0xfd2b, (3298, 2)), (0xfd06, (3224, 2)), - (0x1d597, (4674, 1)), + (0x32b0, (1553, 1)), + (0x1e03e, (5301, 1)), (0x2fab, (1028, 1)), - (0x1d67d, (4904, 1)), - (0x322c, (1343, 3)), - (0xfbdb, (2599, 1)), - (0xfd12, (3248, 2)), + (0x210c, (385, 1)), + (0xfcd6, (3123, 2)), + (0x2164, (491, 1)), (0xff83, (4139, 1)), + (0x24b4, (781, 3)), (0x2f94, (1005, 1)), - (0x2483, (638, 4)), - (0x1d799, (5186, 1)), - (0x2140, (429, 1)), - (0xfdc4, (3678, 3)), + (0x32ed, (1650, 1)), + (0x3232, (1361, 3)), + (0x2f59, (946, 1)), + (0xff33, (4059, 1)), (0x3262, (1454, 1)), - (0xfda9, (3597, 3)), - (0x1d6f0, (5017, 1)), + (0x330e, (1725, 4)), + (0x2489, (660, 2)), (0x2fb5, (1038, 1)), (0xfeea, (3976, 1)), - (0x313d, (1096, 1)), - (0x32f5, (1658, 1)), + (0x2fc8, (1057, 1)), + (0x215e, (478, 3)), (0xff05, (4013, 1)), - (0x1d616, (4801, 1)), - (0x1ee1d, (5315, 1)), - (0x3159, (1124, 1)), - (0x1d457, (4377, 1)), - (0xfe78, (3842, 2)), - (0x2f31, (906, 1)), + (0x2f8a, (995, 1)), + (0x1ee1d, (5377, 1)), + (0xfebb, (3929, 1)), + (0x1d67f, (4906, 1)), + (0xfe93, (3889, 1)), + (0xfecf, (3949, 1)), (0xfbfb, (2666, 3)), - (0x2085, (340, 1)), + (0x1d6d6, (4991, 1)), (0x2152, (441, 4)), - (0x1d7f2, (5273, 1)), - (0x1ee4f, (5344, 1)), - (0xfc37, (2788, 2)), - (0x1d459, (4379, 1)), + (0x1db7, (225, 1)), + (0x1f14a, (5625, 2)), + (0xfbdc, (2600, 1)), + (0x1d694, (4927, 1)), (0x2158, (460, 3)), (0x1d63d, (4840, 1)), - (0xfee2, (3968, 1)), - (0xfed5, (3955, 1)), + (0x2101, (368, 3)), + (0x2137, (419, 1)), (0xfdc0, (3666, 3)), - (0x1f238, (5630, 1)), - (0xff9c, (4164, 1)), - (0x1d40, (154, 1)), + (0x1d7a3, (5196, 1)), + (0x1d54, (173, 1)), + (0x10797, (4256, 1)), (0x3268, (1460, 1)), (0x10795, (4254, 1)), (0x33b9, (2260, 2)), + (0xfc02, (2679, 3)), (0x332f, (1861, 4)), - (0x1f251, (5662, 1)), - (0xff6e, (4118, 1)), - (0x1d606, (4785, 1)), - (0x32e6, (1643, 1)), - (0xfc4c, (2830, 2)), - (0x1d432, (4341, 1)), - (0xfcf1, (3179, 2)), - (0x1f13d, (5550, 1)), - (0x32c5, (1594, 2)), + (0x213d, (426, 1)), + (0x3283, (1508, 1)), + (0x2f15, (878, 1)), + (0x1d453, (4374, 1)), + (0x107b0, (4281, 1)), + (0x2f33, (908, 1)), + (0xfe7f, (3856, 2)), + (0x1d7eb, (5266, 1)), + (0x32ca, (1605, 3)), (0xedc, (124, 2)), - (0x1fbf8, (5671, 1)), - (0x2474, (587, 3)), + (0xffed, (4233, 1)), (0x1d7ca, (5235, 1)), - (0xfd0c, (3236, 2)), - (0xfbef, (2630, 3)), + (0x3265, (1457, 1)), + (0x3389, (2138, 4)), (0xfcaf, (3045, 2)), (0xfd69, (3411, 3)), - (0x2b7, (69, 1)), - (0x1d57d, (4648, 1)), - (0x24db, (824, 1)), - (0x1d5b7, (4706, 1)), - (0x33b3, (2248, 2)), - (0xfb98, (2561, 1)), - (0x1d47a, (4412, 1)), + (0x32a4, (1541, 1)), + (0x2f75, (974, 1)), + (0x2c7c, (852, 1)), + (0x2fae, (1031, 1)), + (0xff2c, (4052, 1)), + (0xfdf1, (3693, 3)), + (0x1d613, (4798, 1)), + (0xfc73, (2920, 2)), (0x1d495, (4439, 1)), - (0xfb7d, (2534, 1)), - (0x2b1, (63, 1)), + (0x1d4ea, (4513, 1)), (0xa7f3, (2442, 1)), (0x1d7e5, (5260, 1)), - (0xfeb4, (3922, 1)), - (0xfb7f, (2536, 1)), - (0x2f88, (993, 1)), - (0x24c9, (806, 1)), - (0x1f246, (5652, 3)), - (0xfc10, (2710, 2)), - (0x1f16b, (5578, 2)), - (0x2074, (323, 1)), - (0x3209, (1219, 3)), - (0x338a, (2142, 2)), + (0xfe85, (3867, 2)), + (0x1d4f2, (4521, 1)), + (0x1d65e, (4873, 1)), + (0x1d7c6, (5231, 1)), + (0x2103, (372, 2)), + (0x2083, (338, 1)), + (0xfc33, (2780, 2)), + (0x333d, (1918, 5)), + (0xfcef, (3175, 2)), + (0xfeb8, (3926, 1)), + (0x32fd, (1666, 1)), (0x1d74b, (5108, 1)), - (0x1f21d, (5603, 1)), - (0x1eeb1, (5417, 1)), - (0x2157, (457, 3)), - (0x1ee10, (5302, 1)), - (0x1f106, (5440, 2)), + (0x247c, (611, 3)), + (0x1079d, (4262, 1)), + (0x1e052, (5321, 1)), + (0x1ee10, (5364, 1)), + (0x2f7d, (982, 1)), (0xfda4, (3582, 3)), - (0x2f91, (1002, 1)), - (0x24a1, (724, 3)), + (0x323a, (1385, 3)), + (0x3157, (1122, 1)), (0x33c0, (2274, 2)), (0x1f3, (60, 2)), - (0xff54, (4092, 1)), + (0xfc51, (2840, 2)), (0xfe15, (3762, 1)), (0x3204, (1204, 3)), (0x3397, (2172, 2)), - (0xff02, (4010, 1)), - (0x32e8, (1645, 1)), - (0x2094, (354, 1)), - (0x1d652, (4861, 1)), - (0x1d442, (4357, 1)), - (0x1f135, (5542, 1)), + (0x1d4e2, (4505, 1)), + (0x32ce, (1616, 2)), + (0xfb69, (2514, 1)), + (0x1d6fc, (5029, 1)), + (0x32a5, (1542, 1)), + (0xfe9a, (3896, 1)), (0x1dbe, (232, 1)), - (0x1db7, (225, 1)), - (0x1d475, (4407, 1)), - (0xfdf0, (3690, 3)), - (0x2133, (415, 1)), - (0x2e4, (87, 1)), - (0x2f0e, (871, 1)), + (0x2090, (350, 1)), + (0xfbd9, (2597, 1)), + (0x1d778, (5153, 1)), + (0x1d6d7, (4992, 1)), + (0x1d7bf, (5224, 1)), + (0xfda8, (3594, 3)), (0x3391, (2156, 3)), (0xfc5b, (2860, 2)), - (0x1d41f, (4322, 1)), - (0x1d758, (5121, 1)), - (0x2f53, (940, 1)), - (0x1f222, (5608, 1)), - (0x1d671, (4892, 1)), - (0xff07, (4015, 1)), - (0xff19, (4033, 1)), - (0x1d538, (4586, 1)), + (0x2467, (563, 1)), + (0x1d7f0, (5271, 1)), + (0x3186, (1169, 1)), + (0x2f10, (873, 1)), + (0x1d5e3, (4750, 1)), + (0xfce5, (3155, 2)), + (0x1d75a, (5123, 1)), + (0xa7f9, (2445, 1)), (0x1d580, (4651, 1)), - (0x1f247, (5655, 3)), - (0x1fbf3, (5666, 1)), - (0x1f23b, (5633, 1)), - (0x2496, (691, 3)), - (0x1d4d3, (4490, 1)), - (0x1d44e, (4369, 1)), + (0x1d49b, (4445, 1)), + (0x2151, (438, 3)), + (0x1f23b, (5695, 1)), + (0xfcad, (3041, 2)), + (0x32b7, (1566, 2)), + (0x1d5cf, (4730, 1)), + (0x1d790, (5177, 1)), (0x1d6cd, (4982, 1)), - (0x335b, (2024, 2)), + (0xffcc, (4207, 1)), (0x3307, (1698, 6)), (0x1d7df, (5254, 1)), - (0x1f147, (5560, 1)), - (0x1d692, (4925, 1)), - (0x3146, (1105, 1)), + (0x2f07, (864, 1)), + (0x24d5, (818, 1)), (0x1d5a0, (4683, 1)), + (0xfb85, (2542, 1)), (0x1d520, (4562, 1)), - (0xfc1b, (2732, 2)), - (0x1ee47, (5339, 1)), - (0xfc42, (2810, 2)), - (0x2fa4, (1021, 1)), - (0x2f06, (863, 1)), - (0xfe4e, (3802, 1)), - (0x3250, (1419, 3)), - (0x3342, (1937, 3)), - (0x1d532, (4580, 1)), - (0x1ee71, (5365, 1)), + (0x1d4d1, (4488, 1)), + (0x2461, (557, 1)), + (0x1d452, (4373, 1)), + (0xfb70, (2521, 1)), + (0x1d69f, (4938, 1)), + (0x1d594, (4671, 1)), + (0x3271, (1472, 2)), + (0x1e057, (5326, 1)), + (0x1d40, (154, 1)), + (0x1ee27, (5383, 1)), (0xfd34, (3316, 2)), - (0xfba5, (2575, 2)), - (0xffb1, (4185, 1)), + (0x209b, (361, 1)), + (0x1d578, (4643, 1)), (0xff56, (4094, 1)), - (0x315c, (1127, 1)), + (0x2121, (403, 3)), (0x3148, (1107, 1)), - (0x1f233, (5625, 1)), - (0xff1d, (4037, 1)), - (0x3167, (1138, 1)), - (0x2130, (413, 1)), - (0x2f67, (960, 1)), - (0x1d59d, (4680, 1)), - (0x1d71a, (5059, 1)), - (0x1d68f, (4922, 1)), - (0x1d681, (4908, 1)), - (0x1d46e, (4400, 1)), - (0x1d74e, (5111, 1)), + (0x2f3d, (918, 1)), + (0x1d724, (5069, 1)), + (0x2166, (494, 3)), + (0x2f1b, (884, 1)), + (0x1d5ea, (4757, 1)), + (0xfc05, (2688, 2)), + (0x336a, (2062, 3)), + (0x24a3, (730, 3)), + (0x3320, (1804, 5)), + (0x1ee82, (5440, 1)), + (0x3344, (1944, 3)), (0x210b, (384, 1)), - (0x1d6a, (195, 1)), - (0x1ee30, (5329, 1)), - (0xfcb4, (3055, 2)), - (0x1ee1a, (5312, 1)), - (0xff2c, (4052, 1)), - (0x2e2, (85, 1)), + (0x1d560, (4619, 1)), + (0x1ee30, (5391, 1)), + (0x24e5, (834, 1)), + (0xffea, (4230, 1)), + (0x1f236, (5690, 1)), + (0x2037, (303, 3)), + (0x1e05a, (5329, 1)), (0x2000, (275, 1)), - (0x1d7b0, (5209, 1)), - (0xfc81, (2948, 2)), - (0xfca0, (3015, 2)), - (0x1d63e, (4841, 1)), - (0xfb5b, (2500, 1)), - (0xfbae, (2585, 1)), - (0x1d60c, (4791, 1)), - (0x2f33, (908, 1)), - (0xfd3c, (3332, 2)), - (0xfef8, (3996, 3)), - (0x332c, (1846, 4)), - (0xfd32, (3312, 2)), - (0xfcbe, (3075, 2)), + (0x1d7e6, (5261, 1)), + (0xff6d, (4117, 1)), + (0x3036, (1072, 1)), + (0x1d6f4, (5021, 1)), + (0x1ee18, (5372, 1)), + (0x1ee00, (5349, 1)), + (0xffb4, (4188, 1)), + (0x1d6a8, (4945, 1)), + (0x3362, (2038, 3)), + (0xfec2, (3936, 1)), + (0x2f26, (895, 1)), + (0x33fe, (2432, 3)), (0x2034, (298, 3)), - (0x1ee6e, (5362, 1)), - (0x2139, (421, 1)), + (0x1cc, (54, 2)), + (0x33e1, (2353, 2)), + (0xfcc0, (3079, 2)), (0x33de, (2345, 3)), - (0x1d34, (143, 1)), - (0x1d5f4, (4767, 1)), - (0x1d429, (4332, 1)), - (0xfba3, (2572, 1)), - (0xfc0b, (2700, 2)), + (0x1d5ba, (4709, 1)), + (0x1d47d, (4415, 1)), + (0xff76, (4126, 1)), + (0xfce2, (3149, 2)), + (0x217a, (534, 2)), (0xfc29, (2760, 2)), (0x1d6e6, (5007, 1)), - (0xff33, (4059, 1)), - (0xffbc, (4196, 1)), - (0xfcac, (3039, 2)), - (0x3344, (1944, 3)), - (0x2087, (342, 1)), - (0x1d73f, (5096, 1)), + (0x1f139, (5608, 1)), + (0xff2f, (4055, 1)), + (0x1d7a2, (5195, 1)), + (0x3000, (1071, 1)), + (0x1d6b2, (4955, 1)), (0x107a9, (4274, 1)), - (0x316a, (1141, 1)), - (0xfd9a, (3552, 3)), + (0xfecb, (3945, 1)), + (0x2f09, (866, 1)), + (0xfe16, (3763, 1)), (0x2100, (365, 3)), - (0x3332, (1871, 6)), - (0xfd89, (3507, 3)), + (0x3369, (2059, 3)), + (0x3322, (1814, 3)), (0xfca8, (3031, 2)), - (0x33e4, (2359, 2)), - (0x2fc7, (1056, 1)), - (0x321c, (1290, 4)), - (0x107b8, (4288, 1)), - (0x3194, (1180, 1)), + (0x2e0, (83, 1)), + (0x1d6c3, (4972, 1)), + (0x2147, (432, 1)), + (0x1d57a, (4645, 1)), + (0x1d6ff, (5032, 1)), (0x1d5d7, (4738, 1)), - (0x3198, (1184, 1)), - (0xfed3, (3953, 1)), - (0xfdb7, (3639, 3)), - (0xfc49, (2824, 2)), - (0x3351, (1992, 4)), - (0x333a, (1905, 4)), + (0xff0f, (4023, 1)), + (0x3259, (1438, 2)), + (0x1d45, (159, 1)), + (0xfef5, (3987, 3)), + (0x1ee94, (5457, 1)), + (0x1d76c, (5141, 1)), (0x316f, (1146, 1)), - (0xff73, (4123, 1)), + (0x2f11, (874, 1)), (0xff1f, (4039, 1)), (0x3212, (1250, 4)), (0x32c0, (1584, 2)), - (0x1d46c, (4398, 1)), - (0x1d4fa, (4529, 1)), + (0xffb8, (4192, 1)), + (0xfc0b, (2700, 2)), (0xfc04, (2685, 3)), - (0x1d640, (4843, 1)), - (0x1f215, (5595, 1)), - (0x2484, (642, 4)), - (0x3f5, (108, 1)), + (0x1d651, (4860, 1)), + (0x1f215, (5657, 1)), + (0x3325, (1824, 3)), + (0x1d753, (5116, 1)), (0x2fbf, (1048, 1)), + (0x1d73e, (5095, 1)), (0xff06, (4014, 1)), - (0xfcc7, (3093, 2)), - (0xff42, (4074, 1)), - (0xfe5c, (3815, 1)), + (0xfb67, (2512, 1)), + (0x3242, (1409, 3)), + (0x1d6c1, (4970, 1)), (0xfe14, (3761, 1)), - (0x1dae, (216, 1)), - (0x1d409, (4300, 1)), + (0x1d743, (5100, 1)), + (0xfeca, (3944, 1)), (0xfe43, (3789, 1)), - (0xfc77, (2928, 2)), (0x1d7d1, (5240, 1)), - (0xfc19, (2728, 2)), - (0xfb86, (2543, 1)), - (0x1d4da, (4497, 1)), - (0x3378, (2099, 3)), - (0x1d661, (4876, 1)), - (0x3252, (1424, 2)), - (0x2f49, (930, 1)), - (0x331a, (1780, 6)), + (0x1d563, (4622, 1)), + (0x1f21f, (5667, 1)), + (0xfc0d, (2704, 2)), + (0x2f7c, (981, 1)), + (0xff82, (4138, 1)), + (0x3250, (1419, 3)), + (0x1d6df, (5000, 1)), + (0x1d7c1, (5226, 1)), (0xfcfb, (3202, 2)), (0xfd51, (3339, 3)), - (0x1ee87, (5383, 1)), - (0x3399, (2176, 2)), - (0xfdc5, (3681, 3)), + (0x3159, (1124, 1)), + (0x1d422, (4325, 1)), + (0xfb04, (2460, 3)), + (0x313a, (1093, 1)), (0x1d638, (4835, 1)), - (0x1d7a8, (5201, 1)), - (0x1d739, (5090, 1)), - (0x32de, (1635, 1)), - (0xfdf7, (3716, 4)), - (0x1f136, (5543, 1)), + (0x33cb, (2301, 2)), + (0x107a0, (4265, 1)), + (0x1d492, (4436, 1)), + (0x2460, (556, 1)), + (0x1d510, (4548, 1)), (0x3374, (2090, 3)), - (0x1d53e, (4591, 1)), + (0x1e032, (5289, 1)), (0xfb29, (2486, 1)), - (0x1ee01, (5288, 1)), - (0x1fbf5, (5668, 1)), - (0x1d76a, (5139, 1)), - (0x32d9, (1630, 1)), - (0xfd2a, (3296, 2)), - (0x1d4a9, (4452, 1)), - (0x24b3, (778, 3)), - (0x2151, (438, 3)), - (0xff95, (4157, 1)), - (0x24aa, (751, 3)), - (0x32a7, (1544, 1)), - (0x1d57e, (4649, 1)), - (0x32bc, (1576, 2)), - (0x2482, (634, 4)), - (0x2176, (524, 3)), + (0x1ee01, (5350, 1)), + (0x1d623, (4814, 1)), + (0x331d, (1793, 3)), + (0xffe8, (4228, 1)), + (0x1d531, (4579, 1)), + (0x1ee2a, (5385, 1)), + (0x2fb9, (1042, 1)), + (0x24e9, (838, 1)), + (0xfcf0, (3177, 2)), + (0x1d4e7, (4510, 1)), + (0x2fd3, (1068, 1)), + (0xfd62, (3390, 3)), + (0x1d7de, (5253, 1)), + (0x1ee1e, (5378, 1)), + (0xfdb2, (3624, 3)), (0x2fb4, (1037, 1)), (0xffc2, (4199, 1)), - (0xfb5e, (2503, 1)), - (0x1d60d, (4792, 1)), - (0x2476, (593, 3)), + (0x322c, (1343, 3)), + (0xfe8c, (3881, 2)), + (0x1d6ef, (5016, 1)), + (0x329f, (1536, 1)), (0x10796, (4255, 1)), - (0x1d55d, (4616, 1)), - (0x1d5c, (181, 1)), - (0x107b3, (4283, 1)), - (0x1d527, (4569, 1)), - (0x1d768, (5137, 1)), - (0xffa5, (4173, 1)), - (0x2f45, (926, 1)), - (0xfd81, (3483, 3)), + (0x1d38, (147, 1)), + (0x331e, (1796, 4)), + (0x1d65c, (4871, 1)), + (0xfb76, (2527, 1)), + (0x1f11d, (5551, 3)), + (0xfc95, (2988, 2)), + (0x1f12c, (5594, 1)), (0x1d588, (4659, 1)), - (0xfe33, (3773, 1)), - (0x1d6c7, (4976, 1)), - (0x2f2e, (903, 1)), - (0x338c, (2146, 2)), + (0x33ee, (2384, 3)), + (0x24a9, (748, 3)), + (0x3209, (1219, 3)), + (0x3202, (1198, 3)), (0x1d72a, (5075, 1)), - (0x3221, (1310, 3)), - (0xff11, (4025, 1)), + (0x2230, (553, 3)), + (0x1ee21, (5380, 1)), (0x3177, (1154, 1)), - (0xfd5b, (3369, 3)), - (0xff88, (4144, 1)), - (0xff08, (4016, 1)), - (0x2fa6, (1023, 1)), - (0xff27, (4047, 1)), - (0x1d4ae, (4456, 1)), - (0xfd71, (3435, 3)), + (0x335e, (2030, 2)), + (0xfeed, (3979, 1)), + (0x3312, (1741, 4)), + (0x3392, (2159, 3)), + (0x1d41e, (4321, 1)), + (0x1d5a8, (4691, 1)), + (0xff6b, (4115, 1)), (0xfef1, (3983, 1)), - (0x1d4b5, (4463, 1)), - (0x2090, (350, 1)), - (0x2467, (563, 1)), - (0x1f145, (5558, 1)), - (0x1f232, (5624, 1)), + (0x329b, (1532, 1)), + (0xfb9d, (2566, 1)), + (0x1d69a, (4933, 1)), + (0x32c3, (1590, 2)), + (0x32b2, (1556, 2)), + (0xfc8f, (2976, 2)), (0x216c, (509, 1)), - (0x222f, (551, 2)), - (0xfe62, (3821, 1)), - (0x1d4e0, (4503, 1)), + (0x1ee99, (5462, 1)), + (0xfdbe, (3660, 3)), + (0x2fb7, (1040, 1)), (0x1d760, (5129, 1)), (0x33c4, (2284, 2)), - (0xff3a, (4066, 1)), - (0x1d590, (4667, 1)), - (0x1ee1f, (5317, 1)), - (0x3375, (2093, 2)), - (0x323e, (1397, 3)), + (0xfc8a, (2966, 2)), + (0x1d7f9, (5280, 1)), + (0x1d53c, (4589, 1)), + (0x32cb, (1608, 3)), (0xfd29, (3294, 2)), - (0x1d5a9, (4692, 1)), - (0x3219, (1278, 4)), - (0xfc6b, (2904, 2)), + (0x1f128, (5584, 3)), + (0x1da0, (202, 1)), + (0xfe9f, (3901, 1)), + (0x2171, (514, 2)), (0x1d56b, (4630, 1)), - (0x24d4, (817, 1)), - (0x1d6b1, (4954, 1)), + (0x1d64e, (4857, 1)), + (0x1d432, (4341, 1)), (0x3315, (1753, 6)), (0xfb64, (2509, 1)), - (0xfd98, (3546, 3)), - (0xfd2e, (3304, 2)), + (0x3284, (1509, 1)), + (0x3357, (2015, 3)), (0xfc35, (2784, 2)), - (0x1d72f, (5080, 1)), + (0x2f92, (1003, 1)), (0x216f, (512, 1)), (0x33ab, (2222, 3)), - (0xfef0, (3982, 1)), - (0x2078, (327, 1)), + (0x1d434, (4343, 1)), + (0x1d4c1, (4473, 1)), (0xfdbd, (3657, 3)), - (0x3288, (1513, 1)), - (0x32ca, (1605, 3)), + (0x1d6bd, (4966, 1)), + (0x1ee34, (5394, 1)), (0x1d6cc, (4981, 1)), - (0xfbdc, (2600, 1)), - (0x1fbf2, (5665, 1)), - (0x2004, (279, 1)), - (0x1da9, (211, 1)), - (0x1d5fa, (4773, 1)), - (0xfc86, (2958, 2)), - (0xff92, (4154, 1)), - (0x1d48c, (4430, 1)), - (0x326f, (1468, 2)), - (0xfc5c, (2862, 2)), + (0x1f135, (5604, 1)), + (0xfc9f, (3013, 2)), + (0x1d556, (4609, 1)), + (0x33c7, (2292, 3)), + (0xfb00, (2451, 2)), + (0x1d765, (5134, 1)), + (0x1d748, (5105, 1)), + (0x2084, (339, 1)), + (0x1d44a, (4365, 1)), + (0x1d62, (187, 1)), (0x318c, (1175, 1)), - (0xfd38, (3324, 2)), - (0x1d47, (161, 1)), - (0x1d609, (4788, 1)), - (0xfba1, (2570, 1)), - (0x1eeb9, (5425, 1)), - (0x1d4fc, (4531, 1)), - (0x3349, (1962, 2)), + (0x2049, (314, 2)), + (0x32e4, (1641, 1)), + (0x1d552, (4605, 1)), + (0x1d546, (4597, 1)), + (0x1d624, (4815, 1)), + (0x1eeb9, (5487, 1)), + (0x1d4da, (4497, 1)), (0x1ca, (50, 2)), - (0x2f68, (961, 1)), - (0x331c, (1790, 3)), - (0xfd77, (3453, 3)), - (0x1d2e, (138, 1)), - (0x2f20, (889, 1)), - (0x1ee3b, (5337, 1)), + (0x3240, (1403, 3)), + (0xfba8, (2579, 1)), + (0xffdc, (4219, 1)), + (0x3225, (1322, 3)), + (0x1d799, (5186, 1)), + (0x1d622, (4813, 1)), + (0xfb28, (2485, 1)), (0x303a, (1075, 1)), - (0x1ee6d, (5361, 1)), - (0xfb8f, (2552, 1)), - (0x332d, (1850, 5)), - (0x1d682, (4909, 1)), - (0xfd76, (3450, 3)), - (0x333d, (1918, 5)), - (0x1f217, (5597, 1)), + (0xffb2, (4186, 1)), + (0x1d592, (4669, 1)), + (0x207b, (330, 1)), + (0x1f12a, (5590, 3)), + (0xfd1f, (3274, 2)), + (0x1f217, (5659, 1)), (0x1d575, (4640, 1)), - (0xfe77, (3840, 2)), + (0xfcf1, (3179, 2)), + (0xfd6e, (3426, 3)), (0x24dd, (826, 1)), - (0x339c, (2182, 2)), - (0x320a, (1222, 3)), - (0x1f119, (5477, 3)), - (0xfc57, (2852, 2)), - (0x1f21f, (5605, 1)), - (0x1d794, (5181, 1)), - (0xfdb3, (3627, 3)), - (0x107a0, (4265, 1)), - (0x222d, (548, 3)), - (0x2f8f, (1000, 1)), - (0x1d553, (4606, 1)), + (0x1d605, (4784, 1)), + (0x1ee2f, (5390, 1)), + (0xfd27, (3290, 2)), + (0x1d52e, (4576, 1)), + (0x1d428, (4331, 1)), + (0x1ee36, (5396, 1)), + (0x32eb, (1648, 1)), + (0x1d678, (4899, 1)), + (0xfb14, (2469, 2)), + (0xff10, (4024, 1)), + (0x1d60e, (4793, 1)), (0xfbad, (2584, 1)), - (0x212f, (412, 1)), - (0xfca6, (3027, 2)), - (0x33c6, (2288, 4)), - (0xfcd8, (3127, 2)), - (0x1d40f, (4306, 1)), - (0x1d423, (4326, 1)), - (0x2f40, (921, 1)), - (0x1d4f0, (4519, 1)), - (0x2f75, (974, 1)), + (0x1d570, (4635, 1)), + (0x2f38, (913, 1)), + (0x2f4a, (931, 1)), + (0xff3a, (4066, 1)), + (0x1d741, (5098, 1)), + (0x1d788, (5169, 1)), + (0x320d, (1231, 3)), + (0x1d64b, (4854, 1)), + (0x2b1, (63, 1)), (0x33a6, (2207, 3)), - (0x1d425, (4328, 1)), - (0x1d76d, (5142, 1)), - (0x1da4, (206, 1)), - (0x1ee57, (5348, 1)), - (0xfea0, (3902, 1)), - (0x1d49a, (4444, 1)), - (0xfea1, (3903, 1)), + (0x1d774, (5149, 1)), + (0xfd2c, (3300, 2)), + (0x2109, (381, 2)), + (0x1f100, (5490, 2)), + (0xfc03, (2682, 3)), + (0x1d61, (186, 1)), + (0x1d7f2, (5273, 1)), (0xfbab, (2582, 1)), - (0x3300, (1670, 5)), - (0x3145, (1104, 1)), - (0x1d6c0, (4969, 1)), - (0x1d539, (4587, 1)), + (0xffa7, (4175, 1)), + (0x1d664, (4879, 1)), + (0xfcdd, (3137, 2)), + (0x1d4be, (4470, 1)), (0x33da, (2337, 2)), - (0x2075, (324, 1)), - (0x1d51e, (4560, 1)), - (0x10782, (4236, 1)), + (0x1d67, (192, 1)), + (0x2f60, (953, 1)), + (0x24a0, (721, 3)), (0xfb56, (2495, 1)), (0x24bd, (794, 1)), + (0xfbdf, (2604, 1)), (0xffb7, (4191, 1)), - (0x1ee16, (5308, 1)), - (0x1d6e2, (5003, 1)), - (0xfdc7, (3687, 3)), - (0x2fbc, (1045, 1)), - (0xfc66, (2890, 3)), - (0xfc6e, (2910, 2)), - (0x1fcd, (247, 3)), + (0x1d77d, (5158, 1)), + (0x3296, (1527, 1)), + (0x1d5b7, (4706, 1)), + (0x1f23a, (5694, 1)), + (0x316e, (1145, 1)), + (0x336d, (2071, 3)), + (0xff7e, (4134, 1)), (0x1d534, (4582, 1)), (0x32a6, (1543, 1)), - (0xfd84, (3492, 3)), - (0x1ee7c, (5374, 1)), - (0xfd6f, (3429, 3)), - (0xfeef, (3981, 1)), - (0xfd80, (3480, 3)), + (0x1ee7c, (5436, 1)), + (0x1ee2d, (5388, 1)), + (0xfd5b, (3369, 3)), + (0x331a, (1780, 6)), + (0x32f4, (1657, 1)), (0x32bb, (1574, 2)), - (0x3270, (1470, 2)), - (0x333f, (1927, 2)), + (0x3343, (1940, 4)), + (0x2fd4, (1069, 1)), (0xfcd2, (3115, 2)), - (0x334c, (1973, 5)), - (0x1d5bd, (4712, 1)), - (0x1d7ec, (5267, 1)), - (0x1d656, (4865, 1)), - (0x2464, (560, 1)), + (0x2189, (543, 3)), + (0x107ae, (4279, 1)), + (0xffd3, (4212, 1)), + (0x2f2d, (902, 1)), + (0xfd56, (3354, 3)), (0x2105, (374, 3)), - (0x1d2d, (137, 1)), - (0x1d66f, (4890, 1)), - (0x329a, (1531, 1)), - (0x1ee42, (5338, 1)), - (0x208b, (346, 1)), + (0xfbff, (2672, 1)), + (0xfbea, (2615, 3)), + (0x1d71d, (5062, 1)), + (0x1ee42, (5400, 1)), + (0xfdfc, (3753, 4)), (0x33d8, (2330, 4)), - (0xfe19, (3766, 3)), - (0x3358, (2018, 2)), + (0x675, (112, 2)), + (0x1cb, (52, 2)), (0xfd6b, (3417, 3)), - (0x1d711, (5050, 1)), - (0x1ee80, (5376, 1)), + (0x332a, (1837, 3)), + (0x1d7a7, (5200, 1)), (0xfb51, (2490, 1)), (0x33fd, (2429, 3)), - (0x1d729, (5074, 1)), - (0x107a2, (4267, 1)), - (0x1d66, (191, 1)), - (0x1d497, (4441, 1)), - (0x2498, (697, 3)), + (0x1ee57, (5410, 1)), + (0xa0, (0, 1)), + (0x2f2b, (900, 1)), + (0x1d404, (4295, 1)), + (0x2081, (336, 1)), (0xf79, (132, 3)), - (0x314f, (1114, 1)), - (0x1d79b, (5188, 1)), + (0xfeec, (3978, 1)), + (0xfc2f, (2772, 2)), (0x1d52, (171, 1)), - (0x1d5d, (182, 1)), - (0x246d, (573, 2)), - (0x1d53d, (4590, 1)), + (0xff41, (4073, 1)), + (0x1d5ad, (4696, 1)), + (0x2133, (415, 1)), (0x1d7ab, (5204, 1)), - (0xfd94, (3534, 3)), - (0xff75, (4125, 1)), - (0x3350, (1989, 3)), - (0x1f137, (5544, 1)), + (0x1d463, (4389, 1)), + (0xfe71, (3832, 2)), + (0xfbaf, (2586, 1)), + (0x1d736, (5087, 1)), (0x1d5e, (183, 1)), (0x2e3, (86, 1)), - (0x1f244, (5646, 3)), - (0xfb79, (2530, 1)), - (0x2135, (417, 1)), + (0xfea4, (3906, 1)), + (0x1e035, (5292, 1)), + (0x3354, (2002, 5)), (0x211a, (397, 1)), - (0x1ee5f, (5352, 1)), - (0xfe9b, (3897, 1)), - (0x2fb9, (1042, 1)), - (0x2f3b, (916, 1)), - (0x1d54b, (4599, 1)), - (0x1d5bb, (4710, 1)), - (0xfd9f, (3567, 3)), - (0xfe17, (3764, 1)), - (0x1ee82, (5378, 1)), - (0xfb6e, (2519, 1)), - (0x248b, (664, 2)), - (0x1f115, (5465, 3)), - (0x335a, (2022, 2)), + (0xfe8b, (3879, 2)), + (0x1ee5f, (5414, 1)), + (0x1d74f, (5112, 1)), + (0x1d78, (196, 1)), + (0x1f13f, (5614, 1)), + (0xffc7, (4204, 1)), + (0x314b, (1110, 1)), + (0x1d5a6, (4689, 1)), + (0xfd0a, (3232, 2)), + (0x2476, (593, 3)), + (0x1e037, (5294, 1)), + (0x1d63, (188, 1)), + (0xfb62, (2507, 1)), + (0xfdf6, (3712, 4)), (0xfd7a, (3462, 3)), (0xffa2, (4170, 1)), - (0x1d529, (4571, 1)), - (0x3303, (1684, 3)), - (0x1d7ad, (5206, 1)), - (0x2f8c, (997, 1)), - (0x10797, (4256, 1)), - (0x2f52, (939, 1)), - (0x3245, (1416, 1)), - (0x336e, (2074, 3)), - (0x1d696, (4929, 1)), + (0x1c4, (35, 3)), + (0x1d4f4, (4523, 1)), + (0x3388, (2135, 3)), + (0x1d5a2, (4685, 1)), + (0x2f90, (1001, 1)), + (0x3281, (1506, 1)), + (0x1d4b2, (4460, 1)), + (0x1d61a, (4805, 1)), + (0xfcc8, (3095, 2)), (0x1d61e, (4809, 1)), - (0xfe7a, (3846, 2)), - (0xff85, (4141, 1)), + (0xfcb3, (3053, 2)), + (0xfd86, (3498, 3)), (0x2096, (356, 1)), (0x1d714, (5053, 1)), (0xfed7, (3957, 1)), - (0x1ee9b, (5402, 1)), - (0x1d793, (5180, 1)), - (0x1d494, (4438, 1)), + (0xff8c, (4148, 1)), + (0x2f77, (976, 1)), + (0x107b4, (4284, 1)), (0x2089, (344, 1)), - (0xfbd8, (2596, 1)), - (0x1d6d2, (4987, 1)), + (0x3207, (1213, 3)), + (0xfd15, (3254, 2)), (0x1d6b7, (4960, 1)), - (0x1d6ed, (5014, 1)), - (0x1d660, (4875, 1)), + (0x1f134, (5603, 1)), + (0xfe59, (3812, 1)), (0x1d6d4, (4989, 1)), - (0x2f6b, (964, 1)), - (0x2f9d, (1014, 1)), + (0x1d708, (5041, 1)), + (0x1d7f6, (5277, 1)), + (0x1d74e, (5111, 1)), (0x1d7db, (5250, 1)), - (0x1ee74, (5367, 1)), - (0x32ab, (1548, 1)), - (0x2f50, (937, 1)), + (0xfcbe, (3075, 2)), + (0x2f86, (991, 1)), (0x2f35, (910, 1)), - (0xfb9c, (2565, 1)), - (0x1ee06, (5292, 1)), + (0xfb81, (2538, 1)), + (0x1d569, (4628, 1)), (0x3189, (1172, 1)), - (0xfdc2, (3672, 3)), + (0xfc71, (2916, 2)), (0x1d45b, (4381, 1)), - (0x2b3, (65, 1)), - (0x1d700, (5033, 1)), - (0x149, (32, 2)), - (0x3228, (1331, 3)), - (0xfc6f, (2912, 2)), - (0x2009, (284, 1)), - (0x1e9b, (236, 2)), + (0xff4b, (4083, 1)), + (0xfbdb, (2599, 1)), + (0x3243, (1412, 3)), + (0x2b5, (67, 1)), + (0x1d564, (4623, 1)), + (0x3170, (1147, 1)), + (0xfbdd, (2601, 2)), (0x2fce, (1063, 1)), - (0x1d706, (5039, 1)), - (0x1d6d0, (4985, 1)), + (0x215a, (466, 3)), + (0x2175, (522, 2)), + (0xfd7f, (3477, 3)), (0x3380, (2119, 2)), - (0x2150, (435, 3)), - (0x1d7ae, (5207, 1)), - (0xfc02, (2679, 3)), - (0x24ba, (791, 1)), - (0xfc62, (2878, 3)), + (0xff4c, (4084, 1)), + (0x1d6cb, (4980, 1)), + (0xfee2, (3968, 1)), + (0xffc5, (4202, 1)), (0x32ae, (1551, 1)), - (0x33c8, (2295, 2)), + (0xfe69, (3827, 1)), (0x3235, (1370, 3)), - (0x338f, (2152, 2)), + (0x24bc, (793, 1)), + (0x2fbb, (1044, 1)), (0xffa3, (4171, 1)), - (0x3036, (1072, 1)), - (0x1f12b, (5531, 1)), - (0xfdc3, (3675, 3)), - (0x1dad, (215, 1)), - (0xfced, (3171, 2)), - (0x33d1, (2313, 2)), - (0xfd88, (3504, 3)), - (0x1d507, (4541, 1)), - (0x1f146, (5559, 1)), - (0x1eeb3, (5419, 1)), - (0xfb5a, (2499, 1)), - (0x1d404, (4295, 1)), + (0x3316, (1759, 6)), + (0x1f12b, (5593, 1)), + (0xfc11, (2712, 2)), + (0x2f44, (925, 1)), + (0xfbd3, (2591, 1)), + (0x1d63b, (4838, 1)), + (0xfd0f, (3242, 2)), + (0x1f146, (5621, 1)), + (0x328e, (1519, 1)), + (0x309c, (1078, 2)), + (0x1da6, (208, 1)), + (0x32bd, (1578, 2)), (0xfba2, (2571, 1)), - (0x1d4d6, (4493, 1)), - (0x24c7, (804, 1)), - (0x2f8e, (999, 1)), - (0x2f07, (864, 1)), - (0x1d435, (4344, 1)), + (0x1d527, (4569, 1)), + (0xfcc5, (3089, 2)), + (0x332d, (1850, 5)), + (0xfe5a, (3813, 1)), + (0x1d60c, (4791, 1)), (0x2481, (630, 4)), - (0x1ee69, (5358, 1)), - (0x318d, (1176, 1)), - (0xfc76, (2926, 2)), - (0x1d4ea, (4513, 1)), - (0x1d63a, (4837, 1)), - (0x1d6e1, (5002, 1)), - (0x1f117, (5471, 3)), - (0x33bb, (2264, 2)), - (0xff36, (4062, 1)), - (0xfcb2, (3051, 2)), - (0x1d614, (4799, 1)), - (0xfec7, (3941, 1)), - (0x1d59b, (4678, 1)), - (0xfebe, (3932, 1)), - (0x1d4f9, (4528, 1)), - (0x1d605, (4784, 1)), + (0xfe4e, (3802, 1)), + (0xff45, (4077, 1)), + (0x32ef, (1652, 1)), + (0x1d2d, (137, 1)), + (0x3135, (1088, 1)), + (0x3342, (1937, 3)), + (0x1f117, (5533, 3)), + (0x1d72b, (5076, 1)), + (0x1d41, (155, 1)), + (0xff5d, (4101, 1)), + (0xfd03, (3218, 2)), + (0xfecc, (3946, 1)), + (0x1d52f, (4577, 1)), + (0xfc23, (2748, 2)), + (0x1d522, (4564, 1)), + (0x32f8, (1661, 1)), (0x3143, (1102, 1)), + (0x1d450, (4371, 1)), (0x2db, (77, 2)), - (0x1ee00, (5287, 1)), - (0x2137, (419, 1)), - (0x1d77f, (5160, 1)), + (0xfccb, (3101, 2)), + (0x24b1, (772, 3)), (0x1d7ee, (5269, 1)), - (0x2166, (494, 3)), - (0xfbd9, (2597, 1)), + (0x1d52d, (4575, 1)), + (0x1d792, (5179, 1)), (0x2fa9, (1026, 1)), (0x3206, (1210, 3)), - (0xfbe2, (2607, 1)), + (0x2f22, (891, 1)), + (0x2f14, (877, 1)), (0x309b, (1076, 2)), - (0x1f200, (5584, 2)), - (0x1eea9, (5410, 1)), - (0x2037, (303, 3)), - (0x1d559, (4612, 1)), - (0x1d64d, (4856, 1)), - (0x2495, (688, 3)), - (0xfbac, (2583, 1)), - (0x2f25, (894, 1)), - (0x3179, (1156, 1)), - (0xfeb0, (3918, 1)), - (0x1d496, (4440, 1)), + (0x1eea9, (5472, 1)), + (0xfd74, (3444, 3)), + (0x1d6a, (195, 1)), + (0x1e05e, (5333, 1)), + (0x1d5d6, (4737, 1)), + (0x1d504, (4539, 1)), + (0xfc9e, (3011, 2)), + (0x2153, (445, 3)), + (0x1d421, (4324, 1)), + (0x1eea5, (5468, 1)), + (0x2f67, (960, 1)), (0x3d4, (100, 2)), (0xfc82, (2950, 2)), - (0x1ee98, (5399, 1)), - (0x3173, (1150, 1)), - (0xfc16, (2722, 2)), + (0x1ee98, (5461, 1)), + (0x2f1f, (888, 1)), + (0x1d7d3, (5242, 1)), (0x3313, (1745, 6)), - (0x1d4c7, (4478, 1)), - (0xfbd6, (2594, 1)), - (0x1ee67, (5356, 1)), - (0xff53, (4091, 1)), + (0x325e, (1448, 2)), + (0x2f74, (973, 1)), + (0x336c, (2068, 3)), + (0x2484, (642, 4)), (0xfe66, (3825, 1)), - (0x1d513, (4551, 1)), - (0xab5c, (2446, 1)), - (0xfbf4, (2645, 3)), + (0x1078b, (4244, 1)), + (0xfef6, (3990, 3)), + (0xfd85, (3495, 3)), (0x1d48b, (4429, 1)), - (0x24d8, (821, 1)), - (0x1d666, (4881, 1)), + (0x2487, (654, 4)), + (0x1d64f, (4858, 1)), (0xfe7d, (3852, 2)), - (0x1d43a, (4349, 1)), - (0x1ee8e, (5389, 1)), - (0x24d3, (816, 1)), + (0xfd7c, (3468, 3)), + (0xfcc1, (3081, 2)), + (0x1d4a2, (4449, 1)), (0x203e, (308, 2)), - (0x2480, (626, 4)), - (0x1d704, (5037, 1)), - (0x1d762, (5131, 1)), - (0xff0f, (4023, 1)), - (0xfce0, (3144, 3)), - (0x1d42, (156, 1)), - (0xfccd, (3105, 2)), - (0x2a0c, (840, 4)), - (0x2189, (543, 3)), - (0x3166, (1137, 1)), + (0x1d598, (4675, 1)), + (0x323c, (1391, 3)), + (0x247a, (605, 3)), + (0xfd12, (3248, 2)), + (0x1d429, (4332, 1)), + (0x1ee13, (5367, 1)), + (0xfc8d, (2972, 2)), + (0x2f29, (898, 1)), + (0x1d6a1, (4940, 1)), + (0x1f110, (5512, 3)), (0x1d2c, (136, 1)), (0x1d7b8, (5217, 1)), - (0x1d42d, (4336, 1)), - (0x24c2, (799, 1)), - (0x1d79d, (5190, 1)), - (0x2164, (491, 1)), + (0x32ec, (1649, 1)), + (0x3145, (1104, 1)), + (0xfdbf, (3663, 3)), + (0x1d54d, (4601, 1)), (0x3181, (1164, 1)), - (0xfd83, (3489, 3)), - (0xb3, (7, 1)), - (0xfc05, (2688, 2)), - (0xfd2c, (3300, 2)), - (0x1d6f6, (5023, 1)), - (0x1d444, (4359, 1)), - (0x33a7, (2210, 3)), + (0xfc67, (2893, 3)), + (0xff34, (4060, 1)), + (0x1d6e3, (5004, 1)), + (0xfd70, (3432, 3)), + (0x1d608, (4787, 1)), + (0x1d711, (5050, 1)), + (0xff9d, (4165, 1)), (0x1d51f, (4561, 1)), - (0x332e, (1855, 6)), - (0x1d5b3, (4702, 1)), - (0x1d488, (4426, 1)), - (0x3393, (2162, 3)), + (0x1d773, (5148, 1)), + (0xfd95, (3537, 3)), + (0xff5f, (4103, 1)), + (0x2174, (521, 1)), (0xfec4, (3938, 1)), - (0x2f6c, (965, 1)), + (0x1d523, (4565, 1)), (0x207c, (331, 1)), - (0x1d65c, (4871, 1)), + (0x2faa, (1027, 1)), + (0x1d69e, (4937, 1)), (0x2f55, (942, 1)), - (0xfe9c, (3898, 1)), - (0xff48, (4080, 1)), - (0x1fce, (250, 3)), + (0x1d582, (4653, 1)), + (0x1d601, (4780, 1)), + (0x1d7aa, (5203, 1)), (0x215f, (481, 2)), - (0x1fbf, (240, 2)), + (0xff4a, (4082, 1)), (0x1d477, (4409, 1)), - (0x1d418, (4315, 1)), (0x1d525, (4567, 1)), - (0x2f6e, (967, 1)), + (0xfda2, (3576, 3)), (0xff94, (4156, 1)), - (0x1d744, (5101, 1)), + (0xff8e, (4150, 1)), + (0x1d43b, (4350, 1)), (0x1d709, (5042, 1)), - (0x1ee62, (5354, 1)), - (0x2468, (564, 1)), - (0x1ee77, (5370, 1)), - (0x1eeac, (5412, 1)), - (0x2f44, (925, 1)), + (0x1d56d, (4632, 1)), + (0x33ea, (2372, 3)), + (0x1ee77, (5432, 1)), + (0x1eeac, (5474, 1)), + (0x334d, (1978, 4)), (0x1d6a5, (4944, 1)), (0x33c2, (2278, 4)), - (0x2f02, (859, 1)), - (0x1d56f, (4634, 1)), - (0x24c4, (801, 1)), + (0x1d661, (4876, 1)), + (0xfd01, (3214, 2)), + (0x1d5d2, (4733, 1)), (0x2008, (283, 1)), (0xfd8f, (3525, 3)), (0x3227, (1328, 3)), (0x1d447, (4362, 1)), - (0xfc56, (2850, 2)), - (0xfd93, (3531, 3)), + (0x249d, (712, 3)), + (0x1f14b, (5627, 2)), (0x1d5fc, (4775, 1)), (0x1d50a, (4544, 1)), - (0xfe81, (3859, 2)), + (0xfb86, (2543, 1)), (0x1d719, (5058, 1)), - (0x2f3a, (915, 1)), - (0x3319, (1774, 6)), - (0x1d584, (4655, 1)), + (0x330f, (1729, 4)), + (0xfd6a, (3414, 3)), + (0xfc9d, (3009, 2)), (0xfc3e, (2802, 2)), - (0x323a, (1385, 3)), - (0x2f38, (913, 1)), + (0x1e064, (5339, 1)), + (0x3d1, (96, 1)), (0xffaf, (4183, 1)), + (0x1d433, (4342, 1)), (0xfbfe, (2671, 1)), - (0x1d59f, (4682, 1)), - (0x1d646, (4849, 1)), - (0x24cc, (809, 1)), - (0xfd64, (3396, 3)), - (0xfd3b, (3330, 2)), + (0x1d4dc, (4499, 1)), + (0xfbf0, (2633, 3)), + (0x33dd, (2343, 2)), + (0xfcf5, (3190, 2)), (0xfce6, (3157, 2)), (0x1d554, (4607, 1)), - (0x1d791, (5178, 1)), - (0x2f1d, (886, 1)), - (0x1d5c0, (4715, 1)), - (0xfc60, (2872, 3)), - (0x1d60f, (4794, 1)), - (0xff29, (4049, 1)), - (0xff82, (4138, 1)), - (0x1d7e4, (5259, 1)), - (0x1d6ee, (5015, 1)), - (0x327c, (1494, 5)), - (0x3142, (1101, 1)), - (0x2f7c, (981, 1)), - (0x2120, (401, 2)), - (0x32b5, (1562, 2)), - (0x1d72c, (5077, 1)), - (0x2f32, (907, 1)), - (0xff25, (4045, 1)), - (0x1ee85, (5381, 1)), - (0xff84, (4140, 1)), - (0x24e5, (834, 1)), - (0x1f114, (5462, 3)), - (0xfbf6, (2651, 3)), + (0x1fdf, (262, 3)), + (0x2082, (337, 1)), + (0xfeaf, (3917, 1)), + (0x1d43d, (4352, 1)), + (0x1c9, (48, 2)), + (0x1e060, (5335, 1)), + (0xff29, (4049, 1)), + (0x33b6, (2254, 2)), + (0xfb57, (2496, 1)), + (0xfeb2, (3920, 1)), + (0x1d703, (5036, 1)), + (0x1d5e9, (4756, 1)), + (0x24e1, (830, 1)), + (0x10794, (4253, 1)), + (0x328f, (1520, 1)), + (0x1e049, (5312, 1)), + (0x1d58c, (4663, 1)), + (0x335d, (2028, 2)), + (0x3039, (1074, 1)), + (0x1d46d, (4399, 1)), + (0x2f49, (930, 1)), + (0x1f222, (5670, 1)), (0x32fe, (1667, 1)), - (0xfe4c, (3799, 2)), - (0x1f102, (5432, 2)), - (0xfda0, (3570, 3)), - (0x33f0, (2390, 3)), - (0x318a, (1173, 1)), - (0x2b2, (64, 1)), - (0xfb90, (2553, 1)), - (0x24d0, (813, 1)), - (0x208a, (345, 1)), - (0x1f132, (5539, 1)), + (0x1d79c, (5189, 1)), + (0x3179, (1156, 1)), + (0x1d697, (4930, 1)), + (0x1c8, (46, 2)), + (0x2138, (420, 1)), + (0x1d6ac, (4949, 1)), + (0xfc20, (2742, 2)), + (0x327e, (1503, 2)), + (0xfd24, (3284, 2)), + (0x32df, (1636, 1)), (0xfc53, (2844, 2)), + (0xfeb9, (3927, 1)), (0x1d76e, (5143, 1)), - (0x1d657, (4866, 1)), - (0x1d61f, (4810, 1)), - (0x1f107, (5442, 2)), - (0x2102, (371, 1)), - (0xff2f, (4055, 1)), + (0x3378, (2099, 3)), + (0xff9f, (4167, 1)), + (0x1ee19, (5373, 1)), + (0x1f119, (5539, 3)), + (0x1d480, (4418, 1)), (0xfc1d, (2736, 2)), - (0x1d65b, (4870, 1)), - (0x3286, (1511, 1)), - (0x1f13a, (5547, 1)), + (0x30ff, (1082, 2)), + (0xfb63, (2508, 1)), + (0x1f13a, (5609, 1)), (0x333c, (1914, 4)), - (0xfc55, (2848, 2)), - (0xfd26, (3288, 2)), - (0x217a, (534, 2)), + (0xfc87, (2960, 2)), + (0x1d45c, (4382, 1)), + (0xfea9, (3911, 1)), (0x1d41a, (4317, 1)), - (0xfb70, (2521, 1)), + (0x1eebb, (5489, 1)), (0x1d54e, (4602, 1)), - (0x678, (118, 2)), - (0x2465, (561, 1)), - (0x1fcf, (253, 3)), - (0x32e3, (1640, 1)), - (0x1d5f6, (4769, 1)), - (0x1d785, (5166, 1)), + (0xffc4, (4201, 1)), + (0x1d423, (4326, 1)), + (0xfcdc, (3135, 2)), + (0x1d58f, (4666, 1)), + (0x1d456, (4376, 1)), + (0xfd8c, (3516, 3)), (0x1d5c2, (4717, 1)), - (0x1d56e, (4633, 1)), - (0x1d68, (193, 1)), - (0x2b5, (67, 1)), - (0xfea4, (3906, 1)), - (0x3229, (1334, 3)), - (0x2093, (353, 1)), + (0xfdbb, (3651, 3)), + (0x1d67c, (4903, 1)), + (0x1d4ab, (4454, 1)), + (0x1d557, (4610, 1)), + (0xfce4, (3153, 2)), + (0x322f, (1352, 3)), + (0x33bc, (2266, 2)), (0xfe7e, (3854, 2)), (0x1d44f, (4370, 1)), - (0xfe74, (3836, 2)), - (0xfb25, (2482, 1)), - (0x315d, (1128, 1)), - (0x2fa1, (1018, 1)), - (0xfb7e, (2535, 1)), - (0xfce7, (3159, 2)), - (0x1d42f, (4338, 1)), - (0x2f77, (976, 1)), - (0x3363, (2041, 3)), - (0x1eeb7, (5423, 1)), - (0x2f86, (991, 1)), - (0xfd60, (3384, 3)), - (0x211b, (398, 1)), + (0x1d74a, (5107, 1)), + (0x3167, (1138, 1)), + (0xfb9e, (2567, 1)), + (0xff6e, (4118, 1)), + (0xff90, (4152, 1)), + (0x1d700, (5033, 1)), + (0x1d431, (4340, 1)), + (0x1d459, (4379, 1)), + (0x213b, (422, 3)), + (0x1d779, (5154, 1)), + (0xfc46, (2818, 2)), + (0x334b, (1970, 3)), + (0xfc41, (2808, 2)), (0x3279, (1488, 2)), - (0xfb7a, (2531, 1)), (0x3294, (1525, 1)), + (0x1d4eb, (4514, 1)), (0x1d71f, (5064, 1)), - (0x2049, (314, 2)), + (0x2f28, (897, 1)), (0xfbe8, (2613, 1)), - (0x1ee39, (5336, 1)), - (0x1d6d5, (4990, 1)), - (0x1f131, (5538, 1)), - (0x24a0, (721, 3)), - (0x2f59, (946, 1)), - (0x3301, (1675, 4)), - (0x1d717, (5056, 1)), - (0x2dc, (79, 2)), - (0x1d5f3, (4766, 1)), - (0x1d3a, (149, 1)), + (0x24a2, (727, 3)), + (0x1d759, (5122, 1)), + (0xfcba, (3067, 2)), + (0x1d2e, (138, 1)), + (0xfb97, (2560, 1)), + (0x248c, (666, 2)), + (0x1da5, (207, 1)), + (0x33d3, (2318, 2)), + (0xfdf4, (3704, 4)), + (0x107a3, (4268, 1)), (0x2f8d, (998, 1)), - (0x3171, (1148, 1)), - (0xfc32, (2778, 2)), - (0xfcf5, (3190, 2)), + (0x1fbf7, (5732, 1)), + (0x1ee7e, (5437, 1)), + (0xff31, (4057, 1)), (0xfd04, (3220, 2)), - (0x2f79, (978, 1)), + (0x323e, (1397, 3)), (0x246c, (571, 2)), - (0x1d64b, (4854, 1)), - (0x1d589, (4660, 1)), + (0x1d7e9, (5264, 1)), + (0xfd76, (3450, 3)), (0x3328, (1832, 2)), - (0x1d679, (4900, 1)), + (0x1d602, (4781, 1)), (0xfe60, (3819, 1)), + (0x1d58, (177, 1)), (0xfd8e, (3522, 3)), - (0x2f6d, (966, 1)), - (0xfcb3, (3053, 2)), - (0x33f3, (2399, 3)), - (0x1ee86, (5382, 1)), - (0x1d7eb, (5266, 1)), - (0x1ee08, (5294, 1)), + (0x320b, (1225, 3)), + (0x2fa4, (1021, 1)), + (0xfcd8, (3127, 2)), + (0xfcd3, (3117, 2)), + (0x1d446, (4361, 1)), (0x3310, (1733, 4)), - (0x1d530, (4578, 1)), - (0x2179, (533, 1)), - (0x1d613, (4798, 1)), - (0xfd54, (3348, 3)), + (0x1d66a, (4885, 1)), + (0x33ce, (2307, 2)), + (0xf77, (129, 3)), + (0x1d7b7, (5216, 1)), (0xfb8a, (2547, 1)), - (0x326d, (1465, 1)), - (0xfbd4, (2592, 1)), - (0xfec5, (3939, 1)), - (0x1dbb, (229, 1)), - (0xfc95, (2988, 2)), - (0xfba6, (2577, 1)), - (0x2070, (321, 1)), - (0x33c3, (2282, 2)), - (0x2131, (414, 1)), - (0xfc09, (2696, 2)), - (0x1ee8b, (5386, 1)), - (0xfbaa, (2581, 1)), - (0xffb9, (4193, 1)), - (0x2109, (381, 2)), + (0x2f2f, (904, 1)), + (0x3372, (2086, 2)), + (0x2479, (602, 3)), + (0x24c8, (805, 1)), + (0x1d485, (4423, 1)), + (0x1d476, (4408, 1)), + (0x33c1, (2276, 2)), + (0x2f7a, (979, 1)), + (0x1d6f9, (5026, 1)), + (0x1d42b, (4334, 1)), + (0x1d475, (4407, 1)), + (0xfe51, (3805, 1)), + (0x1dbf, (233, 1)), + (0x3180, (1163, 1)), (0x1d427, (4330, 1)), - (0xfe96, (3892, 1)), - (0x3273, (1476, 2)), + (0x2f08, (865, 1)), + (0x1e03a, (5297, 1)), (0x3381, (2121, 2)), - (0x1d4e4, (4507, 1)), + (0xff5e, (4102, 1)), (0x1d75f, (5128, 1)), - (0xfb16, (2473, 2)), - (0x3246, (1417, 1)), + (0x1f2, (58, 2)), + (0x1d539, (4587, 1)), + (0x1d4f9, (4528, 1)), (0x2f43, (924, 1)), - (0x2fa7, (1024, 1)), - (0x2f9e, (1015, 1)), - (0xfc84, (2954, 2)), - (0x2076, (325, 1)), - (0x1d745, (5102, 1)), - (0xff62, (4106, 1)), - (0x24a6, (739, 3)), - (0x1d6bd, (4966, 1)), - (0xfd31, (3310, 2)), + (0xfd1d, (3270, 2)), + (0xfc1f, (2740, 2)), + (0x247d, (614, 4)), + (0xff3e, (4070, 1)), + (0x1d776, (5151, 1)), + (0x1d9f, (201, 1)), + (0x1ee16, (5370, 1)), + (0x3256, (1432, 2)), (0xff7a, (4130, 1)), - (0x1d5e4, (4751, 1)), - (0x249b, (706, 3)), - (0x3386, (2131, 2)), - (0x1f12c, (5532, 1)), + (0x1d629, (4820, 1)), + (0x1ee54, (5409, 1)), + (0xff59, (4097, 1)), + (0x1d6cf, (4984, 1)), + (0x1d6f6, (5023, 1)), (0x33b5, (2252, 2)), - (0x24d9, (822, 1)), + (0x1d7b9, (5218, 1)), (0xffd2, (4211, 1)), - (0x1d9b, (197, 1)), - (0x1d509, (4543, 1)), - (0x32b0, (1553, 1)), + (0x3358, (2018, 2)), + (0x2f2a, (899, 1)), + (0x2e1, (84, 1)), (0xfc68, (2896, 3)), - (0x1f128, (5522, 3)), - (0x1d7c1, (5226, 1)), + (0x3329, (1834, 3)), + (0xfce1, (3147, 2)), + (0x1d732, (5083, 1)), (0xfb54, (2493, 1)), - (0x1f235, (5627, 1)), - (0xff55, (4093, 1)), - (0xfbea, (2615, 3)), - (0x2da, (75, 2)), - (0x330d, (1721, 4)), - (0x32ed, (1650, 1)), + (0x1d4e4, (4507, 1)), + (0x222d, (548, 3)), + (0xfdb1, (3621, 3)), + (0x1d794, (5181, 1)), + (0xfe88, (3873, 2)), (0x1d7c8, (5233, 1)), - (0x32b4, (1560, 2)), - (0xfb88, (2545, 1)), - (0x1d72d, (5078, 1)), - (0x1d669, (4884, 1)), - (0x3149, (1108, 1)), - (0x1d5b0, (4699, 1)), - (0x33e2, (2355, 2)), - (0x1f140, (5553, 1)), - (0xff8c, (4148, 1)), - (0x1d55a, (4613, 1)), + (0xff43, (4075, 1)), + (0x1d420, (4323, 1)), + (0xfc3d, (2800, 2)), + (0xfd18, (3260, 2)), + (0xfe87, (3871, 2)), + (0x2fd0, (1065, 1)), + (0xfbf9, (2660, 3)), + (0x323b, (1388, 3)), + (0x1d685, (4912, 1)), + (0x2087, (342, 1)), (0x1d75d, (5126, 1)), - (0x107a8, (4273, 1)), - (0x2f81, (986, 1)), + (0x1d47, (161, 1)), + (0xfc42, (2810, 2)), + (0x2f3f, (920, 1)), (0xfe82, (3861, 2)), - (0xfef9, (3999, 3)), - (0x33f6, (2408, 3)), - (0x1d44b, (4366, 1)), + (0x1d6c5, (4974, 1)), + (0x1ee88, (5446, 1)), + (0x32e9, (1646, 1)), (0x1d44d, (4368, 1)), - (0x327b, (1492, 2)), - (0x1078d, (4246, 1)), - (0xfbe4, (2609, 1)), + (0xfc52, (2842, 2)), + (0x321c, (1290, 4)), + (0x1fee, (268, 3)), (0x1d448, (4363, 1)), - (0x335e, (2030, 2)), - (0x1d6f1, (5018, 1)), - (0x1f214, (5594, 1)), - (0x1d45d, (4383, 1)), - (0x1d733, (5084, 1)), - (0xfc33, (2780, 2)), - (0x1f11e, (5492, 3)), - (0x1d632, (4829, 1)), - (0xfee4, (3970, 1)), + (0x3349, (1962, 2)), + (0x1d5e2, (4749, 1)), + (0x1f214, (5656, 1)), + (0x3239, (1382, 3)), + (0x2005, (280, 1)), + (0x1f11e, (5554, 3)), + (0x1f238, (5692, 1)), + (0x2f3b, (916, 1)), + (0xfdaf, (3615, 3)), (0x1d6da, (4995, 1)), - (0xfc8a, (2966, 2)), - (0x1d746, (5103, 1)), - (0x1f212, (5591, 1)), + (0xffec, (4232, 1)), + (0x1d62c, (4823, 1)), + (0x3226, (1325, 3)), (0xff93, (4155, 1)), - (0x1d7d2, (5241, 1)), - (0x3388, (2135, 3)), + (0x3314, (1751, 2)), + (0x2079, (328, 1)), (0xff8f, (4151, 1)), - (0xfc1f, (2740, 2)), + (0x3173, (1150, 1)), (0x1d583, (4654, 1)), - (0x1d688, (4915, 1)), + (0x1fbf9, (5734, 1)), (0xb4, (8, 2)), - (0xfc4d, (2832, 2)), - (0x1d7fc, (5283, 1)), - (0x37a, (88, 2)), - (0xfe7f, (3856, 2)), - (0x1f240, (5634, 3)), + (0xfdc2, (3672, 3)), + (0x1d32, (141, 1)), + (0x1d418, (4315, 1)), + (0xff7f, (4135, 1)), + (0x1f133, (5602, 1)), (0x32a0, (1537, 1)), - (0x1d7c0, (5225, 1)), - (0xfd16, (3256, 2)), + (0xfd63, (3393, 3)), + (0x1d771, (5146, 1)), (0x33ad, (2228, 3)), - (0x1d618, (4803, 1)), - (0x1ee99, (5400, 1)), - (0x1d792, (5179, 1)), - (0x1d7a4, (5197, 1)), + (0x2b7, (69, 1)), + (0x1f211, (5652, 1)), + (0x1f16b, (5640, 2)), + (0xfb77, (2528, 1)), (0xfefa, (4002, 3)), - (0x32fd, (1666, 1)), + (0x1d461, (4387, 1)), (0x32ea, (1647, 1)), (0x1d555, (4608, 1)), (0x1dab, (213, 1)), - (0x2167, (497, 4)), - (0x1d639, (4836, 1)), + (0xfebc, (3930, 1)), + (0x1d6b1, (4954, 1)), (0x317e, (1161, 1)), + (0x1d5b1, (4700, 1)), (0xfe95, (3891, 1)), - (0x1d438, (4347, 1)), - (0x3195, (1181, 1)), - (0xfcc0, (3079, 2)), + (0x331f, (1800, 4)), + (0x1d70c, (5045, 1)), (0x1d662, (4877, 1)), - (0x2f4e, (935, 1)), - (0x32a9, (1546, 1)), + (0x1d70e, (5047, 1)), + (0x1d417, (4314, 1)), + (0xfc10, (2710, 2)), (0xfc1a, (2730, 2)), (0x1d755, (5118, 1)), (0x3134, (1087, 1)), - (0x1d6fb, (5028, 1)), - (0xfc69, (2899, 3)), - (0x1d712, (5051, 1)), - (0x1d780, (5161, 1)), - (0xfe8a, (3877, 2)), - (0x2c7c, (852, 1)), - (0x1d70f, (5048, 1)), - (0xff49, (4081, 1)), - (0x33d2, (2315, 3)), + (0x3308, (1704, 4)), + (0x1d541, (4593, 1)), + (0x10787, (4240, 1)), + (0xfeac, (3914, 1)), + (0x1f229, (5677, 1)), + (0x1e046, (5309, 1)), + (0x24c3, (800, 1)), + (0x2026, (292, 3)), + (0x149, (32, 2)), (0x33e7, (2365, 2)), (0x211c, (399, 1)), - (0x3377, (2097, 2)), - (0x1d37, (146, 1)), - (0x1d57f, (4650, 1)), - (0x1d76b, (5140, 1)), - (0xff09, (4017, 1)), - (0x3392, (2159, 3)), - (0x3152, (1117, 1)), + (0x2f58, (945, 1)), + (0x1d5ff, (4778, 1)), + (0xfe9b, (3897, 1)), + (0xfd2f, (3306, 2)), + (0x1d710, (5049, 1)), + (0x1d65, (190, 1)), + (0xfc1e, (2738, 2)), (0xfd9d, (3561, 3)), (0x2077, (326, 1)), (0x24cb, (808, 1)), - (0x1eeba, (5426, 1)), - (0x3160, (1131, 1)), - (0x677, (116, 2)), - (0x1d56a, (4629, 1)), + (0x1eeba, (5488, 1)), + (0xff0e, (4022, 1)), + (0xfb7e, (2535, 1)), + (0x3337, (1895, 3)), (0x248d, (668, 2)), - (0xfd27, (3290, 2)), + (0xfd99, (3549, 3)), (0xfd65, (3399, 3)), - (0x1d566, (4625, 1)), - (0x32da, (1631, 1)), - (0xfcce, (3107, 2)), - (0xff30, (4056, 1)), - (0x1ee7a, (5372, 1)), - (0xfe3d, (3783, 1)), - (0x1d644, (4847, 1)), - (0xfb5c, (2501, 1)), + (0x1d7ac, (5205, 1)), + (0x1f11c, (5548, 3)), + (0x32ff, (1668, 2)), + (0x1ee7a, (5434, 1)), + (0x1e06b, (5346, 1)), + (0xfe47, (3791, 1)), + (0x1d637, (4834, 1)), + (0x3264, (1456, 1)), (0xfc58, (2854, 2)), - (0xfdfc, (3753, 4)), - (0xfee0, (3966, 1)), - (0x1d5d4, (4735, 1)), - (0x322a, (1337, 3)), - (0x2f8a, (995, 1)), - (0x1d64a, (4853, 1)), - (0x32a2, (1539, 1)), - (0x1ee76, (5369, 1)), - (0xfd2b, (3298, 2)), - (0x1f11a, (5480, 3)), + (0x1d603, (4782, 1)), + (0x1d478, (4410, 1)), + (0xff0a, (4018, 1)), + (0xfda3, (3579, 3)), + (0x1d44, (158, 1)), + (0x24d0, (813, 1)), + (0xab5e, (2448, 1)), + (0xfcfc, (3204, 2)), + (0xffe0, (4220, 1)), + (0x1ee0a, (5358, 1)), + (0x313d, (1096, 1)), (0x3398, (2174, 2)), - (0x2489, (660, 2)), - (0x1d64, (189, 1)), - (0x2f18, (881, 1)), + (0xfcd0, (3111, 2)), + (0x2f6e, (967, 1)), (0x202f, (295, 1)), - (0x1d73d, (5094, 1)), - (0xfc36, (2786, 2)), + (0xfcaa, (3035, 2)), + (0x1d43a, (4349, 1)), (0xfd23, (3282, 2)), - (0x1d449, (4364, 1)), + (0x2ef3, (856, 1)), (0xfe5f, (3818, 1)), - (0xfbe7, (2612, 1)), - (0x33aa, (2219, 3)), - (0x107ab, (4276, 1)), - (0x316d, (1144, 1)), + (0x2f93, (1004, 1)), + (0x2086, (341, 1)), + (0xfd6d, (3423, 3)), + (0x249f, (718, 3)), (0x1d424, (4327, 1)), - (0x1d677, (4898, 1)), + (0x1fbf8, (5733, 1)), (0x1d462, (4388, 1)), - (0x2079, (328, 1)), - (0x1d7e7, (5262, 1)), - (0x1d39, (148, 1)), + (0xfe4d, (3801, 1)), + (0x1d53b, (4588, 1)), + (0xfe49, (3793, 2)), + (0x1d6ab, (4948, 1)), (0x3132, (1085, 1)), - (0x3302, (1679, 5)), - (0xfcd9, (3129, 2)), - (0x3192, (1178, 1)), - (0x337b, (2107, 2)), - (0x3327, (1830, 2)), - (0xff0c, (4020, 1)), - (0x1eea2, (5404, 1)), - (0x1f227, (5613, 1)), - (0xfcfe, (3208, 2)), + (0x1d7c2, (5227, 1)), + (0xfd9c, (3558, 3)), + (0x2fc2, (1051, 1)), + (0x33f4, (2402, 3)), + (0x213c, (425, 1)), + (0x1d7e8, (5263, 1)), + (0xff88, (4144, 1)), + (0x1d79d, (5190, 1)), (0x24c1, (798, 1)), - (0x1eeb8, (5424, 1)), - (0x10799, (4258, 1)), + (0x24e0, (829, 1)), + (0x1eeb8, (5486, 1)), + (0xfc70, (2914, 2)), (0xfc6c, (2906, 2)), (0x2fac, (1029, 1)), - (0x1f202, (5588, 1)), + (0x1f202, (5650, 1)), (0xfbf3, (2642, 3)), - (0x1d430, (4339, 1)), + (0x2f78, (977, 1)), (0x3255, (1430, 2)), - (0x329f, (1536, 1)), - (0x1c9, (48, 2)), - (0xfef3, (3985, 1)), + (0x2f2e, (903, 1)), + (0xfb24, (2481, 1)), + (0x32af, (1552, 1)), (0x1d4a, (164, 1)), - (0x1d9d, (199, 1)), - (0xfc3b, (2796, 2)), - (0x2477, (596, 3)), + (0x2f25, (894, 1)), + (0x1ee6e, (5424, 1)), + (0xfd2d, (3302, 2)), (0xff6a, (4114, 1)), - (0xfcdf, (3141, 3)), - (0x1d59e, (4681, 1)), - (0x10fc, (135, 1)), - (0xfea9, (3911, 1)), + (0x2466, (562, 1)), + (0x1d579, (4644, 1)), + (0x1f231, (5685, 1)), + (0xfc61, (2875, 3)), (0x1d7fd, (5284, 1)), (0xfd5f, (3381, 3)), - (0xfdae, (3612, 3)), - (0x32e9, (1646, 1)), - (0x1d63c, (4839, 1)), - (0x3365, (2047, 3)), - (0xfcb7, (3061, 2)), - (0x1d611, (4796, 1)), - (0xfc6a, (2902, 2)), - (0x17f, (34, 1)), - (0x3260, (1452, 1)), + (0x1ee1a, (5374, 1)), + (0x3348, (1958, 4)), + (0xfba9, (2580, 1)), + (0x1d45f, (4385, 1)), + (0x1d66d, (4888, 1)), + (0xfce8, (3161, 2)), + (0xfb5b, (2500, 1)), + (0x1ee62, (5416, 1)), + (0x3146, (1105, 1)), (0x33ac, (2225, 3)), - (0x1f149, (5562, 1)), + (0x1f149, (5624, 1)), + (0x3295, (1526, 1)), (0x3333, (1877, 4)), - (0x1d60, (185, 1)), - (0x2b6, (68, 1)), - (0x1ee29, (5322, 1)), + (0xfc0f, (2708, 2)), + (0xff8a, (4146, 1)), (0x3387, (2133, 2)), - (0xfd00, (3212, 2)), - (0x32ba, (1572, 2)), - (0x1d742, (5099, 1)), - (0x32c7, (1598, 2)), - (0x216b, (506, 3)), - (0xfc83, (2952, 2)), - (0x24e7, (836, 1)), - (0x3241, (1406, 3)), + (0x676, (114, 2)), + (0xffcd, (4208, 1)), + (0xfe86, (3869, 2)), + (0x1d6e8, (5009, 1)), + (0xfc40, (2806, 2)), + (0xfc0a, (2698, 2)), + (0x10788, (4241, 1)), + (0x2fc0, (1049, 1)), + (0x1d5b6, (4705, 1)), (0xffa8, (4176, 1)), - (0x3188, (1171, 1)), - (0x1d69a, (4933, 1)), - (0x1d62d, (4824, 1)), - (0x3210, (1242, 4)), - (0xff46, (4078, 1)), - (0x1d7b7, (5216, 1)), + (0x3289, (1514, 1)), + (0xfd79, (3459, 3)), + (0x3300, (1670, 5)), + (0x1d55, (174, 1)), + (0x24b5, (784, 3)), + (0x2f4c, (933, 1)), (0x3163, (1134, 1)), - (0x33dd, (2343, 2)), - (0x207b, (330, 1)), + (0x2002, (277, 1)), + (0x2f57, (944, 1)), (0xfcdb, (3133, 2)), (0x1d49f, (4448, 1)), - (0xfbe9, (2614, 1)), - (0x3144, (1103, 1)), - (0x33c7, (2292, 3)), - (0x1d77a, (5155, 1)), - (0x1d58d, (4664, 1)), - (0x1d4d1, (4488, 1)), - (0xffb6, (4190, 1)), - (0x1d58f, (4666, 1)), - (0x1ee93, (5394, 1)), - (0xffb8, (4192, 1)), + (0x1d688, (4915, 1)), + (0xff18, (4032, 1)), + (0x2f54, (941, 1)), + (0x1ee85, (5443, 1)), + (0x2fd1, (1066, 1)), + (0x33c5, (2286, 2)), + (0xfb53, (2492, 1)), + (0x3197, (1183, 1)), + (0x2fcf, (1064, 1)), + (0x1d516, (4553, 1)), (0x3201, (1195, 3)), (0xfd82, (3486, 3)), - (0x1d503, (4538, 1)), - (0x1d7d6, (5245, 1)), - (0x210d, (386, 1)), - (0xff3f, (4071, 1)), - (0x1d556, (4609, 1)), - (0x1d70e, (5047, 1)), - (0x2f09, (866, 1)), - (0xfbe5, (2610, 1)), - (0xfcbc, (3071, 2)), - (0x1d5b8, (4707, 1)), - (0xfc7b, (2936, 2)), - (0x3242, (1409, 3)), - (0x1d40b, (4302, 1)), + (0xff16, (4030, 1)), + (0x2150, (435, 3)), + (0x1f109, (5508, 2)), + (0xfe9d, (3899, 1)), + (0x210f, (388, 1)), + (0x320e, (1234, 4)), + (0x1e040, (5303, 1)), + (0x330a, (1711, 3)), + (0x1ee0e, (5362, 1)), + (0xfc45, (2816, 2)), + (0xff48, (4080, 1)), + (0xfc47, (2820, 2)), + (0x1d505, (4540, 1)), (0x2169, (503, 1)), - (0x1d787, (5168, 1)), + (0x24dc, (825, 1)), (0x1d7d8, (5247, 1)), - (0x3293, (1524, 1)), + (0xfb55, (2494, 1)), (0xfe84, (3865, 2)), - (0x1f14b, (5565, 2)), - (0x1d602, (4781, 1)), - (0x2fc9, (1058, 1)), - (0x107b0, (4281, 1)), + (0x1ee22, (5381, 1)), + (0x1d772, (5147, 1)), + (0x33f0, (2390, 3)), + (0x1d4b1, (4459, 1)), (0xff99, (4161, 1)), + (0xfd2e, (3304, 2)), (0x2159, (463, 3)), - (0xfe76, (3838, 2)), - (0x1d741, (5098, 1)), + (0x1d58d, (4664, 1)), (0x1d627, (4818, 1)), (0xfeeb, (3977, 1)), - (0x1ee81, (5377, 1)), - (0x2128, (409, 1)), - (0x217e, (541, 1)), - (0xfeab, (3913, 1)), - (0x1f16c, (5580, 2)), + (0x3334, (1881, 6)), + (0x1f126, (5578, 3)), + (0x3144, (1103, 1)), + (0x1e036, (5293, 1)), + (0x1db9, (227, 1)), (0x1d6ea, (5011, 1)), + (0x1d6ee, (5015, 1)), (0xfec6, (3940, 1)), - (0x1d51a, (4557, 1)), - (0x107a3, (4268, 1)), + (0x1d64c, (4855, 1)), + (0xfcbb, (3069, 2)), (0x2033, (296, 2)), - (0xfe8c, (3881, 2)), - (0x1d5a3, (4686, 1)), - (0x3321, (1809, 5)), - (0xfc22, (2746, 2)), - (0x133, (26, 2)), - (0x1d665, (4880, 1)), + (0x2009, (284, 1)), + (0x3377, (2097, 2)), + (0x3160, (1131, 1)), + (0x1d48c, (4430, 1)), + (0x24b3, (778, 3)), (0x1d4d0, (4487, 1)), - (0x1d7e0, (5255, 1)), + (0xffcb, (4206, 1)), (0xfdad, (3609, 3)), + (0x1ee8b, (5448, 1)), (0xfeb1, (3919, 1)), - (0x1d757, (5120, 1)), + (0xfcea, (3165, 2)), (0x2f76, (975, 1)), - (0x1d7bb, (5220, 1)), (0x32be, (1580, 2)), - (0x2163, (489, 2)), - (0x1d4ab, (4454, 1)), + (0x1d7b1, (5210, 1)), + (0x1d5f8, (4771, 1)), + (0xfd73, (3441, 3)), (0xff1a, (4034, 1)), - (0x2f66, (959, 1)), - (0x1d7e2, (5257, 1)), - (0xfebb, (3929, 1)), - (0xb5, (10, 1)), - (0xfdb9, (3645, 3)), - (0xa7f8, (2444, 1)), + (0xfca2, (3019, 2)), + (0x211b, (398, 1)), + (0x1d5b2, (4701, 1)), + (0xfb60, (2505, 1)), + (0x1ee2e, (5389, 1)), + (0x2071, (322, 1)), (0x1d4bb, (4468, 1)), (0x33fc, (2426, 3)), - (0x3153, (1118, 1)), - (0x1d533, (4581, 1)), - (0x1eea6, (5407, 1)), - (0x2478, (599, 3)), + (0xfeef, (3981, 1)), + (0x1d4fb, (4530, 1)), + (0x1d728, (5073, 1)), + (0xfcff, (3210, 2)), (0x1d6f8, (5025, 1)), - (0x1d41c, (4319, 1)), - (0x1d5bc, (4711, 1)), + (0x1d535, (4583, 1)), + (0x1d34, (143, 1)), (0x2165, (492, 2)), - (0x2134, (416, 1)), - (0x3280, (1505, 1)), - (0xff2a, (4050, 1)), - (0x1dba, (228, 1)), - (0xff3c, (4068, 1)), - (0x2463, (559, 1)), - (0xfce2, (3149, 2)), - (0x1d7f9, (5280, 1)), - (0x33dc, (2341, 2)), + (0x1ee2c, (5387, 1)), + (0x1d5dd, (4744, 1)), + (0x2140, (429, 1)), + (0x322d, (1346, 3)), + (0x1ee96, (5459, 1)), + (0xffbe, (4198, 1)), + (0x1eeb5, (5483, 1)), + (0x3311, (1737, 4)), + (0xfd89, (3507, 3)), (0x32d7, (1628, 1)), - (0x2146, (431, 1)), - (0xfc72, (2918, 2)), - (0xfb97, (2560, 1)), - (0x107ad, (4278, 1)), - (0xfd07, (3226, 2)), - (0xfb62, (2507, 1)), - (0x319d, (1189, 1)), + (0x2f91, (1002, 1)), + (0x10798, (4257, 1)), + (0x246b, (569, 2)), + (0x24c2, (799, 1)), + (0x1d50e, (4546, 1)), + (0xffbc, (4196, 1)), + (0xfd9e, (3564, 3)), (0x2115, (393, 1)), (0x1d715, (5054, 1)), + (0xfcac, (3039, 2)), (0xfc98, (2995, 3)), - (0x33bc, (2266, 2)), - (0x1d401, (4292, 1)), - (0xff0a, (4018, 1)), - (0x1ee68, (5357, 1)), - (0x1ee49, (5340, 1)), + (0xfc66, (2890, 3)), + (0x2d6f, (854, 1)), + (0x1d59c, (4679, 1)), + (0xfc01, (2676, 3)), + (0x1ee49, (5402, 1)), (0x2119, (396, 1)), - (0xfb82, (2539, 1)), + (0x24d7, (820, 1)), (0x1d642, (4845, 1)), - (0x1d5c6, (4721, 1)), - (0x107b7, (4287, 1)), - (0x1d42b, (4334, 1)), - (0xffc6, (4203, 1)), - (0x1ee24, (5320, 1)), - (0xfd03, (3218, 2)), - (0x1d732, (5083, 1)), - (0x1ee07, (5293, 1)), - (0x2082, (337, 1)), - (0x1d5e3, (4750, 1)), - (0x2106, (377, 3)), - (0x1f126, (5516, 3)), - (0x2f51, (938, 1)), - (0x1f14f, (5574, 2)), - (0x1d4ef, (4518, 1)), - (0x33e6, (2363, 2)), - (0xff0b, (4019, 1)), - (0x33d7, (2328, 2)), + (0x3304, (1687, 5)), + (0x3198, (1184, 1)), + (0xfed4, (3954, 1)), + (0x2f6c, (965, 1)), + (0x1d406, (4297, 1)), + (0x1d61d, (4808, 1)), + (0x33d5, (2322, 3)), + (0x1ee07, (5355, 1)), + (0x1d4ce, (4485, 1)), + (0x1f101, (5492, 2)), + (0x10792, (4251, 1)), + (0x24be, (795, 1)), + (0x2fbc, (1045, 1)), + (0x1f14f, (5636, 2)), + (0xfe12, (3759, 1)), + (0xfec7, (3941, 1)), + (0xfc2d, (2768, 2)), + (0x248a, (662, 2)), (0x1fed, (265, 3)), - (0x32f8, (1661, 1)), + (0x1d6d5, (4990, 1)), (0x2fb2, (1035, 1)), - (0x1d7ac, (5205, 1)), - (0x32c4, (1592, 2)), + (0xfc8b, (2968, 2)), + (0x3158, (1123, 1)), (0xffe3, (4223, 2)), (0xfb84, (2541, 1)), (0xfb65, (2510, 1)), - (0xfcd1, (3113, 2)), - (0x3d6, (103, 1)), + (0x1ee93, (5456, 1)), + (0x3208, (1216, 3)), (0x32fc, (1665, 1)), (0xfe94, (3890, 1)), (0x2f4f, (936, 1)), - (0x1d4ca, (4481, 1)), - (0x200a, (285, 1)), + (0x2f87, (992, 1)), + (0x1ee75, (5430, 1)), (0x2057, (316, 4)), (0x1d617, (4802, 1)), - (0x2fcb, (1060, 1)), + (0x1d5e1, (4748, 1)), (0xfdac, (3606, 3)), - (0x327e, (1503, 2)), - (0xfcbf, (3077, 2)), - (0xfd5d, (3375, 3)), + (0x2f0e, (871, 1)), + (0x211d, (400, 1)), + (0x331c, (1790, 3)), (0x2f83, (988, 1)), - (0xfce4, (3153, 2)), + (0x1d5c3, (4718, 1)), (0x3373, (2088, 2)), - (0x24d1, (814, 1)), - (0xfce9, (3163, 2)), - (0x24d6, (819, 1)), - (0x32d2, (1623, 1)), + (0x1f13b, (5610, 1)), + (0x2486, (650, 4)), + (0x1d665, (4880, 1)), + (0xfce0, (3144, 3)), (0x3d3, (98, 2)), - (0x32a8, (1545, 1)), - (0x1f250, (5661, 1)), - (0x1d723, (5068, 1)), - (0xfc75, (2924, 2)), - (0xfbd7, (2595, 1)), + (0x1d403, (4294, 1)), + (0x1d640, (4843, 1)), + (0x24ac, (757, 3)), + (0x2f39, (914, 1)), + (0x1f140, (5615, 1)), (0xfb6f, (2520, 1)), - (0x1d5ba, (4709, 1)), - (0xff70, (4120, 1)), - (0x320e, (1234, 4)), - (0x3390, (2154, 2)), - (0xfeda, (3960, 1)), - (0x2fad, (1030, 1)), - (0xfb72, (2523, 1)), - (0xff67, (4111, 1)), - (0x1f223, (5609, 1)), - (0x3234, (1367, 3)), + (0xfd13, (3250, 2)), + (0x1d4c6, (4477, 1)), + (0x1f248, (5720, 3)), + (0x3183, (1166, 1)), + (0x1d62e, (4825, 1)), + (0x1f148, (5623, 1)), + (0xfb89, (2546, 1)), + (0x1ee81, (5439, 1)), + (0xfc25, (2752, 2)), + (0x1f223, (5671, 1)), + (0x334e, (1982, 4)), (0x2fd2, (1067, 1)), - (0x1f243, (5643, 3)), - (0x1ee21, (5318, 1)), + (0xfd54, (3348, 3)), + (0xff01, (4009, 1)), (0x1d740, (5097, 1)), - (0x1d468, (4394, 1)), - (0x1f100, (5428, 2)), - (0x1f241, (5637, 3)), - (0x1d78d, (5174, 1)), - (0x2b0, (62, 1)), - (0x1db1, (219, 1)), + (0x1d7bc, (5221, 1)), + (0x1db4, (222, 1)), + (0x1d43e, (4353, 1)), + (0xfca9, (3033, 2)), + (0xfd22, (3280, 2)), + (0x2f23, (892, 1)), (0x314e, (1113, 1)), - (0x3304, (1687, 5)), - (0x1d420, (4323, 1)), - (0xfd7d, (3471, 3)), - (0x328b, (1516, 1)), - (0x1d67b, (4902, 1)), - (0x1d62c, (4823, 1)), - (0x317b, (1158, 1)), + (0xfe8a, (3877, 2)), + (0xff03, (4011, 1)), + (0x3292, (1523, 1)), + (0xfcf6, (3192, 2)), + (0x1d3f, (153, 1)), + (0x1db8, (226, 1)), + (0xfe68, (3826, 1)), (0x1d69, (194, 1)), (0x1079b, (4260, 1)), - (0x2081, (336, 1)), - (0x1d735, (5086, 1)), - (0xfecc, (3946, 1)), + (0x331b, (1786, 4)), + (0xfda7, (3591, 3)), + (0xffdb, (4218, 1)), (0xfc7c, (2938, 2)), (0xfda5, (3585, 3)), - (0x1d440, (4355, 1)), + (0x3341, (1934, 3)), (0x24a7, (742, 3)), - (0x2fa8, (1025, 1)), + (0x3216, (1266, 4)), (0x2f3e, (919, 1)), - (0xfc91, (2980, 2)), + (0xff9c, (4164, 1)), (0xfb20, (2477, 1)), - (0x1f116, (5468, 3)), + (0x1f116, (5530, 3)), (0x325b, (1442, 2)), - (0x1d4fe, (4533, 1)), + (0x1d5e6, (4753, 1)), (0x1d79e, (5191, 1)), - (0x1ee14, (5306, 1)), - (0x32d3, (1624, 1)), + (0x1ee14, (5368, 1)), + (0x333f, (1927, 2)), (0x32d4, (1625, 1)), - (0xb8, (11, 2)), - (0x24b1, (772, 3)), - (0x1d5e7, (4754, 1)), + (0x1f22d, (5681, 1)), + (0xfd88, (3504, 3)), + (0x1d4d9, (4496, 1)), (0xfdaa, (3600, 3)), (0xfcc6, (3091, 2)), - (0x2136, (418, 1)), - (0x210c, (385, 1)), - (0x32af, (1552, 1)), - (0x1d3d, (151, 1)), - (0x1f120, (5498, 3)), + (0x1d56e, (4633, 1)), + (0x1ee39, (5398, 1)), + (0x1d48a, (4428, 1)), + (0x1d7d0, (5239, 1)), + (0xb9, (13, 1)), + (0x1f120, (5560, 3)), (0x1d60b, (4790, 1)), - (0x2f2d, (902, 1)), - (0x3368, (2056, 3)), - (0x1eea1, (5403, 1)), - (0x32f4, (1657, 1)), - (0xff72, (4122, 1)), - (0x24b6, (787, 1)), - (0x1d630, (4827, 1)), - (0x1d4cb, (4482, 1)), - (0xfe47, (3791, 1)), - (0x1d684, (4911, 1)), + (0x2f70, (969, 1)), + (0x1d4fa, (4529, 1)), + (0x2f5c, (949, 1)), + (0x32ab, (1548, 1)), + (0xfba3, (2572, 1)), + (0x2f02, (859, 1)), + (0x1f11f, (5557, 3)), + (0xfc69, (2899, 3)), + (0x24d4, (817, 1)), (0x2491, (676, 3)), - (0x32d0, (1621, 1)), + (0x326b, (1463, 1)), (0xfc08, (2694, 2)), + (0x1d7b2, (5211, 1)), (0x33ff, (2435, 3)), - (0xfe65, (3824, 1)), - (0x2f99, (1010, 1)), - (0xfede, (3964, 1)), - (0x1d471, (4403, 1)), + (0xfb8d, (2550, 1)), + (0x1fbf0, (5725, 1)), + (0x3252, (1424, 2)), (0x1d6e5, (5006, 1)), + (0x1d5ac, (4695, 1)), (0xfb94, (2557, 1)), - (0xfe61, (3820, 1)), (0x2f63, (956, 1)), + (0x107a2, (4267, 1)), (0xfc06, (2690, 2)), - (0x1d461, (4387, 1)), - (0x1d5d3, (4734, 1)), - (0x246e, (575, 2)), + (0xfc5a, (2858, 2)), + (0xff75, (4125, 1)), + (0xfeda, (3960, 1)), (0xff79, (4129, 1)), (0x2462, (558, 1)), - (0x1d5b2, (4701, 1)), - (0xfca1, (3017, 2)), - (0x1d61b, (4806, 1)), - (0xff12, (4026, 1)), - (0x1ee51, (5345, 1)), - (0x3f1, (105, 1)), - (0x2145, (430, 1)), - (0xfc48, (2822, 2)), - (0x1d619, (4804, 1)), - (0x323b, (1388, 3)), - (0xfcc1, (3081, 2)), - (0x1ee19, (5311, 1)), - (0xfb26, (2483, 1)), - (0x1d67e, (4905, 1)), - (0x1d749, (5106, 1)), + (0xfc09, (2696, 2)), + (0x2111, (390, 1)), + (0x319e, (1190, 1)), + (0x1d451, (4372, 1)), + (0x2f20, (889, 1)), + (0x1d6a0, (4939, 1)), + (0x1d577, (4642, 1)), + (0x1d7b6, (5215, 1)), + (0xff15, (4029, 1)), + (0x1d744, (5101, 1)), + (0x1f21c, (5664, 1)), + (0x1fbf2, (5727, 1)), + (0xfc3a, (2794, 2)), + (0x337b, (2107, 2)), + (0xfdb8, (3642, 3)), (0xffc3, (4200, 1)), - (0x1d564, (4623, 1)), + (0x33db, (2339, 2)), + (0xff0c, (4020, 1)), (0x1d52a, (4572, 1)), - (0x1d500, (4535, 1)), - (0x1d5d8, (4739, 1)), - (0x1d7b1, (5210, 1)), - (0x1d563, (4622, 1)), - (0x2047, (310, 2)), - (0x33eb, (2375, 3)), - (0xfda3, (3579, 3)), - (0x3317, (1765, 5)), - (0xff74, (4124, 1)), - (0x1ee1e, (5316, 1)), - (0x3308, (1704, 4)), - (0x33d6, (2325, 3)), - (0x3269, (1461, 1)), - (0x1ee27, (5321, 1)), - (0x1d5c3, (4718, 1)), - (0xfe3c, (3782, 1)), - (0x1eeb0, (5416, 1)), - (0x335f, (2032, 2)), - (0x338b, (2144, 2)), - (0x3318, (1770, 4)), - (0xfe7c, (3850, 2)), - (0xfedf, (3965, 1)), - (0x1d32, (141, 1)), - (0xfb63, (2508, 1)), - (0xfe42, (3788, 1)), + (0x1ee9b, (5464, 1)), + (0x24e2, (831, 1)), + (0xff9e, (4166, 1)), + (0x32de, (1635, 1)), + (0x1d574, (4639, 1)), + (0x1ee76, (5431, 1)), + (0x1d59e, (4681, 1)), + (0x1f244, (5708, 3)), + (0x1f137, (5606, 1)), + (0xfea0, (3902, 1)), + (0xff2a, (4050, 1)), + (0x314f, (1114, 1)), + (0x1d47c, (4414, 1)), + (0x1d467, (4393, 1)), + (0xff4f, (4087, 1)), + (0xfea1, (3903, 1)), + (0x33a9, (2217, 2)), + (0x10799, (4258, 1)), + (0x1ee12, (5366, 1)), + (0x2492, (679, 3)), + (0x1d696, (4929, 1)), + (0xfcab, (3037, 2)), + (0xfd19, (3262, 2)), + (0x1d5e8, (4755, 1)), + (0x1ee1f, (5379, 1)), (0xfe91, (3887, 1)), (0x1c7, (44, 2)), - (0x320b, (1225, 3)), - (0x321a, (1282, 4)), - (0x1d4c5, (4476, 1)), + (0x1d681, (4908, 1)), + (0x24b7, (788, 1)), (0x1d784, (5165, 1)), - (0x320d, (1231, 3)), - (0x1d49e, (4447, 1)), - (0x1d604, (4783, 1)), - (0xfc71, (2916, 2)), - (0x1d6ce, (4983, 1)), - (0x1d752, (5115, 1)), + (0x1d742, (5099, 1)), + (0x33a2, (2196, 3)), + (0x1d645, (4848, 1)), + (0x1ee70, (5426, 1)), + (0x1d611, (4796, 1)), + (0x337c, (2109, 2)), + (0x1d442, (4357, 1)), (0xfe32, (3772, 1)), - (0x1ee11, (5303, 1)), (0x1d31, (140, 1)), + (0x3138, (1091, 1)), (0x2485, (646, 4)), - (0xfedb, (3961, 1)), - (0x1d50f, (4547, 1)), - (0x313a, (1093, 1)), - (0xfb66, (2511, 1)), - (0xff64, (4108, 1)), - (0x1d5ac, (4695, 1)), - (0x1d4e2, (4505, 1)), - (0x3f4, (107, 1)), - (0xfecb, (3945, 1)), + (0x1f114, (5524, 3)), + (0x1d5d0, (4731, 1)), + (0x1d635, (4832, 1)), + (0x3309, (1708, 3)), + (0x1d408, (4299, 1)), + (0xfe50, (3804, 1)), + (0x1ee8d, (5450, 1)), + (0xfd93, (3531, 3)), + (0x1d67b, (4902, 1)), (0x1d4db, (4498, 1)), - (0x2fc3, (1052, 1)), - (0x1ee4e, (5343, 1)), - (0xfcd6, (3123, 2)), + (0x1f136, (5605, 1)), + (0x1f22f, (5683, 1)), + (0x1d7ed, (5268, 1)), + (0x32f9, (1662, 1)), (0x32aa, (1547, 1)), - (0x3354, (2002, 5)), - (0x1d5f7, (4770, 1)), + (0x33af, (2236, 6)), (0x24e4, (833, 1)), - (0x32e0, (1637, 1)), - (0x1d421, (4324, 1)), - (0x1d587, (4658, 1)), + (0x2003, (278, 1)), + (0xfd80, (3480, 3)), + (0x1e04e, (5317, 1)), + (0x1d59b, (4678, 1)), (0x3285, (1510, 1)), - (0x1fee, (268, 3)), (0x1d78e, (5175, 1)), - (0x2007, (282, 1)), + (0x3379, (2102, 3)), (0x107b2, (4282, 1)), (0xfeb7, (3925, 1)), - (0x32e4, (1641, 1)), + (0x2470, (579, 2)), (0x1d620, (4811, 1)), - (0x1d6ca, (4979, 1)), - (0x1d725, (5070, 1)), - (0xfdbe, (3660, 3)), + (0x1d4b4, (4462, 1)), + (0x1d754, (5117, 1)), + (0x1f246, (5714, 3)), (0x2160, (483, 1)), - (0xfc52, (2842, 2)), - (0xfc73, (2920, 2)), - (0x2171, (514, 2)), - (0x1d528, (4570, 1)), + (0x1d72f, (5080, 1)), + (0xfe4f, (3803, 1)), + (0x1d47a, (4412, 1)), + (0x1fcd, (247, 3)), + (0x327d, (1499, 4)), (0x338e, (2150, 2)), - (0xfdf4, (3704, 4)), - (0x33f2, (2396, 3)), - (0x3222, (1313, 3)), - (0x1f22b, (5617, 1)), - (0x1d453, (4374, 1)), - (0x1d41b, (4318, 1)), - (0xffcc, (4207, 1)), - (0x1d58e, (4665, 1)), - (0xfd19, (3262, 2)), - (0x1d6bb, (4964, 1)), - (0x1d41d, (4320, 1)), - (0x2f7e, (983, 1)), - (0xfe8d, (3883, 1)), - (0xff58, (4096, 1)), - (0x24dc, (825, 1)), - (0xfe55, (3808, 1)), - (0x3231, (1358, 3)), + (0x33b3, (2248, 2)), + (0xfd10, (3244, 2)), + (0x2f37, (912, 1)), + (0x3187, (1170, 1)), + (0xff5c, (4100, 1)), + (0x2135, (417, 1)), + (0x1d73b, (5092, 1)), + (0x3178, (1155, 1)), + (0xfc86, (2958, 2)), + (0x2fa5, (1022, 1)), + (0x1d6f1, (5018, 1)), + (0x1db5, (223, 1)), + (0xfb7d, (2534, 1)), + (0xfc48, (2822, 2)), + (0x1d56, (175, 1)), + (0x1d647, (4850, 1)), + (0xfe65, (3824, 1)), (0xfc18, (2726, 2)), (0x33f1, (2393, 3)), - (0x32f1, (1654, 1)), - (0x209c, (362, 1)), - (0xfe8b, (3879, 2)), - (0x24e0, (829, 1)), - (0x1d4b6, (4464, 1)), - (0x1d622, (4813, 1)), + (0x328c, (1517, 1)), + (0x32b9, (1570, 2)), + (0xfb79, (2530, 1)), + (0x1d4ee, (4517, 1)), + (0x338f, (2152, 2)), + (0x1d663, (4878, 1)), (0x33b7, (2256, 2)), - (0x1d487, (4425, 1)), + (0x1d55a, (4613, 1)), (0xfcb1, (3049, 2)), - (0x331e, (1796, 4)), + (0x3254, (1428, 2)), (0xfbde, (2603, 1)), (0x2f73, (972, 1)), - (0x32f6, (1659, 1)), + (0x1d497, (4441, 1)), (0xff89, (4145, 1)), (0x1d5f5, (4768, 1)), ]; @@ -28460,403 +28666,410 @@ pub(crate) const CJK_COMPAT_VARIANTS_DECOMPOSED_KV: &[(u32, (u16, u16))] = &[ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, + 0xd, + 0x4, + 0xc, + 0x5, + 0x689, + 0x7, + 0x0, 0x2, - 0x2, - 0x6, - 0x9, - 0xb02, - 0x15, 0x0, - 0x8, - 0x1c, 0x2, - 0x206, + 0x3, 0x0, 0x0, - 0x82, + 0xab, 0x0, - 0x269, + 0x158, 0x0, - 0x24, - 0x11a, + 0x5a, + 0x1c6, + 0x143, 0x0, + 0x1, 0x0, - 0x7, - 0x2a, - 0xe, + 0x4, 0x0, 0x0, 0x0, - 0x1, + 0x6, + 0x4, 0x0, - 0x235, + 0x92, 0x0, 0x0, - 0x1a6, + 0x24d, 0x0, - 0x5, + 0x7, 0x0, - 0xa5, + 0x7f, 0xc, 0x0, + 0xc7, 0x0, - 0xfa, - 0x32b, - 0x0, + 0x16d, 0x0, 0x0, - 0x1b, - 0x5c, - 0x1, - 0x1, 0x0, - 0x8f, - 0xd, - 0x15b, - 0x63, + 0xda, + 0x4, 0x19, + 0x5, + 0x0, + 0x93, + 0x6, + 0x7c, + 0x13, + 0x11b, 0x0, 0x1, - 0x11, - 0x43, + 0x8, + 0x58, + 0x0, + 0x5c, + 0xa5, 0x0, - 0x36, - 0x3f, 0x1, - 0x17, 0x0, 0x0, 0x0, 0xb4, 0x1, - 0x53, - 0x0, 0x1, - 0x7e, - 0xb, - 0x0, - 0x73, - 0x4b, 0x0, - 0x4e, - 0x1e, - 0x9b, - 0x3, - 0x15, + 0x1, + 0x8, 0x0, + 0x79, + 0x7, 0x0, + 0xa0, + 0x37, 0x0, 0x7, + 0x36, + 0x5, + 0x39, 0x0, 0x0, - 0x22, 0x2, - 0x0, - 0x89, + 0x9, 0x0, 0x0, - 0x25, + 0x73, 0x1, + 0x5, 0x0, 0x0, - 0x41, 0x0, + 0x3d, 0x1, 0x0, - 0x0, 0x4, - 0x23, + 0x0, + 0x54, + 0x1, + 0x0, + 0x27, + 0x4d, + 0xfa, + 0x4d, 0x3, - 0x10, 0x1c, - 0x66, - 0xc, - 0x7, - 0x36, - 0x40, - 0x0, + 0xdd, + 0x6, + 0x1, + 0x24, + 0x41, 0x0, 0x0, - 0x1d, 0x0, - 0x12, - 0xa, - 0x4, + 0xb, 0x0, - 0xc, - 0x7, - 0x4, 0x5, + 0x3, + 0xb6, 0x0, - 0x8a, - 0x6d, - 0x1e, - 0x0, - 0x15, + 0xf, 0x0, - 0x10, - 0x3, - 0x3b, - 0xa3, - 0xd, - 0x2, - 0x37, - 0x25, - 0x17, + 0x1, 0x16, 0x0, - 0x6, 0x0, + 0x9e, 0x1, 0x0, + 0x21, + 0x0, + 0x25, + 0x4, + 0x10, + 0x4, + 0x15, + 0x2, 0x1, - 0x47, - 0x24, - 0x12, + 0x23, + 0x5, + 0x84, 0x0, 0x0, + 0xf, + 0xa, + 0x2, + 0x37, 0x1, 0x0, + 0x46, + 0xd, + 0x12, 0x0, + 0x4, 0x0, 0x0, - 0x1, - 0x34, 0x0, - 0x1, + 0x24, + 0xc, + 0x4a, + 0x2, + 0x4, 0x0, - 0x1e, + 0x42, 0x0, - 0x3, + 0x4, 0x13, - 0x8, - 0x28, - 0x2b, - 0x57, + 0x2, + 0x13, + 0x7b, + 0x3e, 0x0, - 0x1d, - 0x3, 0x11, - 0x8, + 0x2, + 0x7, + 0x1, 0x0, + 0x31, 0x3, - 0x47, 0x0, - 0x4, + 0x12, 0x0, 0x0, 0x0, + 0x35, + 0x6, 0xe, - 0x3, - 0x5, - 0x0, - 0x3f, + 0x1e, + 0xc1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5, + 0x2, + 0x1c, 0x0, - 0x18, - 0x32, - 0x1, + 0x8, 0x0, - 0x14, - 0xa, 0x9, - 0x23, 0x3, - 0x0, + 0x8d, + 0x70, + 0x54, + 0x23, + 0x11, + 0x1f, + 0x5, + 0x17, + 0x4, 0x2, 0x0, - 0x1, - 0x3, - 0x0, - 0xe, - 0x1a, - 0x8, - 0xf, + 0x47, + 0x17, + 0xc, + 0x2a, 0x0, - 0x1, + 0x3, 0x0, 0x0, 0x0, - 0x4, - 0x4e, - 0x2, - 0x1b, - 0x15, 0x5, + 0x38, + 0x11, + 0x15, + 0x39, + 0x6, 0x0, 0x3, + 0x3, 0x1, - 0xd, 0x0, 0x0, 0x0, - 0x5, - 0x3, - 0x0, - 0x2, + 0x53, + 0x4, 0x1, - 0x1b, - 0x0, - 0x20, - 0x3, + 0x1, + 0x1, + 0x2, 0x0, + 0xf, + 0x6, 0x0, 0x0, - 0x9, - 0x6, 0x0, + 0x4, + 0x28, + 0x4, 0x0, 0x0, - 0x1e, - 0x31, + 0x11, + 0x2e, + 0x6, + 0x4, 0x1, - 0xc, - 0xb, 0x1, + 0x12, 0x0, 0x0, 0x0, + 0x2, 0x5, - 0x1, - 0x4, - 0x11, 0x0, - 0x3a, - 0x1, 0x15, + 0x2e, 0x0, - 0x12, + 0x1, 0x0, 0x0, - 0x4, - 0x13, - 0x14, + 0x6, 0x0, 0x0, - 0x11, - 0x2, - 0x8, + 0xd, + 0x3, 0x0, 0x0, + 0x3f, 0x8, - 0x3, 0x0, - 0x4, - 0x0, - 0x3, - 0xb, - 0x3, - 0xc, + 0x8, 0x0, 0x0, + 0x1a, + 0x2, 0x0, - 0x9, + 0x7, 0x0, - 0x6, - 0x1, 0xa, + 0x0, 0x3, + 0xc, + 0x0, + 0x14, + 0x0, 0x6, - 0x2, + 0x0, + 0x19, 0x1, 0x3, - 0x2, - 0x2b, - 0x9, 0x3, + 0x6, + 0x10, + 0x12, + 0x1, + 0x16, 0x0, + 0x4, + 0x1, 0x0, 0x0, - 0x8, - 0x30, - 0x2, 0x0, - 0x1, - 0x1b, + 0x0, + 0x3, 0x2, + 0x21, + 0x1, + 0x3, + 0x13, + 0x16, 0x0, 0x0, - 0x29, - 0x4, - 0xb, - 0x5f, + 0x1, + 0x5, 0x0, + 0xe, 0x0, 0x0, + 0x38, + 0x2, + 0x20, 0x3, - 0xb, - 0x1, 0x0, - 0x9, 0xa, + 0xe, 0x1, - 0x8, - 0x4, + 0x3, 0x0, - 0x8, - 0x1, 0x0, + 0xa, + 0x6, 0x0, - 0x1f, + 0x0, + 0x2, 0x0, 0x0, - 0x8, - 0x28, + 0x0, + 0x2, 0x0, 0x4, 0x18, - 0x1e, + 0x1, + 0x0, 0x2, 0x0, + 0xc, 0x0, - 0xa, 0x0, 0x1, + 0x1, 0x0, 0x1, - 0x9, + 0x0, 0xb, 0x0, - 0x2, - 0x1e, - 0x18, + 0x1, 0x2, 0x0, 0x0, - 0xd, - 0xb, - 0x25, + 0x1b, + 0x6, 0x0, + 0x4, 0x0, 0x0, - 0x4, + 0x5, + 0x20, 0x0, - 0x1, - 0xc, + 0x9, 0x0, 0x0, 0x0, - 0x4, 0x0, - 0x1, + 0x2, 0x0, + 0x1, 0x3, - 0xa, 0x0, - 0xf, + 0xc, 0x0, + 0x16, 0x0, - 0xb, 0x0, - 0x5, + 0x3, + 0x0, + 0x7, 0x0, + 0x8, 0x4, - 0x3, 0x0, 0x0, 0x0, @@ -28868,1022 +29081,1040 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0x4, + 0x1f, + 0xa, + 0x28, + 0x0, + 0x1, 0x0, - 0xe, 0x0, + 0x8, + 0xd, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, + 0x1, 0x0, + 0x2, 0x0, 0x0, + 0x3a, + 0x4, + 0x8, + 0xb, 0x0, - 0x1, - 0x21, 0x17, 0x0, + 0x2, 0x0, - 0x1, - 0x7, - 0x16, - 0xc, - 0x1, 0x0, 0x22, - 0x5, - 0x0, - 0x3, 0x0, - 0x24, - 0xc, - 0x3, 0x4, - 0x5, - 0x1f, - 0x7, - 0x1, - 0xa, 0x0, 0x1, - 0x3a, + 0x2, + 0x6, + 0x17, + 0x7, 0x9, + 0x27, 0x0, 0x1, - 0x5, - 0x0, - 0x0, + 0x11, + 0x7, + 0x23, 0x1, 0x1, - 0x3, - 0x27, - 0x9, - 0x0, - 0xf, - 0x18, - 0x3, - 0x4, 0x0, 0x0, 0x9, - 0x5, - 0x4, - 0x0, - 0xf, - 0x1, - 0x1, - 0x7, + 0x8, 0x2, - 0x1, - 0x7, - 0x1, - 0x5, + 0x27, 0x8, 0x0, - 0x3e, - 0x2, - 0xb, - 0xd, - 0x1, - 0xf, + 0x17, + 0xc, + 0x3b, + 0x6, 0x0, 0x0, - 0x9, - 0x1d, - 0x12, + 0xc, 0x0, + 0x4, + 0x0, + 0x2e, + 0x5, + 0x7, + 0x7, 0x0, - 0xc, 0x3, - 0x6, - 0x19, + 0xf, + 0x1, 0x0, - 0x15, - 0x6, - 0x14, 0x2, 0x0, 0x6, + 0x2, + 0x2, + 0x4, 0x0, - 0x9, - 0x0, + 0x3, + 0xf, 0x0, - 0xe, - 0x1, 0x1, + 0x12, + 0x24, 0x0, - 0x2, - 0x3, 0x0, 0x0, + 0xb, 0x1f, - 0xa, + 0x15, + 0xd, 0x0, - 0x8, + 0x1, 0x0, - 0x3, + 0x1, + 0x2, 0x0, 0x1, 0x0, - 0x2, - 0x1b, + 0x8, + 0x0, 0x0, - 0x4, 0xc, 0x1, + 0xe, + 0x0, 0x4, + 0x4, + 0x0, 0x0, 0x1, + 0x3, + 0x0, + 0x2, + 0x0, + 0x2e, + 0x0, + 0x11, + 0x0, + 0x1b, + 0xa, + 0x13, + 0x12, + 0x2, 0x9, - 0x7, - 0x7, + 0x1, + 0xd, 0x0, - 0x3, 0x1, + 0x2, + 0x0, + 0xd, 0x0, + 0xb, + 0x6, 0x0, 0x0, + 0xb, 0x1, 0x0, 0x0, - 0x6, 0x2, - 0x0, + 0x13, + 0x16, + 0xd, + 0xe, + 0x4, + 0xf, + 0xb, 0x2, 0x0, - 0x1, - 0xa, - 0x1, 0x0, - 0x5, + 0xa, 0x0, - 0x1c, + 0x3, 0x0, 0xd, - 0x6, - 0x3, 0x2, - 0xe, + 0xb, 0x0, - 0x10, + 0x1d, 0x0, - 0x1, - 0x3d, + 0x2, + 0x7, 0x0, 0x0, - 0x6, + 0x1, 0x0, 0x0, 0x0, - 0x3, 0x7, + 0x6, + 0xe, 0x4, - 0x20, - 0xc, - 0x1, 0x0, - 0x15, + 0x1, + 0x8, + 0x14, 0x0, - 0x2, 0x0, + 0x15, 0x0, - 0x5, + 0x1, 0x0, 0x0, 0x0, - 0xd, + 0x10, 0x0, 0x0, - 0x2, - 0x3, + 0x6, + 0x17, 0x0, 0x1, 0x0, - 0x4, + 0x10, 0x0, 0x0, 0x0, - 0xd, + 0xa, 0x0, 0x0, - 0x5, - 0x2c, + 0x1, + 0x6, + 0x4, + 0x0, 0x4, - 0x2, 0x1, - 0x7, 0x1, - 0xa, - 0xf, + 0x2, + 0x2, 0x0, - 0x8, + 0x1, + 0x7, 0x0, 0x0, - 0x13, - 0x1, - 0x19, 0x2, - 0x1, - 0xf, + 0x2, + 0x7, + 0x2, + 0x1f, + 0x9, 0x0, 0x4, - 0x19, + 0x7, 0x0, - 0xc, + 0x1, 0x0, 0x0, 0x0, - 0x1, + 0x4, + 0x3, + 0x4, 0x0, - 0x5, 0x0, 0x0, - 0x1, + 0x4, 0x0, 0x0, 0x1, - 0xd, - 0x1, - 0x5, + 0x9, + 0x17, + 0x6, + 0xf, + 0xc, 0x0, - 0x2, - 0xb, 0x0, 0x0, + 0x10, 0x0, - 0x18, - 0x6, - 0x1, - 0x1, + 0x2, + 0x2, 0x0, - 0x3, - 0x4, 0x6, + 0x2, 0x0, 0x3, - 0x8, - 0x4, - 0x6, 0x2, + 0x9, + 0x3, + 0x2, + 0x3, + 0x1, 0x0, 0x0, 0x0, + 0x12, + 0x4, 0x0, - 0x6, - 0x0, + 0x8, 0x0, - 0x2, 0x3, - 0xb, + 0x18, 0x0, 0x3, - 0x0, 0xc, - 0x3, - 0x17, + 0x0, + 0x2, + 0x26, 0x0, 0x0, - 0x4, - 0xa, - 0x11, + 0x2, + 0x6, + 0x2, 0x0, 0x1, - 0x3, - 0x3, + 0x9, 0x8, - 0xd, + 0x16, 0x1, + 0x3, 0x11, 0x0, - 0x9, + 0x13, 0x0, + 0x2, 0x7, 0x0, - 0x2, + 0x3, 0x0, 0x0, 0x0, - 0x7, - 0x2, + 0xc, + 0x1a, 0x0, 0x0, - 0x7, 0x1, - 0x7, - 0x6, + 0x2, 0x0, - 0x3, - 0x5, - 0xa, + 0x2, + 0x9, + 0x4, + 0x12, 0x0, 0x0, - 0x3, - 0xe, + 0x11, + 0x8, + 0x0, 0x0, 0x1, - 0x8, 0x3, - 0x2, + 0x0, + 0x3, + 0x6, + 0xf, 0x4, - 0x5, - 0x1d, - 0x7, 0x1, + 0x3, 0x0, - 0x4, 0x7, + 0x4, 0x9, + 0x4, + 0x1, + 0x0, 0x5, - 0x3, + 0x4, 0x0, - 0xd, - 0x3, + 0x1, 0x0, - 0x4, 0x0, + 0x3, + 0x2, + 0x15, + 0x2, + 0x0, + 0x8, 0x0, 0x2, - 0x1, 0x0, - 0x14, - 0x15, - 0x4, 0x3, - 0x4, - 0x0, - 0x17, - 0xc, + 0x11, + 0x6, + 0x6, + 0xd, 0x1, 0x0, - 0x4, 0x1, - 0x5, 0x3, - 0x5, - 0xb, 0x6, - 0x5, - 0x7, - 0x3, - 0x0, - 0x3, + 0x20, + 0x4, + 0x1, + 0x2, + 0xb, + 0x1, 0x0, 0x0, + 0x1, + 0x1, 0x11, - 0x21, 0x0, - 0x10, - 0x4, - 0x4, - 0x0, - 0x4, + 0x1, 0x0, - 0x15, - 0x3, + 0x2, 0x1, + 0x0, + 0x0, + 0x7, 0x4, + 0x5, + 0x3, 0x0, 0x0, 0x0, - 0x1, - 0x8, - 0x3, - 0x2, + 0x5, 0x0, + 0x2, 0x3, 0x0, - 0x1, + 0x3, 0x0, + 0x4, + 0x4, 0x2, 0x0, - 0xc, - 0x6, - 0x5, - 0x2, - 0x1b, - 0x2, - 0x2, - 0x1, 0x2, - 0xf, + 0x19, + 0x4, 0x1, - 0x0, - 0x16, - 0x0, + 0x13, 0x1, + 0x2, 0x9, + 0xb, + 0x6, + 0x4, 0x0, 0x1, 0x0, + 0x1, + 0x1a, 0x0, 0x2, + 0x5, 0x0, 0xf, 0x0, - 0x1, - 0x17, - 0x4, - 0x2, + 0x8, + 0x0, + 0x0, 0x2, + 0x4, + 0x10, 0x1, 0x1, + 0x2, + 0x12, 0x0, 0x0, + 0x9, 0x0, - 0xc, - 0x0, - 0x3, - 0x0, + 0x13, 0x1, - 0x6, - 0x5, 0x2, - 0x0, - 0x8, - 0x5, + 0x4, 0x6, + 0x4, + 0x4, 0x0, - 0x3, - 0x9, + 0x6, + 0x2, 0x15, 0x0, - 0xb, + 0x1, + 0x9, + 0xe, + 0x2, 0x3, 0x3, + 0x0, + 0x1, 0x4, - 0x3, 0x0, 0x0, - 0x2, - 0xb, + 0x5, + 0xe, + 0x0, + 0x7, 0x0, 0x2, 0x0, + 0xb, 0x2, - 0x8, - 0x1, - 0x15, 0x0, - 0x3, + 0x1, 0x4, - 0x2, + 0x9, 0x2, 0x0, 0x0, - 0x4, + 0x0, 0x1, 0x1, - 0xf, - 0x8, - 0xe, - 0x6, - 0x3, 0x0, + 0x4, 0x1, + 0xd, + 0x3, 0x0, 0x1, - 0x1, - 0x1, - 0x0, 0x0, + 0x4, + 0x3, 0x1, - 0x0, - 0x8, 0x2, 0x0, - 0x4, + 0x2, + 0x5, 0x0, + 0x3, + 0x2c, + 0xa, + 0x3, 0x0, - 0x1, + 0x9, 0x0, - 0x3, 0x0, 0x2, 0x0, - 0x0, - 0x1, 0x1, 0x0, 0x0, + 0x27, + 0x2, + 0x0, 0x0, 0x0, + 0x15, 0x1, + 0x2, + 0x4, + 0x0, + 0x2, + 0x0, 0x3, 0x3, - 0x0, 0x1, 0x0, - 0x7, - 0x7, + 0x2, + 0x5, + 0xa, 0x9, - 0x0, - 0x1, - 0x1, - 0x4, - 0x4, 0x1, 0x2, 0x3, - 0x16, - 0x3, 0x1, - 0xd, - 0x3, - 0xb, 0x5, - 0x4, - 0x0, - 0x7, - 0x4, - 0x0, + 0x1, 0x8, - 0xc, - 0x0, + 0x1, + 0x1, + 0xf, 0x0, + 0x3, + 0xa, + 0x3, 0x4, - 0x7, - 0x1, 0xd, + 0x3, + 0x1, 0x0, + 0xc, + 0x1e, 0x1, 0x1, + 0xa, 0x1, - 0x6, + 0x3, 0x0, - 0x4, - 0x9, - 0x9, - 0x8, - 0x1, 0x1, + 0x0, 0x6, - 0x2, - 0x1, 0x0, + 0x3, 0x2, - 0x1, + 0x7, + 0x3, + 0xe, + 0x3, + 0x4, + 0xf, + 0x4, 0x2, + 0x3, + 0x8, 0x0, 0x2, 0x3, 0x1, + 0x10, + 0x2, + 0x2, 0x2, - 0x1, - 0x1, - 0x4, 0x0, 0x0, - 0x1, - 0x3, + 0x5, + 0x2, 0x0, - 0x4, 0x0, + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x7, + 0x8, 0x0, 0x0, 0x0, - 0x2, + 0x4, 0x0, 0x0, 0x0, 0x1, - 0x8, + 0x3, 0x0, 0x0, 0x1, + 0x2, 0x1, - 0xa, - 0x0, + 0xb, 0x7, - 0x1, - 0x1, - 0x0, - 0x0, 0x0, + 0x3, + 0x5, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x1, - 0x4, + 0x0, 0x2, + 0xa, + 0xa, + 0x5, + 0x1, 0x0, 0x0, 0x0, - 0x4, + 0x2, 0x1, - 0x4, + 0x9, 0x0, 0x2, - 0x4, - 0x5, + 0xb, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x8, 0x1, - 0x2, - 0xe, - 0xa, + 0xc, + 0xc, + 0x4, 0x0, 0x1, - 0x1, - 0x1, - 0x2, 0x4, - 0x2, + 0x3, + 0x4, + 0x3, + 0x1, + 0x7, 0x5, + 0x2, 0x4, - 0x0, - 0x8, - 0x14, + 0x1, 0x1, 0x2, 0x0, 0x0, - 0x5, + 0x8, 0x1, 0x0, 0x0, 0x0, 0x1, + 0x2, 0x1, + 0x2, 0x0, - 0x6, - 0x0, - 0x4, - 0x0, + 0xc, + 0x5, 0x1, 0x0, 0x2, - 0xa, - 0x17, - 0x3, + 0x2, 0x6, - 0x4, 0x0, + 0x1, + 0x2, + 0x2, 0x0, 0x0, + 0x6, + 0x2, + 0x7, 0x1, 0x0, - 0x1, 0x0, + 0x5, + 0x1, + 0xa, 0x0, - 0x8, - 0x2, 0x2, 0x0, 0x1, 0x0, - 0x2, - 0x0, 0x0, 0x1, - 0x9, - 0x6, + 0x1, + 0xc, 0x0, 0x3, 0x2, + 0x9, 0x0, - 0x0, - 0x2, 0x2, + 0x3, 0x0, 0x1, - 0x8, - 0x6, 0x1, - 0x7, + 0x5, 0x4, - 0x2, 0x7, - 0x5, - 0x8, - 0x5, - 0x0, - 0x8, - 0x0, + 0x1, 0x1, 0x1, 0x2, - 0x7, 0x1, + 0x3, + 0x3, + 0x0, 0x1, - 0x8, + 0x3, 0x0, 0x2, + 0x2, 0x0, + 0x1, 0x6, + 0x1, + 0xa, 0x0, - 0xb, 0x0, - 0x2, + 0x8, + 0x0, 0x5, 0x0, + 0x1, + 0x2, + 0x0, 0x0, 0x0, - 0x4, + 0x7, 0x0, - 0x8, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, - 0x14, - 0x9, - 0x10, - 0xa, 0x2, + 0x10, + 0x7, + 0x1, + 0x5, + 0xe, 0x0, 0x0, 0x0, - 0xc, - 0x3, + 0x5, + 0x7, + 0x5, 0x1, - 0x3, 0x0, - 0x1, - 0x16, + 0x4, + 0x0, 0x5, - 0x9, - 0x1, - 0xa, - 0x1, + 0x3, + 0x2, 0x0, 0x1, 0x0, 0x0, - 0x3, - 0x3, - 0xd, + 0x9, 0x0, + 0x4, + 0x2, + 0x3, 0x6, - 0x1, + 0x5, 0x0, 0x1, + 0x1, + 0x1, + 0x3, + 0x2, + 0x4, + 0x2, 0x2, - 0x6, 0x2, - 0x9, - 0x9, - 0xf, - 0x0, - 0x0, - 0xd, - 0x1, 0x0, 0x3, - 0x4, + 0x6, 0x0, 0x1, 0x1, 0x0, - 0x0, - 0x1, - 0x1, 0x1, + 0x2, + 0x14, + 0x0, 0x0, 0x7, + 0x5, + 0x2, + 0x0, + 0x1, 0x0, 0x0, 0x0, 0x1, + 0x6, + 0xb, + 0x5, 0x0, - 0xc, - 0x8, + 0xf, + 0x1, 0x0, - 0x5, + 0x6, + 0x9, + 0x1, + 0x7, 0x2, 0x0, - 0x4, - 0x2, 0x1, - 0x3, - 0xb, - 0x0, - 0x3, - 0x4, + 0x1, 0x0, 0x0, 0x1, 0x1, + 0x1, 0x5, 0x7, - 0x7, 0x0, 0x0, 0x0, - 0x3, 0x0, - 0x5, - 0x5, + 0x6, + 0x6, 0x0, - 0x1, 0x7, 0x0, - 0x0, 0x1, + 0x0, + 0x0, 0x3, + 0x8, + 0x0, 0x0, - 0x4, 0x1, - 0xe, 0x1, - 0x4, + 0x6, + 0xb, + 0x7, 0x0, 0x0, - 0xa, + 0x3, 0x0, 0x1, - 0x2, - 0x3, + 0x8, 0x1, - 0x7, 0x1, + 0x5, + 0x2, 0x1, - 0x4, - 0x7, - 0x0, 0x2, + 0xa, 0x0, - 0x0, - 0xc, - 0x0, - 0x1, 0x1, 0x0, 0x0, + 0x3, 0x0, - 0xe, - 0x9, - 0x2, - 0x6, - 0x2, 0x2, - 0x1, - 0x1, 0x2, 0x0, - 0x8, - 0xb, + 0x0, 0x0, 0x0, 0x1, - 0x2, 0x3, - 0x1, + 0x6, 0x2, 0x0, - 0x5, - 0x6, 0x2, 0x1, - 0x1, 0x4, 0x1, + 0x2, + 0x2, 0x0, - 0x3, 0x0, - 0x5, - 0x7, 0x1, - 0x0, - 0x13, + 0x4, + 0x2, 0x1, - 0x3, - 0x9, 0x1, 0x1, 0x0, + 0x2, 0x4, + 0x3, + 0x2, + 0x3, 0x1, 0x0, - 0x5, 0x1, - 0x5, - 0x10, - 0x7, + 0x0, + 0x0, + 0x4, 0x0, 0x3, - 0xc, 0x3, + 0x0, + 0x5, 0x5, 0x1, + 0x3, + 0x6, 0x0, + 0x1, 0x2, - 0xd, - 0x4, 0x0, + 0xa, + 0x3, + 0x1, + 0x1, 0x2, - 0x6, 0x0, 0x0, - 0x9, + 0x2, + 0x4, 0x3, + 0x2, + 0x0, + 0x2, + 0x5, 0x1, 0x0, + 0xb, + 0xa, + 0x0, + 0x0, + 0x1, 0x3, 0x0, 0x3, - 0x2, - 0x2, 0x0, + 0x1, 0x0, + 0x3, + 0x8, 0x2, - 0x1, 0x0, 0x4, 0x0, - 0x2, 0x1, 0x0, + 0x8, + 0x2, + 0x0, + 0x1, 0x1, 0x1, 0x0, 0x0, - 0x8, - 0x6, + 0x0, + 0x5, 0x3, - 0x8, - 0x7, + 0x6, + 0x2, + 0x14, 0x0, 0x1, 0x0, - 0x1, + 0x2, + 0x3, 0x3, 0x1, - 0x2, + 0x3, + 0x6, + 0x8, 0x1, 0x1, - 0x2, - 0x3, - 0x2, 0x1, 0x1, + 0x3, 0x8, - 0x1, 0x0, 0x0, + 0x4, + 0x6, 0x3, - 0x1, - 0x9, 0x0, 0x3, 0x0, - 0x7, 0x0, + 0x9, + 0xa, + 0x3, + 0x3, 0x2, + 0x5, + 0x7, 0x2, 0x0, - 0x3, - 0x1, - 0x1, - 0xe, + 0xa, 0x1, 0x2, 0x1, 0x1, - 0x1, 0x0, 0x2, + 0x2, 0x0, - 0x5, + 0x1, + 0x6, 0x1, 0x0, - 0xe, + 0x0, + 0xb, + 0x3, 0x2, + 0x3, 0x0, 0x0, - 0x3, - 0x6, - 0x1, - 0x6, 0x0, + 0x6, 0x0, - 0x1, - 0x1, - 0x3, + 0x2, 0x12, 0x1, 0x0, 0x0, - 0x3, + 0x2, 0x0, 0x0, 0x0, @@ -29891,219 +30122,223 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x6, - 0x6, + 0x1, 0x0, 0x0, - 0x1, + 0x2, + 0x0, 0x3, - 0x9, - 0x1, + 0x4, + 0x0, 0x0, 0x0, 0x1, + 0xf, 0x3, - 0x5, - 0xc, 0x2, + 0xe, + 0x9, + 0x0, + 0x1, + 0x6, + 0x0, + 0x1, 0x0, - 0x7, 0x0, 0x1, 0x3, 0x0, - 0x4, - 0x0, 0x0, - 0x2, + 0x7, 0x5, 0x0, - 0x0, 0x3, 0x0, - 0x1, 0x0, + 0xc, 0x0, + 0x3, 0x0, - 0x7, - 0x8, 0x4, - 0x9, - 0x1, + 0x6, + 0x5, 0x1, - 0x2, + 0x0, + 0x3, 0x0, 0x1, + 0x4, + 0x3, 0x0, + 0x3, 0x4, - 0x1, 0x0, 0x3, 0x0, - 0x12, - 0x6, - 0x2, - 0xa, 0x0, - 0x7, + 0x1, 0x0, - 0x2, + 0x6, 0x0, - 0x5, + 0x6, 0x0, 0x2, 0x0, + 0x2, + 0x3, + 0x3, 0x5, - 0x7, 0x1, - 0x1, - 0x9, - 0x3, 0x0, 0x5, + 0x5, + 0x3, 0x1, 0x1, - 0x2, - 0x6, - 0x2, - 0x3, + 0x1, + 0x1, + 0x4, 0x0, 0x0, 0x0, + 0x4, 0x1, - 0x0, 0x1, 0x2, - 0x5, + 0x0, 0x1, + 0x7, 0x0, + 0x2, 0x0, - 0x12, 0x0, 0x1, 0x0, 0x0, - 0x1, + 0x3, 0x0, 0x0, 0x1, 0x2, 0x0, - 0x0, 0x1, - 0x3, 0x1, + 0x3, 0x0, - 0xb, - 0x1, - 0x1, - 0x9, + 0x0, + 0x4, 0x2, + 0x5, 0x1, + 0x2, + 0x3, 0x0, - 0x7, 0x3, + 0x1, 0x0, 0x0, 0x1, - 0x2, - 0x2, - 0x3, + 0x6, + 0x1, + 0x1, 0x0, 0x0, 0x3, - 0x2, + 0x5, 0x0, 0x0, - 0x2, 0x0, - 0xb, + 0x1, + 0x3, 0x0, - 0x4, + 0x11, 0x0, - 0xe, - 0x6, + 0x2, + 0x5, + 0x1, 0x9, 0x1, 0x0, - 0x0, - 0x4, + 0x5, + 0x3, 0x2, + 0x1, 0x0, - 0x5, 0x0, + 0x6, 0x0, - 0x1, + 0x4, 0x0, - 0x8, - 0x1, + 0x2, 0x1, - 0x5, 0x0, 0x0, 0x0, - 0x6, 0x0, + 0x8, 0x0, - 0x1, 0x0, - 0x2, 0x1, 0x0, - 0x2, - 0x6, + 0x7, + 0x1, 0x0, 0x1, + 0x5, 0x0, + 0x1, 0x6, + 0x2, 0x3, - 0x1, 0x5, - 0x2, - 0x1, - 0x1, 0x4, - 0x6, 0x2, - 0xb, 0x1, - 0x0, - 0x2, + 0x1, + 0x7, 0x3, 0x2, + 0x3, 0x1, 0x0, 0x2, - 0x9, + 0x8, + 0x4, 0x1, 0x0, - 0x0, 0x1, - 0x0, - 0x0, 0x1, - 0x0, + 0x2, 0x0, 0x0, 0x1, + 0x2, + 0x0, 0x1, - 0x7, + 0x3, 0x0, - 0x4, + 0x0, + 0xb, 0x2, - 0x3, + 0x2, + 0xf, 0x0, 0x2, + 0x1, 0x0, 0x0, + 0x5, + 0x0, + 0x2, 0x1, 0x0, 0x0, 0x0, 0x1, - 0x1, 0x2, - 0x1, - 0x5, + 0x0, + 0x3, + 0x2, 0x0, 0x0, 0x1, @@ -30111,204 +30346,207 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x3, - 0x0, - 0x9, - 0x5, 0x2, - 0x1, - 0x1, 0x0, - 0x2, - 0x1, - 0x8, - 0x1, + 0x6, 0x2, 0x2, + 0x3, 0x1, + 0xc, 0x0, + 0x1, + 0x6, 0x2, 0x3, + 0x2, 0x1, - 0x0, + 0x2, 0x1, 0x3, + 0x2, + 0x3, 0x1, - 0x0, - 0x1, + 0x2, 0x1, 0x0, + 0x4, + 0x5, 0x0, 0x0, - 0x3, 0x0, 0x1, + 0x0, + 0x3, 0x4, - 0x5, - 0x1, - 0x4, + 0x2, + 0xb, + 0x0, + 0x2, 0x0, 0x0, 0x0, - 0x2, - 0x8, 0x1, - 0x4, 0x0, - 0x2, + 0x1, + 0x4, 0x2, 0x5, 0x2, - 0x3, + 0x7, + 0x0, + 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x5, 0x6, 0x0, - 0x2, - 0x2, - 0x0, 0x0, 0x1, + 0x4, 0x0, 0x0, - 0x1, 0x2, - 0x9, 0x0, - 0x1, - 0x2, 0x0, - 0x3, - 0x4, + 0x5, + 0x6, 0x1, - 0x4, + 0x0, 0x1, + 0x5, + 0x0, 0x0, 0x4, 0x2, 0x3, - 0x4, - 0x2, 0x1, + 0x0, + 0xa, + 0x3, + 0xa, + 0x2, 0x2, 0x1, 0x1, - 0x4, - 0x5, - 0x4, - 0x0, + 0x2, 0x2, 0x3, + 0x4, 0x2, - 0x0, + 0x1, 0x0, 0x2, - 0x6, + 0x1, + 0x7, 0x0, - 0x2, + 0x3, + 0x1, 0x1, 0x0, + 0x2, + 0x4, 0x1, 0x0, 0x0, - 0x1, - 0x9, + 0x2, + 0x6, + 0x3, 0x0, 0x1, 0x0, 0x3, + 0xa, 0x1, - 0x0, - 0x0, - 0x2, - 0x2, + 0x6, 0x2, 0x0, + 0x3, 0x0, 0x0, - 0x4, - 0x5, 0x0, + 0x6, 0x3, + 0x0, 0x2, - 0x2, + 0x6, + 0x3, 0x4, 0x0, - 0x1, - 0x0, - 0x3, + 0xa, 0x0, - 0x5, + 0x2, 0x0, + 0x4, 0x0, - 0x6, - 0x1, 0x0, + 0x4, 0x3, + 0x2, + 0x2, 0x0, + 0x8, 0x1, - 0x0, - 0x6, - 0x1, + 0x4, 0x4, 0x1, 0x1, - 0x2, + 0x1, 0x1, 0x2, + 0x1, 0x0, + 0x1, 0x2, - 0x2, - 0x0, + 0x1, 0x0, 0x0, 0x3, 0x0, - 0x5, - 0x2, 0x0, + 0x5, 0x1, + 0x0, + 0xa, + 0x6, 0x1, 0x2, - 0x0, + 0x4, 0x2, 0x1, 0x1, + 0x0, + 0x5, 0x1, + 0x3, + 0x3, + 0x0, + 0x0, 0x1, - 0x1, - 0x1, - 0xa, + 0x6, 0x5, - 0x1, + 0xc, + 0x0, 0x0, + 0xa, + 0x1, 0x1, 0x1, - 0x4, - 0x5, 0x0, 0x0, 0x2, + 0x0, + 0x4, 0x1, 0x2, - 0x4, - 0x0, + 0x3, 0x2, + 0x4, 0x0, - 0x0, - 0x3, 0x1, 0x1, - 0x1, - 0x1, - 0x4, - 0x0, - 0x2, - 0x0, 0x0, 0x0, 0x0, @@ -30319,22 +30557,23 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0x1, + 0x0, + 0x2, 0x0, 0x0, 0x4, - 0x4, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x2, + 0x2, 0x7, - 0x0, - 0x1, - 0x1, 0x1, + 0x4, 0x2, 0x1, 0x0, @@ -30344,70 +30583,71 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x5, 0x2, - 0x4, + 0x1, + 0x0, + 0x1, + 0xa, 0x0, - 0x2, - 0x5, 0x0, 0x0, - 0x1, - 0x1, 0x1, 0x2, - 0x7, + 0x2, + 0x1, 0x0, 0x0, + 0x2, 0x1, - 0x1, - 0x0, 0x0, 0x0, - 0x6, - 0x7, - 0x5, - 0xf, - 0x2, 0x0, + 0x4, + 0x4, 0x1, - 0x1, - 0x3, - 0x0, + 0x4, + 0x4, 0x0, 0x1, - 0x2, 0x1, 0x0, 0x3, + 0x0, + 0x4, + 0x3, 0x1, + 0x0, + 0x6, 0x1, - 0x3, + 0x0, 0x1, + 0x0, + 0x2, 0x1, 0x3, 0x0, 0x0, - 0x4, - 0x2, + 0x3, + 0x3, 0x0, 0x1, + 0x2, + 0x2, 0x1, - 0x1, - 0x6, - 0x1, + 0x3, 0x0, - 0x4, + 0x1, 0x0, - 0x4, - 0x4, + 0xb, + 0x7, 0x0, - 0x2, 0x1, 0x5, + 0x1, 0x0, 0x0, - 0x2, + 0x9, 0x1, - 0x2, + 0x3, 0x0, 0x0, 0x0, @@ -30415,165 +30655,168 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x1, 0x0, 0x0, - 0x3, - 0x0, - 0x0, + 0xe, 0x2, - 0x8, - 0x1, + 0x0, + 0x4, 0x3, + 0x1, + 0x6, 0x0, 0x0, - 0x3, + 0x4, 0x0, - 0x6, + 0x5, + 0x3, 0x1, - 0x4, - 0x2, - 0x6, + 0x0, 0x2, 0x1, - 0x2, + 0x0, + 0x1, 0x1, - 0x2, 0x3, - 0x7, 0x1, - 0x6, + 0x0, + 0x1, + 0x5, 0x1, + 0x2, 0x1, 0x0, + 0x1, 0x0, + 0x2, 0x1, - 0x3, - 0x3, 0x1, - 0x9, + 0x7, 0x1, - 0x3, - 0x8, - 0x0, - 0x2, 0x1, 0x2, + 0x6, + 0x4, 0x2, + 0x3, + 0x1, 0x1, - 0x6, - 0x0, 0x1, 0x0, - 0x2, 0x1, + 0x0, 0x1, 0x2, - 0x2, + 0x1, + 0x3, 0x0, 0x1, + 0x5, 0x0, - 0x4, 0x0, - 0x2, 0x6, - 0x3, + 0x2, + 0x2, + 0x1, 0x0, 0x2, 0x1, - 0x5, - 0x7, + 0x1, + 0x1, 0x2, 0x4, 0x2, 0x0, 0x0, 0x0, - 0x1, 0x0, - 0x8, + 0x1, 0x3, - 0x5, - 0x0, 0x2, + 0x0, + 0x4, 0x1, + 0x4, + 0x2, 0x0, 0x0, + 0x3, + 0x0, 0x2, - 0x6, - 0x1, - 0x1, - 0x1, + 0x0, 0x3, + 0x0, 0x1, 0x0, 0x1, - 0x2, + 0x1, 0x0, 0x0, 0x5, - 0x1, + 0x3, 0x1, 0x1, 0x1, 0x0, - 0x0, 0x1, - 0x0, 0x2, - 0x3, + 0x0, + 0x7, + 0x4, 0x0, 0x1, 0x1, 0x0, - 0x5, - 0x0, - 0x4, - 0x2, + 0x1, 0x0, - 0x3, 0x5, - 0x0, - 0x0, 0x1, 0x0, 0x1, - 0x1, - 0x2, 0x0, 0x2, - 0x1, - 0x1, + 0x0, 0x1, 0x2, - 0x0, + 0x2, 0x2, 0x1, - 0x0, - 0x4, 0x2, - 0x0, - 0x0, + 0x5, 0x2, 0x1, 0x1, 0x3, 0x0, + 0x3, + 0x1, + 0x0, 0x2, + 0x3, + 0x6, + 0x0, + 0x3, 0x2, + 0x0, + 0x5, + 0x0, + 0x4, + 0x4, + 0x3, 0x1, 0x0, - 0x1, - 0x5, + 0x2, + 0x8, 0x0, + 0x3, 0x0, - 0x4, 0x0, 0x0, 0x0, - 0x1, + 0x3, 0x0, - 0x4, - 0x2, 0x2, 0x2, + 0x1, + 0x1, 0x0, 0x3, 0x0, @@ -30582,133 +30825,135 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x0, - 0x5, + 0x1, 0x3, - 0x8, - 0x0, - 0x7, + 0x1, + 0x4, + 0x1, 0x2, 0x2, - 0x1, 0x2, 0x2, + 0x0, + 0x2, 0x4, - 0x9, 0x1, - 0x0, - 0x0, 0x1, 0x0, - 0x5, 0x2, 0x0, - 0x1, 0x0, 0x2, + 0x4, + 0x4, 0x1, + 0x2, 0x0, - 0x4, + 0x1, 0x2, 0x1, - 0x9, - 0x6, + 0x4, 0x2, 0x3, - 0x2, 0x6, 0x0, + 0x1, + 0x5, + 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, - 0x1, 0x2, + 0x1, 0x0, 0x0, 0x0, - 0x1, + 0x2, + 0x2, 0x4, - 0x1, 0x0, 0x0, 0x0, 0x4, - 0xc, - 0x0, 0x3, - 0x2, - 0x4, - 0x0, - 0x0, 0x1, - 0x0, - 0x0, + 0x1, + 0x9, 0x1, 0x0, 0x0, + 0x3, + 0x0, 0x0, - 0x1, 0x2, + 0x1, 0x0, - 0x8, 0x0, 0x1, - 0x2, 0x3, 0x0, - 0x0, - 0x1, - 0x4, 0x1, + 0x0, 0x2, - 0x1, 0x2, 0x1, + 0x0, + 0x0, 0x1, - 0x1, - 0x1, + 0x3, 0x2, - 0x1, 0x2, 0x0, - 0x0, 0x1, 0x1, 0x0, + 0x2, 0x1, + 0x5, 0x2, + 0x4, + 0x1, + 0x0, 0x2, + 0x0, 0x8, - 0x1, + 0x0, 0x3, 0x1, + 0x3, 0x1, + 0x2, 0x1, 0x1, - 0x4, - 0x3, 0x2, - 0x0, 0x1, 0x1, + 0x3, + 0x3, + 0x1, + 0x0, + 0x3, 0x1, 0x2, + 0x2, 0x1, 0x0, + 0x0, 0x1, - 0x1, - 0x3, + 0x4, + 0x0, + 0x2, 0x0, - 0x7, 0x0, 0x0, - 0x7, 0x1, + 0x3, 0x1, - 0x2, 0x0, + 0x1, 0x3, - 0x0, 0x1, 0x0, 0x2, @@ -30721,6 +30966,7 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, @@ -30733,18 +30979,18 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x1, - 0x3, + 0x5, 0x2, 0x0, 0x0, - 0x0, + 0x1, 0x2, + 0x8, 0x0, - 0x3, 0x0, 0x1, 0x0, - 0x1, + 0x11, 0x1, 0x0, 0x0, @@ -30755,2523 +31001,2567 @@ pub(crate) const COMBINING_MARK_SALT: &[u16] = &[ 0x0, 0x0, 0x2, - 0x3, - 0x0, - 0x0, - 0x0, - 0x0, 0x1, 0x0, - 0x4, - 0x2, 0x0, - 0x1, - 0x8, 0x0, 0x0, - 0x3, - 0x7, + 0x1, 0x0, 0x1, 0x1, 0x0, 0x1, 0x5, - 0x1, - 0x4, 0x0, 0x0, - 0x0, - 0x3, - 0x5, + 0x6, 0x3, 0x0, 0x2, 0x2, 0x1, - 0x3, - 0x1, 0x1, - 0x3, 0x5, 0x3, - 0x5, + 0x2, + 0x2, + 0x0, + 0x0, + 0x0, + 0x2, + 0x0, + 0x1, + 0x4, 0x1, 0x2, + 0x2, 0x0, 0x1, - 0x7, 0x2, - 0x3, - 0xc, - 0x8, 0x2, 0x1, 0x1, - 0x0, - 0x5, - 0x3, - 0x0, + 0xa, + 0x1, 0x1, 0x0, 0x2, - 0x0, - 0x3, + 0x2, + 0x1, + 0x4, + 0x6, + 0x1, + 0x1, + 0x1, 0x1, 0x0, 0x4, 0x1, + 0x0, 0x1, 0x0, - 0x9, 0x0, + 0x2, + 0xb, 0x1, + 0x8, 0x1, 0x1, - 0x2, 0x1, 0x0, 0x1, + 0x0, + 0x5, + 0x0, 0x3, + 0xf, + 0x1, + 0x1, 0x0, 0x1, + 0x2, + 0x1, 0x0, 0x1, 0x1, 0x1, - 0x0, 0x1, - 0x0, + 0x1, + 0x2, + 0x8, 0x1, 0x1, - 0x4, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, + 0x0, 0x1, 0x1, - 0x4, + 0x0, 0x1, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x1, 0x2, + 0x1, 0x0, 0x1, - 0x2, + 0x3, 0x0, ]; pub(crate) const COMBINING_MARK_KV: &[u32] = &[ - 0x0f9c, + 0xe01cb, 0x115dd, - 0x09fe, - 0x0d83, - 0x0d48, - 0x1da10, - 0x0ac1, - 0x08fb, + 0x0e3a, + 0x11441, + 0xe0134, + 0x11cb1, + 0x115bd, + 0x0faf, 0xe01dc, - 0x0368, - 0xe018b, - 0x0315, - 0x1cf7, + 0x11181, + 0x11934, + 0x11374, + 0x0823, 0xa67c, - 0x1c36, - 0x0b42, - 0x1da3f, + 0x0a4d, + 0xa952, + 0x1e003, 0x0e49, - 0xe0119, - 0x1c27, - 0x0593, - 0xa981, + 0x17b5, + 0x1074, + 0x2dfe, + 0xa8be, + 0x101fd, 0x102e0, - 0xa9b5, - 0x102f, - 0x1e021, - 0xaa2f, - 0x0fa2, - 0xe015e, - 0x1a63, - 0x06e3, - 0x0308, - 0x0f79, - 0x1ba4, - 0x112e7, - 0x16f70, - 0x1bf3, + 0x0fb1, + 0xa9ba, + 0x0c00, + 0x1daa6, + 0x05a2, + 0xfe26, + 0x0a41, + 0x07a6, + 0x0898, + 0x0b82, + 0x0afb, + 0x0fbb, + 0x1a7a, + 0x1cf1a, 0x16f6b, - 0x1e00a, 0xa675, - 0x1136a, - 0xfe0e, - 0x11ef3, - 0x1d243, - 0x11a97, - 0xa806, - 0x1daae, - 0x11831, + 0x1cf45, + 0xe012f, + 0xe014f, + 0x11c3b, + 0x2df7, + 0xa9bf, + 0xa8eb, + 0x1bc9e, 0x1a74, - 0x1cf10, - 0x111b7, - 0x1925, + 0x0eb8, + 0x302c, + 0x0c4d, + 0x064f, 0x105e, - 0xe0112, - 0x0656, - 0x1e006, + 0x0741, + 0x1da44, + 0x0b44, 0x1924, - 0x0f80, + 0x1da1d, 0x09c0, 0xfe2d, - 0xe015c, - 0x0a4b, - 0x11146, + 0x0330, + 0xe01c3, + 0x109d, + 0x0322, 0x1cf18, - 0x0c56, - 0x0346, - 0x1e023, - 0xe017d, + 0x0c02, + 0xe0128, + 0x17cb, 0x1acb, - 0x1da19, + 0xe01e3, 0xa802, - 0x1d242, + 0x16f72, + 0x11001, 0x11634, - 0x1da84, + 0x1da9b, 0x08ce, 0x0eb7, - 0x17dd, + 0x11041, 0x1a7b, - 0x0b4d, 0x1057, + 0xe0150, 0x1b6d, - 0x0fa9, + 0x0ce2, 0xa8e6, - 0x103b, + 0x1103e, 0x0619, - 0x073a, - 0x030d, - 0x1daa7, - 0x1cf04, - 0x112df, - 0x0f7a, + 0x11081, + 0x0fa3, + 0x114c3, + 0x11a90, + 0x082c, + 0x11173, 0x1a66, - 0x0f78, - 0x065d, + 0x1e8d4, + 0x1d16e, 0x111b8, - 0x115af, - 0xa92a, - 0x0982, + 0x1934, + 0x1cf0c, + 0xe01ce, 0x1cf39, - 0x115b5, 0x111be, - 0xa8b6, + 0xe01d2, + 0x1da08, 0xe0141, 0x11236, - 0x11180, - 0x1d165, - 0x0741, + 0x110c2, + 0xfe25, + 0x16b36, 0x0657, 0x0749, - 0x0486, - 0x114bd, - 0x1a75, - 0x08de, + 0x0311, + 0xe01c4, + 0x20d3, + 0x1da21, 0x1be9, - 0x07f1, - 0x1e02a, + 0x1cf0e, + 0x16f5d, 0x1d182, - 0x1dea, - 0x0822, + 0x1cf41, + 0x08fe, 0xfe05, - 0xa8ec, - 0x1036, - 0x115ba, - 0x1ba1, - 0x116b0, + 0x11a59, + 0x1de6, + 0x1ac6, + 0xe0120, + 0x11a38, 0x110b7, 0x1dec, - 0x11a8f, - 0x1e8d1, - 0xaa2b, - 0x0f8e, - 0x1cf03, - 0x1dc7, + 0x0351, + 0x0309, + 0x1dcd, + 0x115bc, + 0x114b5, + 0x16f80, 0x11182, - 0x2de9, + 0x16f6e, 0x11caa, 0xe0198, 0x0dd8, - 0x10a39, + 0xa80b, 0x0eca, - 0x0363, + 0x1df0, 0xa8c5, 0x0fbc, - 0x0a4d, + 0x1136c, + 0x1064, 0x1c29, - 0xa8e2, - 0x0fb4, - 0x1ab9, + 0x114c0, + 0x1030, 0x1abd, - 0x11935, - 0x102d, - 0x1acc, - 0x0654, + 0x0e4c, + 0x0a02, + 0x1143d, + 0x1e4ed, + 0x20d8, 0x11a04, 0x1cf26, 0xe0116, 0x0acc, 0x10f4d, 0xaaed, - 0xe012e, - 0x17cc, - 0x0825, - 0xabe4, + 0x07aa, + 0x0902, + 0x11442, + 0xe012c, 0x0ac7, - 0xe0122, - 0x0615, - 0x16f72, - 0xe01c7, - 0x110b3, - 0x0820, + 0xaabe, + 0x1921, + 0x11c9c, + 0x11f3e, + 0x11102, + 0x0953, 0x1da5b, - 0x180f, + 0xa8e9, 0x11044, - 0x1cf45, + 0x16b33, 0x08e3, 0xe0158, 0xa826, - 0x2de4, - 0x06d6, - 0x1dd3, - 0x0f37, - 0xe0139, - 0xe0113, - 0x1a71, + 0x11f41, + 0x0f19, + 0x1058, + 0xe01ef, + 0xe011d, + 0x17bb, + 0x1171f, 0x11232, + 0x1cd7, 0x0364, - 0xe016d, - 0x0c81, + 0x1c35, 0x0a3f, - 0xfe0a, - 0xe01bf, - 0xaab7, - 0x11937, - 0x1e131, + 0x1a5a, + 0x13453, + 0x11a55, + 0x1def, + 0x0342, + 0x0b4c, 0xe01ea, - 0x05bc, - 0xe0149, + 0x1cf32, 0x1082, - 0xfe08, - 0x11357, + 0x0b63, + 0x1ac5, 0x11635, - 0x1da30, + 0x1a69, + 0x0487, 0xe0164, - 0x1a67, 0x1da33, - 0x1ab1, - 0x11c39, + 0xe0107, + 0x0bc0, 0x11c3e, - 0x0e3a, - 0xabe7, + 0xe01c1, + 0x1daae, + 0x0fa1, 0x11c95, - 0x11233, - 0xa8ee, - 0xaa2e, + 0xa671, + 0x1c36, + 0x1b71, 0x1b80, - 0x11a59, - 0xfe04, - 0xe01c2, - 0x1da34, + 0x033c, + 0x20d5, + 0x116ae, 0x1da54, - 0x10f4b, + 0x0819, + 0x1e01f, 0x0301, - 0x16b30, - 0x11a91, - 0x16af3, + 0x119dc, + 0x11726, + 0x031c, 0x17b8, 0xe015b, - 0x0d63, - 0x112e3, + 0x1dd0, + 0x0f9e, 0x0f94, 0x0f7f, 0x11d32, 0x11a8b, 0x1dda, - 0xa9be, - 0x1cf42, - 0x119d7, - 0x1ddd, + 0xe017a, + 0x116b6, + 0x11c9b, + 0x0f8e, 0x11720, - 0x11039, - 0x081c, + 0xaa7d, + 0x10f82, + 0xa9b6, 0x0744, - 0xe0140, - 0x09c1, - 0x11231, - 0x110ba, + 0x11f01, + 0x16f73, + 0x11632, 0x0e38, - 0x110b4, - 0x119da, + 0x0bcc, + 0x11f37, + 0x07f1, 0x0340, - 0x0ecb, + 0x116b3, 0x11002, - 0x2dff, - 0x0331, + 0x1e946, 0x1cf1d, - 0x103d, + 0x1da49, 0x1da2e, - 0x1037, - 0x1ab6, - 0x0337, + 0x1b3e, + 0xe010a, + 0x09e2, 0x1cf2d, - 0x11a90, - 0x11d3c, + 0x0b03, + 0x094f, 0x11373, - 0x1133e, + 0x13449, + 0x11838, 0xaa36, - 0x20e4, + 0x0ccc, 0xe01b0, 0x07ad, 0x1df1, 0x17cd, - 0x11237, + 0x13455, 0x0ae2, - 0x11ca5, - 0x07ef, - 0x1073, - 0x11340, - 0x081d, - 0xe018f, - 0x17c7, - 0x1aba, - 0x1933, + 0x1cf3c, + 0x1cf27, + 0x16f85, + 0x1e00a, + 0x11c9f, + 0x1d168, + 0x119de, + 0x11932, + 0x1dc0, 0x110b0, - 0x11a56, - 0x1da03, - 0xe01cd, - 0x0367, - 0x036d, + 0x1e948, + 0x1da27, + 0x10378, + 0x0310, + 0x0df2, 0x11038, - 0x11830, + 0x114b4, 0x093a, 0x1ce0, - 0x1c32, - 0x0c3f, - 0x1da50, + 0x094c, + 0x16f64, + 0xa8ec, 0x111bf, - 0x2df7, - 0x1cda, - 0x1ba2, - 0x0b02, - 0x0735, + 0x11133, + 0x1bec, + 0x1da35, + 0xa94d, + 0x1cf00, 0x032f, - 0xe014c, + 0xa928, 0x05c7, - 0x20de, - 0x1bee, - 0x0599, - 0xe0114, - 0xa94d, - 0x11a34, - 0x0598, - 0xe01d7, - 0x081f, + 0x1a19, + 0x0354, + 0x11942, + 0x1cf34, + 0x07b0, + 0x0afa, + 0x1c32, + 0x1da0d, + 0x1cf25, + 0x11d8b, 0x116b4, - 0x1e01c, - 0x10ae6, + 0x1ac7, 0xa9bc, + 0x1d18a, 0xfe21, - 0x20e8, 0xe0183, - 0x0c62, + 0x07ac, + 0x13450, 0xe012d, 0x119d6, - 0x07ae, + 0x1de1, 0x0cbe, - 0x1da44, - 0x1cf0c, - 0x089e, - 0x1a7c, + 0x065b, + 0x0316, + 0x1a59, + 0x1e004, 0xa670, - 0x11a05, - 0x06ed, - 0x1cf1b, - 0x20d7, - 0x16f5a, + 0x1da4b, + 0x17dd, + 0x1e008, + 0xe0191, 0x0f18, - 0x085b, - 0x119d2, - 0x09be, - 0x11a38, - 0x17c6, - 0x0cd6, - 0x1dee, - 0x17d3, - 0x1a1b, + 0x1143f, + 0xe0190, + 0xabe3, + 0x1da4d, + 0x0cd5, + 0x0dda, + 0x0d63, + 0x0e35, + 0x1cf1e, + 0x1da1e, 0xe01e8, - 0xe01ab, - 0x1ac6, - 0x2de1, - 0x17d2, - 0x11a99, + 0x114bf, + 0x0746, + 0x1cd1, + 0x1da75, + 0x1e2ec, 0x0596, - 0x08f1, - 0x11cb3, + 0x1dfa, + 0x0334, + 0x16f77, 0x09e3, - 0x0b43, - 0x0f7c, + 0xe019f, 0x17ba, - 0x1d185, + 0x0ac1, 0x1de3, 0x1e130, + 0x1ba1, 0xe01a8, - 0xa8b9, - 0x1939, - 0x0f71, - 0x11728, - 0x116ae, + 0x1ac3, + 0x11c38, + 0x111b3, + 0x0357, + 0xe012a, 0x116ac, - 0x0ce3, - 0x1c2c, + 0x0f76, 0x119e0, - 0xe0106, - 0x1b41, - 0x2df9, - 0x033e, + 0x1a72, + 0x0fa2, + 0x1772, + 0x05b3, + 0x1df7, 0x11cb6, - 0xfe29, 0x1da63, - 0x1ce6, + 0x16f70, 0x1cf8, - 0x2def, - 0x1da32, - 0x16f78, - 0x0b4c, - 0xa950, - 0x0611, + 0x0747, + 0x112e4, + 0x1e8d3, + 0xaa31, + 0x0cc3, + 0xfe0d, + 0x11a37, 0x1dcb, 0x0317, - 0x1928, + 0x1dc8, 0x1c2b, - 0x09cc, - 0x17c4, - 0x0f99, - 0x119d5, + 0x0eba, + 0x085a, + 0x11835, + 0x036c, 0x05af, - 0x108b, - 0xe01da, - 0xe01d8, + 0x1143b, + 0x1da10, + 0x11c9e, 0xa8e1, - 0x11832, - 0x0591, + 0x035c, + 0x1b03, 0x0366, 0x05c4, - 0x10f50, - 0x1d17d, - 0x10a05, + 0x1cf0d, + 0x11a8a, + 0xe01c8, 0xe01a9, 0x06e1, - 0x0319, - 0x0e31, - 0x06df, - 0x20e7, + 0xfe24, + 0xa926, + 0xa824, + 0xa92d, 0x111bc, - 0x081e, - 0x1072, - 0x1da75, + 0xabea, + 0x0afc, + 0x1ded, + 0x065a, 0x0952, - 0xe01d0, - 0x1da27, - 0x115c0, - 0x1e009, - 0x0334, - 0x11127, + 0x1da5d, + 0x0956, + 0x1ce1, + 0x11933, + 0x1d167, 0xa69f, + 0x0d3e, 0x110b5, - 0xe0196, - 0x11073, + 0x116b2, 0x1e017, - 0x08d2, + 0xe013e, + 0x1d180, 0x1da67, 0xaaeb, - 0x0abe, 0x1dd1, + 0xaab8, 0x1cf22, - 0x20dc, - 0x0ae3, + 0x2cf1, + 0x06d7, 0x1930, - 0x20e9, + 0x1da34, 0x0326, 0x1032, - 0x0f76, - 0xe01ef, + 0x1be7, + 0x09c4, 0x1da57, - 0x108a, - 0x0a48, + 0x1136a, 0x1daa1, - 0x08f9, - 0x0d3f, + 0xe0179, + 0x0cc1, + 0x11129, 0x10f83, - 0x11ca4, - 0x11368, - 0x05b2, - 0x0acd, - 0xa67b, - 0x11130, - 0x1da0c, - 0x11001, + 0x1034, + 0x0a82, + 0xa951, + 0x1344b, + 0x2d7f, + 0x09c7, + 0x11f39, + 0x11f34, 0x16f5b, - 0x1bf2, - 0x0f90, + 0x0bbe, + 0x031a, 0x11d8e, - 0x1da11, - 0xe01db, - 0x11344, - 0x1da4f, - 0x1e00c, + 0x1e949, + 0x1ab6, + 0x1b40, + 0x1d16d, + 0x0d82, + 0x1134c, 0x033f, - 0x11369, 0x11d3f, - 0xa928, - 0xe0142, + 0x0dd6, + 0x11445, 0x1a58, - 0x16f65, - 0x11d93, - 0x11a36, - 0x16f80, - 0x309a, - 0x036c, - 0x1a73, - 0x1112b, - 0x1a5e, + 0x08de, + 0x1ac2, + 0x1b34, + 0x11ef4, + 0x11d35, + 0xe0195, + 0x1c37, + 0xa9e5, + 0xa980, + 0xe0185, 0xe018e, - 0x119df, - 0x1dc0, + 0xa8ba, + 0x193b, 0x1da3b, - 0xe0187, - 0x11c93, - 0x0d4a, + 0x094b, + 0x10f48, + 0x0d3c, 0x1dc9, - 0x1cf37, 0x11046, - 0x2df1, - 0x11633, + 0x1926, + 0x05b0, + 0x0c55, 0x11c3c, - 0x0304, 0x08e6, + 0x0617, 0xe0109, - 0xe0181, 0x1e134, 0xfe2c, - 0x1cd8, - 0x0324, - 0x081b, - 0x1da1b, - 0x16af0, - 0xaab0, - 0x05ac, + 0xabe6, + 0xfe0f, + 0x1df6, + 0x1ac9, + 0x103c, + 0x093c, + 0xe0154, + 0x0ddb, 0x1cf13, - 0x111cf, + 0x114c2, 0x20ea, - 0x0fa1, + 0xe01de, 0x06ec, - 0x1a77, - 0x112e1, - 0x1beb, + 0x105f, + 0x1d16f, + 0xfe27, 0xe01c5, - 0xe0167, - 0x16f77, - 0x0afa, - 0x1ac7, + 0xe0182, + 0x05b5, + 0xe0104, + 0xa9be, 0x1e002, 0x0cbf, 0x1886, - 0xe0169, - 0x0fab, - 0x0a51, - 0x10a3f, + 0x1b82, + 0x0fc6, + 0x032a, + 0x0670, 0x0981, 0x0595, - 0x05aa, - 0x06db, + 0x08df, + 0x08ca, 0x1715, - 0xa8bc, + 0x0b41, 0x0658, - 0x11a37, + 0x1dc2, 0x065c, - 0x1da46, + 0xe0130, 0x1bac, - 0xe011b, + 0x1c24, + 0x20de, 0x111bd, - 0x1133c, - 0x08f0, - 0x08cf, - 0x20d6, - 0x16f52, - 0x1ced, - 0xe0127, - 0x0d82, + 0xa8b4, + 0x0486, + 0x0302, + 0xe0102, + 0x1145e, + 0x1da3d, + 0x1cf11, 0xe0151, - 0x05bd, - 0x07a7, + 0xe01b4, + 0x05b7, 0x1ab4, - 0x1712, - 0x11d95, - 0x0d57, + 0x1ba2, + 0x1d1ad, + 0x1182d, 0x1d18b, - 0x11d3a, - 0x0dd9, - 0x1e014, - 0x11ef6, - 0x115bd, + 0x17bd, + 0x1cf1f, + 0x0ac9, + 0x11ca7, + 0x1deb, 0x1d17b, - 0xa8e5, - 0x05a0, - 0x0fa7, - 0x089f, - 0x08fa, - 0x10ae5, + 0x1da68, + 0x0ecc, + 0x1c30, + 0x116b5, + 0xa8e7, + 0x1112a, + 0x11a3d, 0x1136b, - 0x11181, - 0x11070, - 0x16f87, - 0x1143e, - 0x0b01, + 0x05c5, + 0x11363, + 0x08f6, + 0x1ab0, + 0x1163d, 0x0c82, - 0x1da0b, + 0x1cf40, 0x0f3f, 0xe0100, 0x0dd3, - 0x0fb7, - 0xe0182, + 0x1035, + 0x1a76, + 0x1daa4, 0x0314, - 0x0d42, - 0x08e1, - 0x0b63, + 0x10f46, + 0x16f79, 0xe0159, - 0xaa4d, - 0x06dc, - 0x1d166, - 0xe0155, - 0x1da26, + 0x0f9c, + 0xe013c, + 0x1183a, + 0x1e000, + 0x1da41, + 0x11a47, 0x0733, - 0x0d4d, - 0x16f62, - 0x108c, + 0x1da60, + 0x11440, 0x1b72, 0x07af, + 0x0f73, 0xa827, - 0x089d, - 0x1cde, - 0x1a79, + 0xe01e9, + 0x11a96, 0x1e012, - 0x094f, - 0x115be, - 0x10f4c, + 0x11830, + 0x1da46, + 0x2de6, + 0x1cdb, 0x0616, 0xfe01, - 0x115b8, 0x11300, 0x0951, - 0x1b6e, - 0x1dcd, - 0x1e004, - 0x08d8, - 0x11631, + 0x0abc, + 0xaa29, + 0x1931, + 0x1da17, + 0x1a6d, 0x11723, - 0x1cf16, - 0xfe2e, - 0x1c2f, - 0x064f, - 0xaaec, - 0x08d4, - 0x11c31, - 0x0bc0, - 0xe019e, - 0x11d34, - 0x0746, - 0xe01d5, - 0x11caf, - 0x0fa8, - 0x1b44, - 0x1de8, + 0x10f4a, + 0xe011e, + 0x06e4, + 0x0343, + 0x1cd2, + 0x20d9, + 0x1163e, + 0x05a8, + 0x1122e, + 0x1de0, + 0x103e, + 0x102d, + 0x1da0b, + 0xaac1, + 0x16f7c, + 0x20da, + 0xa948, 0xa67a, - 0x1cf2a, - 0x11000, - 0xe0103, - 0x06d7, - 0x030c, - 0x1ddf, - 0x11a3e, + 0x1cf23, + 0xaa35, + 0xa8bc, + 0x1da55, + 0xe01b3, + 0x16f57, + 0x10a05, 0x1172a, + 0x1a77, 0x116b1, - 0x1de1, - 0x11102, - 0x1d189, - 0xfe24, - 0x0983, - 0xe012a, - 0x17ce, + 0x1dc1, + 0x1cf06, + 0x0a75, + 0x16f75, + 0x11d45, + 0x1b3c, + 0x1037, 0xe01be, - 0xabea, - 0x11c34, - 0x082d, - 0x1e8d4, - 0xe0121, - 0x1baa, + 0xe01a5, + 0x11833, + 0x0954, + 0xfe0b, + 0x16f6f, + 0x10eff, 0x064e, - 0x1df0, - 0x05b3, - 0x0afb, - 0x08ec, + 0x0320, + 0x1dcf, + 0xfe29, + 0x09be, 0x0f35, - 0x1b35, + 0x0cd6, 0x0489, - 0x08cc, + 0x0d4a, 0x17b7, - 0x2df0, 0x1dfc, - 0x111b3, + 0xabe8, + 0x1dce, 0x1b6c, - 0x0ecc, - 0xe019a, - 0x0a41, - 0x1d16e, - 0x0d62, - 0xe010a, - 0x032d, - 0x059f, - 0x1da59, - 0x1a56, - 0xe0173, + 0x0ddf, + 0x16f90, + 0x11633, + 0x11a94, + 0xa94f, + 0x11837, + 0x0d00, + 0x1d171, + 0x108b, + 0x0732, + 0x11a99, 0x1d186, - 0x11cb4, + 0x0303, 0x10377, - 0x11a3c, - 0x0fae, + 0x114b3, + 0x1e015, 0x0f9f, - 0x11235, + 0x0acd, 0xa8c1, - 0xabe8, + 0x1daa3, 0x11c98, - 0x112e4, + 0x115ba, 0xe017b, - 0x11a5b, - 0x1dc3, - 0x1acd, - 0xa8c2, - 0x16f69, - 0x1dde, - 0x0fb2, - 0x11942, + 0x0bc7, + 0x11368, + 0x08e7, + 0x0ae3, + 0x0c4c, + 0x1cf37, + 0x1cf3d, + 0x112e3, 0x1bf1, - 0x1cf21, - 0xe0145, + 0x112e2, + 0x1d170, + 0xa9b3, 0x0362, - 0x114bf, 0x0f84, 0xe013f, 0x0483, - 0x11835, - 0x1732, + 0x05b2, + 0xe0160, 0x11cae, 0x10f4f, + 0x16f61, 0xaaef, - 0x11041, - 0x1da0e, + 0xe01d8, 0x11a06, - 0x05c2, - 0x1143b, - 0x2cef, - 0x1cf0d, + 0x0339, + 0x11636, + 0x114b2, + 0x11c2f, 0x0b3e, - 0x11ca2, + 0x1163a, 0x10f49, - 0xa8e4, - 0x0650, - 0x0e36, - 0xe01a4, + 0xa8ea, + 0x0c41, + 0x0655, + 0x11234, 0x032c, - 0x11c9a, - 0xe0172, + 0xe01af, + 0x1d17f, 0x0d3b, - 0xa824, + 0x1da23, + 0xfb1e, 0x0ac2, 0x1bad, - 0x0c4b, + 0x1163c, 0x0f95, - 0x1714, + 0xa8bf, 0x1cf28, - 0x0fb6, + 0xe0139, 0x10f85, - 0xaaf6, - 0x07b0, + 0x1abb, + 0x1da29, 0x1cf4, - 0x1cd7, - 0x11c33, + 0x06e8, + 0x1e8d1, 0x0b3c, - 0xaabe, + 0xe011c, 0x1e013, - 0x1cf43, - 0x16f5d, - 0x0ec8, - 0x0dcf, - 0x1b00, - 0x1163d, + 0x1ace, + 0x05ab, + 0x10ae6, + 0x20e1, + 0x1cf3f, + 0x1dfb, 0x08cd, - 0xe0133, - 0x1a1a, + 0x11c36, + 0x073b, 0x082a, - 0x1ac0, + 0x17b6, + 0x0e48, 0x20ee, - 0x0dde, - 0x17c5, - 0x115bc, - 0x0349, + 0x11937, + 0x1cdf, + 0xe0162, 0x1cf3a, + 0x08d9, 0x11637, - 0x1cdd, + 0x2dfb, 0xe018c, - 0x0fb0, - 0x114be, - 0x094b, - 0x119d3, + 0x1df9, + 0x11073, + 0x135f, 0x08d7, 0x1773, - 0x302b, - 0x0f81, + 0x08e0, + 0x16af3, 0x0610, - 0x1cf2b, + 0xe019c, + 0x0901, 0x1e018, - 0x1171d, + 0x1e027, 0x1da2c, - 0x11367, + 0x0b43, 0x180c, - 0xe01a5, + 0x1753, 0x114b1, 0x115b2, - 0x1daa5, - 0x1134c, - 0x0bd7, - 0x1dd8, - 0xe0189, - 0x1cf09, + 0xabe7, + 0x031d, + 0x0c01, + 0x111b4, + 0xe01e2, + 0x08f5, 0x11cb5, 0x0cbc, - 0x0dd6, - 0x082b, - 0xe0110, + 0x1a1a, + 0x1da14, + 0x1dc7, 0x1a18, - 0xfb1e, - 0x0949, + 0x0d62, + 0x0742, 0x1da58, 0x111b9, 0x11a35, - 0x08ff, - 0x11436, - 0x11c36, + 0x115b9, + 0x0369, + 0x05a6, 0xa8f0, + 0xe0169, 0x116ab, - 0x031a, - 0x05ba, - 0xabe3, - 0x110b8, - 0x0bbe, + 0x0ecb, + 0x0599, + 0x1da59, + 0x2dec, 0x11c99, - 0x1ba9, - 0xa983, + 0x0358, + 0x11128, 0xa8b5, - 0x1ac9, + 0x1cf17, 0x16af2, - 0x036e, - 0x1b3d, - 0xfe0f, - 0x1cf30, - 0xe014b, + 0x1133c, + 0x0711, + 0x11369, + 0x1a70, + 0x1062, 0xa94e, - 0x1122d, + 0x1da11, + 0x059c, 0x0fb9, 0x11d42, - 0x11a51, - 0x1ac4, + 0xa92a, 0x11d91, - 0x0cc8, + 0x1aba, 0x1a6b, + 0x1122c, 0xe0136, - 0x112e9, - 0x17c9, - 0x16f92, - 0x11a07, + 0x1086, + 0x1067, + 0xe01a2, + 0x0afd, 0x1da15, - 0x1e010, - 0xe01df, - 0x1b04, - 0xe0146, - 0x11938, - 0x116ad, - 0x11c94, - 0xa679, + 0x16f83, + 0x1da2a, + 0x1cf29, + 0x1da28, + 0x1b70, + 0x17b4, + 0x0ebb, + 0x0947, 0x11371, - 0x05c5, + 0x1a1b, 0x0361, - 0x10f47, + 0x11d34, 0x1cd4, - 0xe0143, - 0x1e029, - 0x1e2ec, + 0x1cf3e, + 0x11935, + 0x11130, 0x1a5b, 0x11134, - 0x05bf, - 0x0355, - 0x102c, + 0xe0149, + 0x11446, + 0x0363, 0xe0180, - 0x1cf34, + 0xfe0c, 0x11c35, + 0x0eb6, 0x0fa4, - 0xa825, - 0x1dcc, - 0x2de7, + 0x0fa0, + 0x08ff, 0x114ba, - 0x05b9, - 0x0f7d, + 0x11439, + 0xe0170, 0x0d40, 0xe015f, - 0x1183a, + 0x06dc, 0x111c9, 0x0c48, + 0x1734, 0x1da43, - 0x0323, - 0x20d2, + 0xaa2c, 0x0ecd, - 0x0333, - 0x1b3a, - 0x1be8, - 0x18a9, + 0xe01b1, + 0x1e023, + 0x16f60, + 0x089d, 0x0e4d, + 0x07ee, 0x0312, - 0xe01d2, - 0x1da08, + 0xa8c4, 0x034c, 0x1103c, 0x0829, - 0xe012c, + 0x1cf42, 0x1daa2, 0x11729, - 0x16f81, + 0x0957, 0x119d1, - 0x11ca3, + 0x1dc6, 0x1cf08, - 0x0ac3, - 0x11838, + 0x1abf, + 0x059e, + 0x0d81, 0xe01d3, 0x1da09, - 0x0f7e, + 0x1d17d, 0x112e5, - 0x0c02, + 0x11d90, 0x1e01e, - 0x1cf9, 0x1e135, - 0x1b42, + 0x030f, 0x110b2, - 0x0659, + 0x111ce, + 0x17c6, 0xa8e3, 0x16f66, 0x0a3e, - 0x1bef, - 0x0732, - 0xe011d, + 0x1e132, + 0xe0155, + 0x1e4ee, 0x07ab, - 0x2de3, - 0x05bb, - 0xaab3, - 0xa9b3, + 0x20ed, + 0x0963, + 0xe01d0, + 0xe01bf, 0x08d3, - 0x16f84, - 0x1e028, - 0x08f6, + 0x1cde, + 0x1ba4, + 0x0ce3, 0x11437, - 0x114b0, - 0xe010d, - 0x08e7, - 0xe0186, + 0x0b02, + 0x0c40, + 0x08f4, + 0x11f38, 0x1088, - 0x0d81, - 0x0d03, - 0x073c, - 0x11374, - 0x036f, + 0xa950, + 0x1bee, + 0xa881, + 0xe01a0, + 0x0900, + 0x1e8d6, 0x1171e, - 0x0b3f, 0xe01b5, - 0x1da2d, + 0x05ac, + 0xe0125, 0x20ef, - 0x11c9c, - 0x2deb, + 0x05b6, + 0xe01a7, 0x11d8d, - 0x1063, - 0x11c9b, - 0x1daa6, + 0xe017c, + 0x0ccb, 0x1b3f, + 0x20eb, 0x0a3c, - 0x0740, + 0xe0157, 0x1a57, - 0x1d244, + 0x1d1ac, 0xa8ef, - 0xe016e, + 0x0598, 0x112e0, - 0x1da29, - 0x20df, + 0xe012b, + 0x0f80, 0x1ddc, - 0x1934, - 0x0e4e, + 0x034b, + 0x1a68, 0xa6f0, 0x059b, 0x1b81, - 0x11636, + 0x16b32, 0x0faa, 0x109c, 0x034d, - 0x1da45, - 0x1cf3f, - 0x16f6e, - 0x10a03, + 0xe010c, + 0x0319, + 0x1925, + 0x11a3b, 0x031b, - 0xe014a, - 0x11a03, + 0x1a64, + 0x08d4, 0xa677, 0x0b62, - 0x1e003, - 0x193b, + 0x11045, + 0x0acb, 0x1112f, - 0x0dca, - 0x1885, - 0xa9b7, - 0x11c30, + 0xe01d4, + 0x1da0a, + 0x115af, + 0x0613, 0xaaf5, - 0x0c01, - 0x0f8f, - 0x1103e, + 0x08f1, + 0x11a56, + 0x0bbf, 0xaa4c, - 0x1e947, + 0x1037a, 0x1dff, - 0xe0175, - 0x2df5, + 0x0abe, + 0x302e, 0x1b39, - 0x1da14, - 0x1136c, - 0xe01de, - 0x302a, - 0x2de5, - 0xe01b9, - 0x1a6d, - 0x1cf23, - 0x2dfb, + 0x1da9d, + 0x1a6a, + 0x11ef6, + 0xe01aa, + 0x112ea, + 0x1e01c, + 0x1039, + 0x05b8, + 0x11c34, + 0x20db, 0x11230, 0x0c83, - 0x0bc6, - 0xe0150, - 0xe016f, - 0x193a, - 0x0e39, - 0x1068, - 0xe017f, - 0x10d27, - 0xe01a3, - 0x20e5, - 0x0afc, - 0x1cf07, - 0x1da40, + 0x1036, + 0x0948, + 0x119db, + 0xe01ed, + 0x1c31, + 0x10a3f, + 0x1ab5, + 0x11d94, + 0xa983, + 0x0ccd, + 0x17c4, + 0x11931, + 0x11f42, 0x1c28, - 0x0cc3, - 0x0954, - 0xabec, + 0x1da32, + 0x11145, + 0x302a, 0xe0135, 0x0ac8, 0x0cc7, - 0x1ac3, + 0xe01ad, 0x1da00, 0x1b37, - 0x0e35, + 0x036f, 0x11d43, - 0xe01ee, - 0x1143d, + 0x116ad, + 0x11ef5, 0xa8ff, - 0x2cf1, - 0x1cf3d, - 0xa82c, + 0x1da19, + 0x030a, + 0x09cc, 0x10eac, 0x11d8c, 0x11a0a, - 0x0dd0, - 0x20d9, + 0xaab4, + 0xfe2f, 0x0ac0, 0xe0194, 0x065f, - 0x11940, - 0xaa31, - 0x0ce2, - 0xe0190, + 0x11a07, + 0xe015a, + 0xe0173, + 0x1c27, 0x17c8, - 0x10f4a, - 0x2dfd, - 0x0ac9, - 0x11080, - 0xa671, - 0x1193c, + 0x0820, + 0x065d, + 0x0bcb, + 0xe01dd, + 0x11343, + 0x1e009, 0x0941, - 0x0c3c, + 0x1752, + 0x1ce4, 0x0329, - 0x11d8a, - 0x0fb3, - 0x17b4, - 0x1a5d, + 0x1713, + 0xe0118, + 0x119da, + 0x1da6a, 0x08f2, - 0x1df6, - 0x08d5, + 0x0f71, 0x16f51, + 0x089e, 0x2df8, - 0x302c, 0x10a0e, - 0xe01c0, - 0x2cf0, - 0x16f55, - 0x1de7, - 0x10f48, + 0x2de4, + 0xaa2a, + 0xe0192, + 0x0dd2, + 0x0c81, + 0xe01c7, 0x10a38, 0xe0176, - 0x16f60, + 0x20e9, 0xe019d, - 0x1cd5, - 0x0d44, - 0x111ce, - 0x0bbf, - 0x1cf44, - 0x0345, - 0x11a96, - 0x1931, - 0xe01c1, - 0x116b5, + 0x20e7, + 0x032e, + 0x1e01d, + 0x1cf24, + 0x0731, + 0x0ac4, + 0xe017d, + 0x16f7b, + 0x1c34, + 0x115b5, 0x0306, - 0x08ea, + 0x16f76, 0x0bc8, - 0x0fba, + 0x061a, 0xa949, - 0x0fa6, - 0x0bca, + 0x08f0, + 0x11cb2, 0x1133f, - 0x11301, - 0x0738, - 0x1e944, - 0xa672, + 0x111b5, + 0x11344, + 0x082d, + 0x1dd3, + 0x1d172, 0xe010b, - 0x114c1, - 0xfe2a, - 0x1daa9, - 0x0fad, - 0x11ca9, - 0x0bc1, - 0x1ac8, - 0x1163a, + 0x2df6, + 0x06e0, + 0x1107f, + 0x16f74, + 0x11d47, + 0x11943, + 0x16b30, 0x11a01, 0x0d4b, 0xaa7b, - 0xe012b, - 0x0823, - 0x0ccc, - 0x16f56, + 0x1da22, + 0xe01ec, + 0x13447, + 0x1cf0b, + 0x11c9a, 0x2dfa, - 0x030a, + 0xe01c2, 0x11724, - 0x114c3, - 0x08ed, - 0x115b4, - 0x0487, - 0x0903, - 0x1dc2, + 0x0485, + 0x11a52, + 0xe01cd, + 0x1da03, + 0xa8bb, 0x11722, - 0x16f83, - 0x11d40, - 0x064b, + 0x11930, + 0x06ed, + 0x0615, 0x1daa8, + 0xe0132, 0x1cf33, 0x11042, - 0x05b4, + 0x1cd8, 0x1a17, - 0x0352, - 0x11c3f, - 0x1112a, + 0xe0171, + 0x089f, + 0x119dd, 0x1da5e, - 0x11c3b, - 0x17d1, - 0x1ab0, - 0x11a5a, - 0x08e4, + 0x1d1aa, + 0x1da24, + 0x0b01, + 0x1a5e, + 0x11d3d, 0xe0165, - 0x11cac, + 0x0367, 0x110b6, - 0x1da49, + 0x11074, 0x1cf38, - 0x1cf32, - 0x1df9, + 0x11237, + 0x1df3, 0x1de5, - 0xa823, - 0x114bc, - 0x0f75, + 0xe0140, + 0xa672, + 0x074a, 0x10376, + 0x180d, 0xe01c9, - 0xaa2c, 0x0c63, - 0x1056, - 0xe019f, - 0x0eb9, - 0x1da9d, - 0x0a75, - 0xaa7d, - 0x11c9f, - 0x0d46, - 0x110c2, + 0x064c, + 0x1ba8, + 0x0f7c, + 0x16f55, + 0xe010d, + 0x0484, + 0x11caf, + 0xe0106, + 0x0318, + 0x119e4, 0x032b, - 0x0350, - 0x1e8d0, + 0xe016e, 0x11438, 0x116af, - 0xa881, - 0x0327, - 0x1a70, - 0x1058, + 0x17cf, + 0x1344d, + 0x1e4ef, + 0x11f03, + 0x1da47, 0x106d, - 0x103e, - 0x0748, - 0x06e8, - 0xa927, - 0x17c3, - 0x1dce, + 0x1ddf, + 0x0d47, + 0x0c4a, + 0x0a4c, + 0x1cda, + 0x0591, 0x0b56, 0x1d187, 0x0a47, - 0x1c35, - 0x20e2, + 0x10a0c, 0x0a81, - 0x1dd0, - 0xfe00, - 0xe017a, - 0x11d97, + 0xa8b6, + 0x11d95, + 0x0cc0, + 0x0a83, + 0x1927, 0x06d8, - 0x1b34, - 0x1e8d3, + 0xe011b, + 0x06d6, 0x2dea, - 0x0df2, + 0x1a61, 0xe0117, - 0x17bd, + 0x20e4, 0xa9b8, 0x10f84, 0x08dd, 0xe01bb, 0x1dd2, - 0x16f75, - 0x1e8d6, - 0x11c38, - 0xe01ad, - 0x16f73, - 0x17bf, - 0x1a68, - 0x0ccd, - 0x11074, - 0xfe0b, - 0x2df2, - 0x11133, - 0x1da4b, + 0x1da05, + 0x0f87, + 0x1bea, + 0x17d1, + 0x11728, + 0x1dc3, + 0x114b0, + 0xa8b9, + 0x073c, + 0x0a48, + 0x094e, + 0xa94b, + 0x0fb6, + 0x17c1, 0x05a7, 0x1df2, - 0x16f86, - 0x1c2a, - 0x1da69, - 0x0fa3, + 0x0bd7, + 0x0d83, + 0x1cf3b, 0x16fe4, + 0x10efd, 0x0365, - 0x1a6a, - 0x1086, - 0x0a03, - 0x3099, - 0x119de, + 0x089a, + 0x0fa6, + 0x1da3c, + 0x11c9d, + 0xe0114, 0x1ab7, - 0x1da5c, - 0x1a59, - 0xaa29, - 0x0303, - 0x0bc7, + 0x081f, + 0xa8e8, + 0x1193b, + 0x0eb1, + 0x032d, 0x1cf2c, - 0xe0134, - 0x1da0d, - 0x0ddf, - 0x0316, + 0xa8e4, + 0xe01d7, + 0x059d, 0xabed, - 0x0fac, - 0x0d47, + 0x16f78, + 0x1b04, + 0x08f3, 0x11101, - 0x0342, - 0x1172b, - 0xe0177, - 0x0743, - 0x16b32, - 0xe0195, - 0x1e008, + 0x115be, + 0x11d31, + 0x1c33, + 0x1cf07, + 0x0307, + 0x0651, + 0x1ce5, 0x1dd9, - 0xe01c8, - 0x1cf14, - 0x0f87, - 0xa926, + 0x115b8, + 0xe01ac, + 0x033e, + 0x1920, 0x08e9, - 0xe01e9, - 0x08cb, - 0x10d26, + 0x2df9, + 0x16f58, + 0xe01d5, 0x16f6d, - 0x16b36, - 0x05b6, - 0xe0123, + 0xe014a, + 0x0d4d, + 0x11ca0, 0x1cf0a, - 0x1cd1, - 0x065a, + 0x1ce8, + 0x1060, 0x11c96, 0x035e, - 0x16b35, + 0xe0186, 0x115bb, - 0xe0137, - 0x0ac4, - 0x0947, - 0x1da55, - 0x0818, - 0xe01ec, - 0x1123e, - 0xe0132, - 0x0357, - 0x1182f, - 0x094e, - 0x11c9e, - 0x11343, + 0x119d7, + 0x16af4, + 0x1daa9, + 0x0982, + 0x11cb3, + 0x1cf2a, + 0x11ca4, + 0x033b, + 0x135d, + 0x11435, + 0x114b8, + 0x09bc, + 0x1e005, + 0x11082, 0x1d1ab, - 0x1abf, - 0x1cdb, - 0x05b5, - 0xfe0d, - 0x111cc, - 0x1937, - 0x089a, + 0x10a03, + 0xa8f1, + 0x0e4a, + 0x11ca2, + 0xabec, + 0x081c, 0x1ce2, - 0x11d96, - 0x0948, - 0x1b82, - 0x0cc4, + 0x1da0e, + 0x06df, + 0xfe22, + 0x1ce6, 0x1087, - 0x1a5a, - 0x16f67, - 0x1c34, + 0x0f8f, + 0x11a8f, + 0x09c2, 0x1da4e, - 0x1a7f, - 0xe0138, - 0x20dd, + 0x1e006, + 0x08d0, + 0x1dd8, + 0x1714, 0x0a40, - 0x1ac5, 0xe0126, - 0x1923, - 0x11372, - 0x11303, - 0x11833, + 0x11a53, + 0x13451, + 0x1059, + 0x1da61, + 0x1e2ed, 0x1d17c, 0xa678, - 0x0dda, - 0x1be7, - 0x1bc9e, + 0x3099, + 0x16f65, + 0xe0131, 0x0826, - 0x1182c, + 0x11c3d, 0x0df3, - 0xaa2d, - 0x09c4, - 0x102b, + 0x180f, + 0x1a56, + 0x11d8a, 0x1cd9, 0xa8e0, - 0x1ce7, - 0x11933, - 0x11a8a, - 0xe0179, - 0x1da24, + 0xe0129, + 0x1938, + 0x11f00, + 0x0345, + 0x1b02, 0xa9bd, 0x11443, - 0xaa7c, - 0xfe27, + 0xa806, + 0xa9b9, + 0x1da0c, 0xe01d6, - 0x1b73, 0x1e00f, - 0x11129, - 0x07ac, - 0x1d167, - 0x030f, - 0x2dee, + 0x1932, + 0x13454, + 0x1134b, + 0x192a, + 0x0f79, 0x1a60, - 0xa952, - 0x1e949, - 0x10a0d, + 0x0659, + 0x11f3a, + 0x1e8d5, 0x0d01, - 0x031d, - 0x135f, - 0xe01e4, - 0x11ef4, + 0x0734, + 0x11146, + 0xe0108, + 0xe0153, + 0x06eb, 0xe013b, - 0x0956, - 0x0816, - 0x1da65, - 0x16f6f, + 0x1a73, + 0xe0167, + 0x11a98, 0x0f72, - 0x16f79, - 0xaab4, - 0x105f, - 0x1d180, - 0x1e132, - 0x059c, - 0xe0185, - 0xa9b6, + 0x11831, + 0x1dcc, + 0x0f81, + 0x119d5, + 0x16f68, + 0x0f90, + 0x114bb, + 0x2dfd, + 0xfe00, 0x08f7, 0x1da56, - 0xe016a, - 0x16f7b, - 0x034e, - 0x1030, + 0xe0187, + 0xa9c0, + 0x0f93, + 0xa67b, 0x0344, - 0xe0118, - 0x0336, - 0x1752, + 0x20e2, + 0x08fa, + 0x082b, 0x05a1, 0x1ba3, - 0x08eb, - 0x0b4b, + 0x1da42, + 0x0313, 0x11366, - 0x11ca6, - 0x1d16d, + 0x1a6c, + 0xe01db, 0xa929, - 0x16f6c, - 0x112e8, - 0x0dd2, - 0xe0192, - 0x093c, + 0xe01e5, + 0x1da1b, + 0x116b0, + 0x0324, + 0x17be, 0x17c0, - 0x1cf1a, + 0x20dd, 0x11836, + 0x10f50, 0x073d, - 0x10379, - 0x1c26, + 0xe01bd, 0x0dd1, - 0x1da0f, - 0xe01d9, - 0x16b31, - 0x114c2, + 0x1933, + 0x1cf1b, + 0x081b, + 0xaa43, + 0xe01ee, 0x115dc, 0x1de4, - 0x1e01d, - 0xfe25, + 0x0349, + 0x11c32, 0xe0184, - 0x05b0, - 0x10378, + 0xa953, + 0x20ec, 0xe0147, - 0x17cf, - 0x1e01b, - 0xe01af, - 0x0c55, - 0x2d7f, + 0x1cf31, + 0xaa2d, + 0x0b47, + 0x08cf, + 0xa92c, 0x1e024, - 0x135d, - 0x1da35, - 0x0313, - 0xa92b, - 0xe0160, + 0x1e01b, + 0x1acd, + 0xe0181, + 0xe0124, + 0x1a62, 0x09bf, 0x059a, 0x0d4c, 0x11727, - 0x1daad, 0x109b, - 0xa947, - 0x1e2ae, - 0x1c2d, + 0x115c0, + 0x2def, + 0xe010e, + 0x1ced, 0xaa30, - 0xe010c, + 0x1baa, 0xaabf, - 0xe01b4, + 0x1da18, 0x1daaf, 0x1da1a, 0x1d181, 0x1ba6, - 0x1dcf, - 0x06eb, - 0x11a3b, - 0x0953, + 0x1cf02, + 0x11ca9, + 0xe01ba, + 0x0903, 0x1cf05, 0x0abf, - 0x05a8, + 0x108c, 0x115bf, - 0x11d8b, + 0x0d46, 0xe0111, - 0xe01cf, - 0x1da05, - 0x1c30, + 0x05a0, + 0x11c3a, + 0x11725, 0x0c04, - 0x20d0, - 0x08df, - 0x1b01, - 0x0fbb, - 0x11128, - 0x0b41, + 0x08d5, + 0x10379, + 0x0308, + 0x1e020, + 0x0f9a, + 0x17c3, + 0xfe06, 0x1a55, - 0x0d3e, - 0x08e8, - 0x05ab, - 0x1d16f, - 0x1a76, - 0x1da0a, - 0xaa32, - 0xe0130, + 0x115b0, + 0x111b7, + 0x20d4, + 0x16f87, + 0x0a03, + 0xe0163, + 0x102b, + 0x06e2, 0xa9bb, 0x07a9, - 0x0739, - 0x1b70, - 0x10f46, - 0x1e000, - 0x0a83, - 0xe018d, - 0x11a47, + 0xaa4d, + 0x10f4c, + 0x11d97, + 0x114bc, + 0x2cf0, + 0x1ab8, + 0x1a67, 0x106b, - 0x1a61, - 0x192b, - 0xa8ba, - 0x11145, + 0x0f75, + 0x11348, + 0x1cf9, + 0x11070, 0x065e, 0xe0199, 0x0f7b, - 0xe013c, - 0xa980, - 0x0aff, + 0xa679, + 0x11a05, + 0x1ab2, 0x034a, - 0x1df8, - 0x030e, - 0xa8e7, - 0xa8c0, + 0xa82c, + 0x1e136, + 0x10f4b, + 0x20d2, 0x1cf46, 0x1da9e, 0x08db, - 0x11363, - 0xe0115, - 0x0faf, - 0x08f5, - 0x1035, - 0x0943, - 0x1dc4, - 0x114c0, - 0x08fc, - 0x2de6, + 0x0f39, + 0x111bb, + 0x1da26, + 0x10d26, + 0x1e00c, + 0x102c, + 0x16f86, + 0xe012e, + 0x1e944, + 0x0fb7, 0x1b36, 0x0c47, 0x180b, - 0x0899, - 0x302f, - 0x1da5f, - 0x109d, - 0x16f90, - 0x0fb1, + 0x0654, + 0x11cad, + 0x08ec, + 0x16f6c, + 0x1b44, + 0x0ece, 0x0ddc, - 0xe015a, + 0xe01e7, + 0xe0177, 0x1dd7, - 0xaa35, + 0xe015e, 0x0b55, - 0xa880, - 0x1df7, - 0x1a5c, + 0x0aff, + 0x0cca, 0x1163b, - 0x1074, - 0x119d4, - 0xe0153, - 0xe01a6, - 0xfe02, - 0x035c, - 0x1cf0f, - 0xa8eb, - 0x0a01, - 0x11a08, + 0x1b01, + 0x112e7, + 0x10a01, + 0x0f99, + 0x11a3e, + 0x1da01, + 0x1143c, + 0x11a97, + 0xe019e, + 0xe019a, 0x135e, + 0xe018b, 0x034f, 0x1193d, - 0x0940, - 0x16f74, + 0x0368, 0xaaee, - 0x1da13, + 0xaa2b, + 0x10f47, 0x10f4e, - 0x114b8, - 0xe0166, - 0x115b3, - 0xe01c3, - 0x11a57, - 0x1da3d, - 0x0b47, - 0x0f93, - 0x302d, + 0x0f91, + 0xe0112, + 0x11640, + 0x08ee, + 0x11080, + 0x11c33, + 0x16f7f, + 0x1dde, + 0x1daab, 0xe017e, 0x0945, - 0x1cf3c, + 0x0593, 0x1da5a, - 0x11446, - 0x1932, - 0xa948, - 0x033b, - 0xe012f, - 0x0afd, + 0x05bb, + 0x0942, + 0x1da30, + 0xaaf6, + 0x1da50, + 0x16ff0, 0xa8b7, - 0x1dd5, + 0x11940, 0x0360, - 0xe01ba, - 0x0359, + 0x2df5, + 0x073f, 0x1a78, - 0x11c3a, - 0x0eb5, - 0x0339, - 0x1b3c, - 0x1cf25, + 0x09fe, + 0x08e5, + 0x17ce, + 0x16f52, + 0xfe2e, + 0x1c2f, 0x1182e, - 0x11081, - 0x1034, - 0x119db, - 0x11c92, - 0x11725, - 0x0302, - 0x0b44, - 0x1d171, + 0xe017f, + 0x2df4, + 0xe01a3, + 0x11631, + 0x07f0, + 0x11ef3, + 0x05bd, 0x1dfe, + 0x1133e, 0x11a02, - 0x114b4, - 0x11173, + 0xe0110, 0x0afe, - 0x20eb, + 0x2dee, 0x05a5, - 0xe01d4, + 0x0594, 0x1da04, - 0x11445, - 0x11d33, + 0x08ef, + 0xe0145, + 0x030e, 0x0347, - 0x1df4, + 0x0c62, 0xfe09, - 0xe01e3, - 0x0e4a, - 0x0eb8, - 0x0f83, + 0x1133b, + 0x114bd, + 0x111b6, + 0x1cf10, 0x1da3e, - 0x0e48, + 0xe01b9, 0x1da48, - 0x06ea, - 0xe0154, + 0x0b4d, + 0x1dc5, 0x0dd4, - 0x11348, + 0x1e945, 0x0618, 0x0f74, 0x11043, - 0x1929, + 0x1a7f, 0x08d6, - 0x1de6, - 0x11a52, + 0x1e08f, + 0x11c30, 0x11a8c, 0xe01ca, 0x0332, - 0x1daac, - 0x082c, + 0x16af0, + 0x0dde, 0x16f7a, - 0xa94f, + 0x10a0f, + 0x20d0, 0x11362, - 0x1da9b, 0x1e00d, - 0x2dfe, + 0x1112b, 0x05a3, - 0x116b6, - 0x17ca, - 0x034b, - 0x1083, + 0x0a70, + 0x1da65, + 0x11a5b, + 0xa9b7, + 0x11ca3, 0x0fb8, - 0x1a6f, - 0x1cd2, + 0x1033, + 0x111cf, 0xe011a, - 0x1cf1e, - 0x16f7e, - 0x1936, - 0x11d90, - 0x16f59, - 0x1e005, - 0x1da42, - 0x07ee, + 0x0822, + 0x05c2, + 0x1733, + 0xe0175, + 0x1ab9, + 0xe014e, + 0x1e02a, + 0x0f3e, 0x106c, - 0x09c8, 0x093b, - 0x103c, + 0x2de5, + 0x17cc, 0x20e3, - 0xe01e5, 0x1da9f, + 0x11938, 0x0736, - 0x1b6b, - 0x07aa, + 0x1e029, + 0x0d03, 0x0bcd, - 0x1cf01, - 0x036b, - 0x114b5, - 0x111c0, - 0x0321, - 0x1163c, - 0xa9e5, - 0x1a6c, - 0x0f73, - 0xa8e9, - 0x085a, + 0x11cab, + 0x11039, + 0x1e4ec, + 0x1cf03, + 0x030d, + 0x1089, + 0x302b, + 0x11301, + 0x11131, + 0xa92b, + 0x1d17e, 0x111ca, - 0x0eb4, - 0x05a6, + 0x1e8d0, + 0x0650, 0x2df3, 0x08dc, - 0x05b7, + 0x102e, 0xa94c, 0x0c03, - 0x17b6, - 0x0819, - 0x1143c, - 0x1d1ad, - 0x0b48, - 0xfe2f, - 0xa8ea, + 0xaab2, + 0x0eb5, + 0xa8e2, + 0x0f77, + 0xe0138, + 0x1bed, + 0xe01cf, + 0x112e9, 0xe0144, - 0x1da20, - 0x1de0, - 0x1037a, - 0x05ad, + 0x11d33, + 0x1ac0, + 0xe01b6, 0x17c2, + 0x0ac5, 0x11d44, - 0x16f85, - 0x0ccb, - 0x11370, - 0x11930, + 0x0739, + 0x11839, + 0x1885, 0x11100, + 0x064b, 0x1ba5, - 0x1e8d5, + 0x110b3, 0x0e47, - 0x1069, - 0x1cdf, - 0xfe20, + 0x08d2, + 0x07ef, 0x0335, - 0x11ca7, - 0x07f0, - 0x10a0f, + 0x0f86, + 0x1a5d, + 0x030c, 0xa67d, + 0x1d165, 0x11cb0, 0x033d, - 0x08d9, + 0x1beb, 0x16f8f, - 0x108f, - 0x1122e, - 0x1b6f, - 0xe01dd, - 0x033a, - 0x1dc8, - 0x16b33, - 0xa8bd, - 0x11d3d, - 0x11a55, + 0x11a5a, + 0x10ae5, + 0x1da13, + 0x103d, + 0x1cf12, + 0x0e36, + 0x11630, + 0x0944, + 0xaab7, + 0x10a3a, 0x1da31, - 0x1daa3, - 0x1da41, - 0x20d8, - 0x2df6, + 0x1cf30, + 0x07f2, + 0x1cf09, + 0xe014c, 0x1cf15, - 0x1da4c, + 0x0d42, 0x0946, - 0xe0162, - 0x1a69, - 0x1cf17, + 0x1da40, + 0x0cc6, + 0x09c1, 0x06e7, - 0x1d17f, + 0x0fa9, 0x1ba7, - 0x0369, + 0x0cf3, 0x0341, - 0xe01e2, - 0x1da18, - 0x0c42, - 0xfe26, - 0x1ab2, - 0x11d31, - 0x033c, - 0x0d43, - 0xe0168, - 0xabe5, + 0x05ba, + 0x1acc, + 0x0bc6, + 0x1ddb, + 0x0327, + 0x1da2d, + 0xe0178, + 0x2dff, + 0x16b34, + 0x0bca, + 0x1939, 0x1be6, - 0x1e948, - 0x20f0, - 0x11943, + 0x0fad, + 0x119d3, 0xa9b4, - 0x0b03, + 0x11d3a, 0x0488, 0x20e0, - 0x0d00, - 0x119dc, + 0x1cf36, + 0x0337, + 0x1abe, 0x1031, - 0x09bc, - 0x073b, - 0x16f58, - 0x10f82, - 0x1067, - 0x035d, - 0x1059, - 0x0817, - 0x1da2b, + 0x1dd4, + 0x09d7, + 0x1163f, + 0x1cf21, + 0x1dc4, + 0xfe04, + 0xe0189, + 0x036a, + 0x1ddd, 0x114b6, - 0x1a7a, - 0x0f96, + 0x11180, + 0xe016a, 0x16f6a, 0x16ff1, - 0x0485, - 0xe014f, - 0x16f63, - 0x1734, + 0xe0127, + 0x11231, + 0x11241, + 0x0656, 0xe0161, - 0x11d45, - 0x0bcc, - 0x0c40, - 0xa6f1, - 0x1da6a, - 0x0310, - 0x0ddb, - 0x1cf27, - 0x16f7f, - 0x0f92, - 0x11c97, - 0x0859, - 0x1cf02, + 0x0346, + 0x1143a, + 0x1cd6, + 0x0949, + 0x1c26, + 0x110b1, + 0x11436, + 0x11a03, + 0x11367, + 0x1e2ae, + 0xfe0a, + 0x1e00e, + 0x0325, 0x1da9c, 0x1a65, - 0x11cab, + 0x0983, + 0x11a08, 0x17b9, - 0x1deb, - 0xe0191, - 0x0f9e, - 0x16f5e, - 0x1abc, + 0x0c4b, + 0xe0174, + 0x1d244, + 0x1344f, + 0x2de7, 0x1b38, - 0x1071, 0xe013a, + 0x20dc, 0xe011f, - 0x0c4a, - 0x1da28, - 0xabe9, + 0x1cf19, + 0x08d1, + 0x1e010, 0x0955, - 0x089b, + 0x16f69, 0x10eab, - 0xa92c, - 0x1ba8, - 0x11721, - 0x20e1, - 0xa69e, - 0xa9bf, + 0x17c7, + 0x11340, + 0x081d, + 0x0328, + 0x1e028, 0x17bc, - 0x059d, + 0xaab3, 0xe01b7, - 0xe013e, - 0x0e4c, + 0x0e4e, + 0x1abc, 0x1da66, - 0x0325, - 0x08f4, - 0xa92d, - 0x1927, - 0x111b5, - 0x1a72, - 0x1dc6, + 0x1732, + 0xe01ae, + 0x1cf43, + 0x1d243, + 0x1712, + 0x0c42, + 0x0b3f, + 0x302d, 0xe01e6, 0x1da1c, - 0x16b34, 0x2ded, - 0x0a70, + 0x1b41, + 0x11cb4, 0xe0148, - 0x0fa0, - 0x08e0, - 0x20ed, - 0x0902, - 0xe019c, - 0x11726, - 0xe0193, + 0xe0123, + 0x11d93, + 0x1072, + 0x1936, + 0x1063, + 0x0c56, + 0x11a39, 0x1e2ef, - 0x1bec, + 0xe01ab, 0x17d0, - 0x0c4c, - 0x1cf00, - 0x11ca0, - 0x16f64, - 0x094c, + 0x1d242, + 0x0359, + 0x1123e, + 0x11639, + 0x1b73, 0xe0152, - 0x08ef, + 0x11a8d, 0x16af1, 0x035b, 0x0bc2, 0x1da12, - 0x1e00b, + 0xe01da, + 0x11c93, 0x094a, - 0x1143f, 0x073e, - 0x20d4, - 0x064c, - 0xfe06, - 0x09c3, - 0x1bf0, - 0x17b5, - 0x1e001, + 0x11372, + 0x0d48, + 0x1de9, + 0x114c1, + 0x07ae, + 0x11a54, + 0x10a39, 0x11638, - 0x11045, - 0x1a64, - 0x0484, - 0x0c00, - 0x08fe, - 0x0f82, - 0x0cd5, - 0x112e2, + 0x2deb, + 0x073a, + 0x1cf0f, + 0x0fab, + 0x1aca, + 0xa8c3, + 0xa981, + 0x1ac4, 0x1e133, + 0xabe5, 0x1da52, - 0x05b8, + 0x0e37, 0xe0105, - 0x1d18a, - 0xa674, - 0x0737, - 0x0d41, + 0x11357, + 0x0336, + 0x0c3e, + 0xe010f, 0xe0188, - 0x0eba, 0x111cb, 0x11444, - 0x1d1aa, + 0x0940, + 0x11cac, 0xa8ed, 0x114b7, - 0x2de8, - 0x0307, - 0x0f3e, + 0x11832, + 0x0743, + 0x08d8, 0x1e026, 0x1da53, - 0xe0120, + 0x11c3f, 0x1da06, - 0x16af4, - 0x1b43, - 0x0351, - 0x1dc1, + 0xe019b, + 0x119d2, + 0xaa34, + 0x1b00, 0x0730, - 0x06e4, - 0x1163e, - 0x1938, + 0x13440, + 0x0cc4, + 0xe0146, 0x1c25, - 0xa94a, - 0x0eb6, - 0x1134b, - 0xe0108, - 0x1ab5, - 0x11234, - 0x1ddb, + 0x030b, + 0x11a95, + 0x0323, + 0x1e00b, + 0x0943, + 0x0f8d, + 0x0dca, 0x10d25, - 0x2df4, - 0x0322, + 0x2de9, + 0x1bab, 0x115b1, + 0x1da2b, 0x0ebc, - 0x16f76, - 0xa9b9, + 0x1e131, 0xe018a, + 0x1923, 0x05c1, - 0x11d35, + 0x20df, 0x1103d, - 0xfe0c, - 0xa676, + 0xa927, + 0x1c2e, 0x07ec, - 0x1cf24, 0x16f82, - 0x112ea, + 0xe01e4, 0x1da25, - 0xe014e, - 0x11630, + 0x0f7a, + 0x1cf20, + 0x1171d, 0x11347, - 0x07fd, 0x112e6, + 0x1d188, 0x11d41, - 0x032e, + 0x1068, 0x089c, - 0x065b, - 0xfe22, - 0x09c2, - 0xe01b1, - 0x115b9, - 0x0354, - 0xaab2, + 0x11f36, + 0x11341, + 0xaa2f, + 0x0356, + 0xe0137, + 0x1344c, + 0x0fb0, 0xe016b, - 0xaab8, - 0xa982, - 0x08d0, - 0x1926, + 0x1df4, + 0x1112d, + 0x1de2, 0x1103b, - 0x1cf31, - 0xe01ce, - 0x0898, - 0x11a09, + 0x08f9, + 0xe01c0, + 0x11f40, + 0x119df, + 0x1083, 0xaa33, - 0x1b3e, - 0x17be, - 0x1dca, - 0x16f71, - 0x0acb, + 0x13448, + 0x0fb4, + 0x0ac3, + 0xabe4, + 0x11a3c, 0x1134d, 0x114b9, 0x103a, - 0x1ac2, - 0xe01a2, - 0xe0129, - 0x0309, + 0x1da20, + 0x08da, + 0x16f56, + 0x309a, + 0x11127, 0x11a93, - 0x1b3b, - 0x1cf36, + 0x192b, 0x0f97, - 0x1def, - 0x11a39, + 0x1cd5, + 0x1da5f, 0x1084, - 0x1da22, - 0xe01a0, - 0x0fc6, - 0x1cf1f, - 0xe0157, - 0xe0107, - 0x0f86, + 0x0eb4, + 0x11370, + 0x10efe, + 0x1069, + 0x111c0, + 0x11834, + 0x119d4, + 0x1193c, 0x1cf1c, - 0x1daaa, - 0xa80b, + 0x1928, + 0x17bf, 0x1da6c, - 0x1a62, - 0x1da1d, - 0x1064, - 0xe01e7, + 0xe0156, + 0x1bf2, + 0x0304, 0x11ca1, - 0x0731, + 0x11233, + 0x0859, 0x0a42, - 0x1107f, - 0x192a, + 0x1c2d, + 0x0738, 0x0592, - 0x0f39, - 0x11d47, + 0x1b6f, + 0x0355, 0x0ddd, - 0x16f5c, - 0x0338, - 0x1103f, - 0x1b40, - 0x1182d, - 0x1aca, - 0x1cf0b, - 0x1ace, + 0x1a71, + 0x0bc1, + 0x112df, + 0x1344e, + 0x1daac, + 0x1e014, + 0x0d44, + 0x1df8, 0x16f4f, 0xe01e0, - 0xe0174, 0x1da16, - 0x0670, - 0x0963, - 0x11a3d, - 0x1921, - 0x0320, + 0x11721, + 0x0d02, + 0x20e5, + 0x115b4, + 0x1b42, + 0x1b43, 0x0b40, - 0xe01cb, - 0x1da01, + 0xe016c, + 0x08ed, 0x109a, + 0x11303, 0x1cf35, - 0x032a, - 0xe013d, - 0x11341, - 0x0c44, - 0x1cf11, - 0x1ce4, - 0x0942, - 0xe0171, - 0x0617, - 0xe01b3, - 0x1d172, + 0x1344a, + 0x17c5, + 0x11c39, + 0xa66f, + 0x093f, + 0x20d7, + 0x05ae, + 0x1cf14, + 0x1e016, + 0x08eb, 0x16f53, 0x0745, - 0x1da36, - 0x031f, - 0x06e2, + 0x0353, + 0x0c3c, + 0x0315, 0x16f54, - 0x180d, - 0x09d7, - 0xe01ae, - 0x1da1e, - 0x1df3, - 0x0747, + 0x0eb9, + 0x114be, + 0x08cb, + 0x16f81, + 0x06db, + 0x07a7, + 0x0a4b, 0x20e6, 0x1df5, - 0x074a, + 0xe01a4, 0xfe23, - 0x1da68, - 0x1ab8, - 0x1ce8, - 0x1cf0e, + 0x1172b, + 0x0dd9, + 0x1929, + 0x302f, 0x064d, - 0x08ca, - 0x1ded, + 0x0a01, + 0x09c8, 0x20d1, - 0x1163f, - 0xa953, - 0x0318, - 0x1a6e, - 0x11a8e, - 0x0a71, - 0x116b7, + 0xe018f, + 0xa8e5, + 0xa8c2, + 0x16b31, + 0xa6f1, + 0x0f92, + 0x07fd, 0x094d, 0x0e4b, 0x1193e, - 0x1143a, + 0xe0115, 0x093e, 0x0821, - 0x0300, - 0x1da47, - 0x1cf40, - 0xe0102, + 0x1cd0, + 0x1c2a, + 0x0735, + 0xa823, 0x05a4, - 0x1e01f, - 0x0311, - 0xe01b2, - 0x1da51, - 0xe0178, - 0xaac1, - 0x0f9a, + 0xe0121, + 0xe015c, + 0x1a79, + 0x0f83, + 0x112e1, + 0xa947, + 0x16f5e, 0x10a06, - 0x11cad, - 0xa9ba, - 0xe01b6, - 0x1de9, - 0x16f68, - 0x2dec, - 0x08d1, - 0x0900, + 0x17d3, + 0x1d185, + 0x0d57, + 0x16f62, + 0x0f96, + 0x115b3, + 0x11f35, + 0xe0119, 0x16f7d, - 0x11a54, - 0xe017c, - 0x1dd4, - 0x1da60, - 0xa8bb, - 0x116b3, + 0xfe02, + 0x0c46, + 0x1cf44, + 0x2de0, + 0xaa2e, + 0x111ba, + 0x110b4, 0x1e8d2, - 0x11c9d, + 0x11c92, 0x1d169, - 0x1713, - 0xa8be, - 0x11a94, + 0x035f, + 0x0740, 0x1cdc, - 0x1e00e, - 0x10d24, + 0x1122d, + 0x2de8, + 0x0748, 0x0ec9, - 0x05a2, - 0x0711, - 0xaa2a, - 0x0e37, + 0x1a63, + 0x1da5c, + 0x1b35, + 0x0cc2, 0x1112c, - 0x08ee, + 0xe0113, 0x06da, 0x1922, - 0x10a01, - 0x1da62, - 0x1ce5, - 0x1cf3b, - 0x11435, - 0x0cc0, - 0x17c1, + 0x2de3, + 0x18a9, + 0x1ba9, + 0x08cc, + 0x11a57, + 0x102f, + 0x0737, 0x0652, - 0x1da3c, - 0x1daab, - 0x0cc1, - 0x0b82, - 0x07a6, - 0x11640, - 0x1b71, - 0x0655, + 0x10a0d, + 0x05b4, + 0x11000, + 0x0fa7, + 0x06e3, + 0x1bf3, + 0xe01a6, + 0x0352, 0x0305, - 0x1c2e, - 0x0cca, - 0x1cf20, - 0x1c31, + 0x0f82, + 0xe0172, + 0x11235, + 0x0d43, 0x106a, - 0x08e5, - 0x1d1ac, - 0x1da21, - 0xe01eb, + 0x20e8, + 0x11c94, + 0x1b6e, + 0x05b1, 0x0614, + 0x08fb, 0x11132, - 0x11931, - 0x0343, + 0x103b, 0x110b9, - 0x1039, - 0xa94b, + 0x112e8, + 0x1b6b, 0x1da6b, - 0xa8f1, + 0x1c2c, + 0x1b3a, 0xe01bc, - 0x0a82, + 0x1da64, 0x1085, - 0x101fd, - 0x05b1, + 0x1da45, 0x11d36, - 0xa66f, - 0x0bcb, - 0x1060, - 0x16f57, + 0x20f0, + 0x1da0f, + 0x0899, + 0xe01d9, 0x031e, 0x0fa5, + 0x1182c, 0xe01a1, 0xe01c6, - 0x11cb1, - 0xe010e, + 0x0350, + 0x13452, 0x1ce3, - 0x1de2, + 0x2de1, 0x2dfc, - 0xe0128, 0x1da4a, - 0x1e015, - 0xe019b, - 0x20db, + 0x1cf04, + 0x16f63, + 0x1d189, + 0xe0101, 0xe014d, 0x11a92, - 0x0eb1, - 0xe01a7, + 0x0817, + 0x11c31, 0x11040, - 0x11c3d, - 0x1da4d, + 0xe01df, + 0x1e021, 0x11302, 0xe01e1, - 0x0651, - 0x1da17, - 0x1920, - 0x11cb2, + 0xe0166, + 0x11a34, + 0x111cc, + 0xaaec, 0x0962, - 0x1abe, - 0xe0163, - 0x031c, - 0x0356, + 0xfe07, + 0x1cf16, + 0x1bef, + 0x08ea, 0x1e011, - 0x1cf06, - 0x1d170, - 0x07f3, - 0x116b2, - 0x1ce1, + 0x0f7e, + 0x1daa7, + 0x1937, + 0xe016d, + 0x1dee, 0xfe28, - 0xe01c4, - 0x08da, - 0x20d5, - 0x1cf12, - 0xabe6, + 0x085b, + 0xa94a, + 0x1dd5, + 0x1dea, + 0x1a6f, 0xfe03, - 0x1dfa, - 0x11439, - 0x11837, - 0x093f, - 0x1cf41, - 0xe0131, - 0x1145e, - 0x1daa4, - 0x0a02, - 0x07a8, - 0x0734, - 0x1112e, - 0x114b3, - 0x1122c, - 0x0594, - 0x1e020, - 0xe0125, - 0x1e2ed, - 0xe0104, - 0x07f2, - 0x0c4d, - 0x1772, - 0x1bab, - 0x17cb, - 0x0613, - 0x0f91, - 0x111ba, - 0x1abb, - 0x16f7c, + 0x1a75, + 0x06ea, + 0x16f7e, + 0x0f37, + 0x1182f, + 0x059f, + 0x1da69, + 0x0fac, + 0x0c3f, + 0x0d41, + 0x16f84, + 0x0fae, + 0xe0168, + 0x0c44, + 0x034e, + 0x08fc, + 0x05bf, + 0x0dd0, + 0x1bf0, + 0x2cef, + 0x1ab3, + 0x0d3f, + 0x1cf2b, + 0xa8c0, + 0x1a5c, + 0x16f67, + 0x1daaa, + 0xe016f, + 0x1da84, + 0x2df2, 0x05a9, - 0x1d188, + 0xe013d, 0x0c43, - 0xa8c3, - 0x08f3, + 0x1da36, + 0xe0103, 0x08fd, - 0x1193b, - 0x0a4c, - 0x1089, - 0x11839, - 0xa8e8, + 0x0fba, + 0x0ec8, + 0x1da1f, + 0xa9b5, + 0x1be8, 0xfe2b, 0x108d, 0x06d9, - 0x11a95, - 0x16f61, - 0xe011c, - 0x1753, + 0x1cdd, + 0x0816, + 0xa676, + 0x0818, 0x16f5f, - 0x1133b, + 0x0fa8, 0x0f9b, 0x0f9d, - 0x1bed, - 0x0330, - 0xe011e, - 0x1062, + 0x0e31, + 0x11a91, + 0x0611, + 0x0b4b, 0x0b57, - 0xa8bf, - 0xe0156, - 0x1da5d, - 0x1cd0, + 0xe015d, + 0x108f, + 0x1e001, + 0x17ca, + 0x08e1, 0x1bc9d, - 0xe01ed, - 0x1da23, - 0x035f, - 0x11d94, - 0x1dc5, + 0x2df1, + 0x0b42, + 0x081e, + 0x16f59, + 0xfe20, 0x0597, - 0x030b, - 0x114bb, + 0x1cf01, 0x1038, 0x035a, - 0x1e027, - 0x1c37, - 0xaa43, - 0x11441, - 0x302e, - 0x10a0c, - 0xe015d, - 0x1dfb, - 0x11a53, - 0xe01ac, - 0x0f19, - 0x1d168, - 0x1b02, + 0xe0196, + 0x1a6e, + 0x1daa5, + 0x0321, + 0x1da51, + 0x17d2, + 0x1daad, + 0x033a, + 0x1056, + 0x1ab1, + 0x0dcf, + 0x1e947, + 0x0300, + 0x10d24, 0x10a02, 0x11342, - 0x1ab3, - 0x11442, - 0x0c46, + 0x1ce7, + 0x031f, + 0x1073, 0x0653, - 0x111bb, + 0x0fb2, 0x11a33, 0xe01cc, 0x1da02, - 0x11440, + 0xe0133, 0x2de2, - 0xa9c0, - 0x11082, - 0xe0101, - 0x0abc, + 0x0333, + 0x0a71, + 0xe01eb, + 0x11d96, 0x0612, 0xa8b8, - 0xe0124, - 0xa951, - 0x059e, - 0x11632, - 0x1cd6, - 0x17bb, - 0x119e4, - 0x1112d, - 0x0cc2, + 0x08e8, + 0x11ca6, + 0x1de8, + 0x1da4f, + 0x07a8, + 0x0e39, + 0xa982, + 0x036e, + 0x193a, 0x16f91, - 0x20d3, - 0x0c41, - 0x1171f, + 0x10d27, + 0x0f78, + 0x035d, 0x1da2f, - 0x1e945, - 0x1033, - 0x111b4, + 0x11a36, + 0xaab0, + 0xfe0e, + 0x05ad, 0x1dd6, - 0x1733, + 0xe0142, 0x1dfd, - 0x119dd, 0x1122f, - 0x111b6, - 0x1b03, - 0x11c32, - 0xa8b4, - 0x0742, - 0x0358, - 0xe01bd, - 0x036a, - 0x0f8d, - 0x11131, + 0x08e4, + 0xaa7c, + 0x1b3b, + 0x0b48, + 0x05bc, + 0xa8ee, + 0x11c97, + 0x110b8, + 0xe01b2, + 0xe0122, + 0x11a8e, 0x11a58, - 0xfe07, - 0x11c2f, - 0x0ebb, - 0x11934, - 0x2de0, - 0x11639, - 0x1e946, - 0x11ef5, + 0x036b, + 0x0331, + 0x16f71, + 0x1143e, + 0x110ba, + 0x1112e, + 0x089b, 0x1ac1, + 0xe0143, 0x07ed, - 0x114b2, - 0x0944, - 0x11a98, - 0x115b0, - 0x1d17e, - 0x09e2, - 0x1da61, - 0x0353, - 0x1e016, - 0xe01aa, - 0x20da, - 0xe0170, + 0xa674, + 0x2df0, + 0x1da62, + 0xa8bd, + 0x1b3d, + 0x11d3c, + 0xe014b, + 0xaa32, + 0x11a51, + 0x16f92, + 0x1d166, + 0x0cc8, + 0x1dca, 0xe01b8, - 0x10a3a, - 0x11a8d, - 0x073f, - 0x06e0, - 0x1c33, - 0x0328, - 0x1da2a, - 0xe010f, - 0x1cf19, - 0x16ff0, - 0x1e136, - 0x1da1f, - 0x1cf29, - 0x20ec, - 0x0cc6, + 0x1ac8, + 0x17c9, + 0xfe08, + 0x0338, + 0x1de7, + 0xe018d, + 0xa69e, + 0x1da4c, + 0x07f3, + 0x16b35, + 0x0a51, + 0xa825, + 0x1071, + 0x11f3f, 0x0348, - 0x0c3e, + 0x116b7, + 0x09c3, 0x1e2ee, - 0x05ae, 0x0e34, - 0x09c7, - 0x1a19, - 0x1bea, + 0x036d, + 0xabe9, + 0x1cf7, 0x1935, - 0x1cf3e, - 0x061a, - 0x0f77, - 0x0ac5, - 0xa8c4, - 0x1c24, + 0x05aa, + 0x1103f, + 0x11a09, + 0x1da3f, + 0x108a, + 0x16f5c, + 0x20d6, 0x07eb, - 0x0957, - 0x1da64, - 0x0d02, - 0xaa34, - 0x0d3c, - 0x0901, + 0xfe2a, + 0xe0193, + 0x11d40, + 0x05b9, + 0x0f7d, + 0x16f5a, 0xe0197, 0x09cd, 0x0fb5, 0x1da07, 0xe01d1, - 0x102e, - 0xe016c, - 0x110b1, + 0xa880, + 0x1a7c, + 0x11ca5, 0x09cb, - 0x11834, - 0x11932, + 0x0fb3, + 0x0825, 0x1103a, 0x0827, 0x1e94a, @@ -33403,7 +33693,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{0CDD}'..='\u{0CDE}' | '\u{0CE0}'..='\u{0CE3}' | '\u{0CE6}'..='\u{0CEF}' - | '\u{0CF1}'..='\u{0CF2}' + | '\u{0CF1}'..='\u{0CF3}' | '\u{0D00}'..='\u{0D0C}' | '\u{0D0E}'..='\u{0D10}' | '\u{0D12}'..='\u{0D44}' @@ -33433,7 +33723,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{0EA7}'..='\u{0EBD}' | '\u{0EC0}'..='\u{0EC4}' | '\u{0EC6}' - | '\u{0EC8}'..='\u{0ECD}' + | '\u{0EC8}'..='\u{0ECE}' | '\u{0ED0}'..='\u{0ED9}' | '\u{0EDC}'..='\u{0EDF}' | '\u{0F00}'..='\u{0F47}' @@ -33704,7 +33994,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{10E80}'..='\u{10EA9}' | '\u{10EAB}'..='\u{10EAD}' | '\u{10EB0}'..='\u{10EB1}' - | '\u{10F00}'..='\u{10F27}' + | '\u{10EFD}'..='\u{10F27}' | '\u{10F30}'..='\u{10F59}' | '\u{10F70}'..='\u{10F89}' | '\u{10FB0}'..='\u{10FCB}' @@ -33721,7 +34011,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{11180}'..='\u{111DF}' | '\u{111E1}'..='\u{111F4}' | '\u{11200}'..='\u{11211}' - | '\u{11213}'..='\u{1123E}' + | '\u{11213}'..='\u{11241}' | '\u{11280}'..='\u{11286}' | '\u{11288}' | '\u{1128A}'..='\u{1128D}' @@ -33774,6 +34064,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{11A00}'..='\u{11A47}' | '\u{11A50}'..='\u{11AA2}' | '\u{11AB0}'..='\u{11AF8}' + | '\u{11B00}'..='\u{11B09}' | '\u{11C00}'..='\u{11C08}' | '\u{11C0A}'..='\u{11C36}' | '\u{11C38}'..='\u{11C45}' @@ -33795,6 +34086,9 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{11D93}'..='\u{11D98}' | '\u{11DA0}'..='\u{11DA9}' | '\u{11EE0}'..='\u{11EF8}' + | '\u{11F00}'..='\u{11F10}' + | '\u{11F12}'..='\u{11F3A}' + | '\u{11F3E}'..='\u{11F59}' | '\u{11FB0}' | '\u{11FC0}'..='\u{11FF1}' | '\u{11FFF}'..='\u{12399}' @@ -33802,8 +34096,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{12470}'..='\u{12474}' | '\u{12480}'..='\u{12543}' | '\u{12F90}'..='\u{12FF2}' - | '\u{13000}'..='\u{1342E}' - | '\u{13430}'..='\u{13438}' + | '\u{13000}'..='\u{13455}' | '\u{14400}'..='\u{14646}' | '\u{16800}'..='\u{16A38}' | '\u{16A40}'..='\u{16A5E}' @@ -33830,7 +34123,9 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{1AFF5}'..='\u{1AFFB}' | '\u{1AFFD}'..='\u{1AFFE}' | '\u{1B000}'..='\u{1B122}' + | '\u{1B132}' | '\u{1B150}'..='\u{1B152}' + | '\u{1B155}' | '\u{1B164}'..='\u{1B167}' | '\u{1B170}'..='\u{1B2FB}' | '\u{1BC00}'..='\u{1BC6A}' @@ -33845,6 +34140,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{1D100}'..='\u{1D126}' | '\u{1D129}'..='\u{1D1EA}' | '\u{1D200}'..='\u{1D245}' + | '\u{1D2C0}'..='\u{1D2D3}' | '\u{1D2E0}'..='\u{1D2F3}' | '\u{1D300}'..='\u{1D356}' | '\u{1D360}'..='\u{1D378}' @@ -33872,11 +34168,14 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{1DA9B}'..='\u{1DA9F}' | '\u{1DAA1}'..='\u{1DAAF}' | '\u{1DF00}'..='\u{1DF1E}' + | '\u{1DF25}'..='\u{1DF2A}' | '\u{1E000}'..='\u{1E006}' | '\u{1E008}'..='\u{1E018}' | '\u{1E01B}'..='\u{1E021}' | '\u{1E023}'..='\u{1E024}' | '\u{1E026}'..='\u{1E02A}' + | '\u{1E030}'..='\u{1E06D}' + | '\u{1E08F}' | '\u{1E100}'..='\u{1E12C}' | '\u{1E130}'..='\u{1E13D}' | '\u{1E140}'..='\u{1E149}' @@ -33884,6 +34183,7 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{1E290}'..='\u{1E2AE}' | '\u{1E2C0}'..='\u{1E2F9}' | '\u{1E2FF}' + | '\u{1E4D0}'..='\u{1E4F9}' | '\u{1E7E0}'..='\u{1E7E6}' | '\u{1E7E8}'..='\u{1E7EB}' | '\u{1E7ED}'..='\u{1E7EE}' @@ -33942,10 +34242,10 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{1F250}'..='\u{1F251}' | '\u{1F260}'..='\u{1F265}' | '\u{1F300}'..='\u{1F6D7}' - | '\u{1F6DD}'..='\u{1F6EC}' + | '\u{1F6DC}'..='\u{1F6EC}' | '\u{1F6F0}'..='\u{1F6FC}' - | '\u{1F700}'..='\u{1F773}' - | '\u{1F780}'..='\u{1F7D8}' + | '\u{1F700}'..='\u{1F776}' + | '\u{1F77B}'..='\u{1F7D9}' | '\u{1F7E0}'..='\u{1F7EB}' | '\u{1F7F0}' | '\u{1F800}'..='\u{1F80B}' @@ -33956,25 +34256,24 @@ pub fn is_public_assigned(c: char) -> bool { | '\u{1F8B0}'..='\u{1F8B1}' | '\u{1F900}'..='\u{1FA53}' | '\u{1FA60}'..='\u{1FA6D}' - | '\u{1FA70}'..='\u{1FA74}' - | '\u{1FA78}'..='\u{1FA7C}' - | '\u{1FA80}'..='\u{1FA86}' - | '\u{1FA90}'..='\u{1FAAC}' - | '\u{1FAB0}'..='\u{1FABA}' - | '\u{1FAC0}'..='\u{1FAC5}' - | '\u{1FAD0}'..='\u{1FAD9}' - | '\u{1FAE0}'..='\u{1FAE7}' - | '\u{1FAF0}'..='\u{1FAF6}' + | '\u{1FA70}'..='\u{1FA7C}' + | '\u{1FA80}'..='\u{1FA88}' + | '\u{1FA90}'..='\u{1FABD}' + | '\u{1FABF}'..='\u{1FAC5}' + | '\u{1FACE}'..='\u{1FADB}' + | '\u{1FAE0}'..='\u{1FAE8}' + | '\u{1FAF0}'..='\u{1FAF8}' | '\u{1FB00}'..='\u{1FB92}' | '\u{1FB94}'..='\u{1FBCA}' | '\u{1FBF0}'..='\u{1FBF9}' | '\u{20000}'..='\u{2A6DF}' - | '\u{2A700}'..='\u{2B738}' + | '\u{2A700}'..='\u{2B739}' | '\u{2B740}'..='\u{2B81D}' | '\u{2B820}'..='\u{2CEA1}' | '\u{2CEB0}'..='\u{2EBE0}' | '\u{2F800}'..='\u{2FA1D}' | '\u{30000}'..='\u{3134A}' + | '\u{31350}'..='\u{323AF}' | '\u{E0001}' | '\u{E0020}'..='\u{E007F}' | '\u{E0100}'..='\u{E01EF}' @@ -34461,6 +34760,7 @@ pub fn qc_nfkc(c: char) -> IsNormalized { '\u{1D7C3}' => No, '\u{1D7C4}'...'\u{1D7CB}' => No, '\u{1D7CE}'...'\u{1D7FF}' => No, + '\u{1E030}'...'\u{1E06D}' => No, '\u{1EE00}'...'\u{1EE03}' => No, '\u{1EE05}'...'\u{1EE1F}' => No, '\u{1EE21}'...'\u{1EE22}' => No, @@ -35310,6 +35610,7 @@ pub fn qc_nfkd(c: char) -> IsNormalized { '\u{1D7C3}' => No, '\u{1D7C4}'...'\u{1D7CB}' => No, '\u{1D7CE}'...'\u{1D7FF}' => No, + '\u{1E030}'...'\u{1E06D}' => No, '\u{1EE00}'...'\u{1EE03}' => No, '\u{1EE05}'...'\u{1EE1F}' => No, '\u{1EE21}'...'\u{1EE22}' => No, diff --git a/vendor/unicode-script/.cargo-checksum.json b/vendor/unicode-script/.cargo-checksum.json index 44c6c80d2..1bd2141e0 100644 --- a/vendor/unicode-script/.cargo-checksum.json +++ b/vendor/unicode-script/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"3b6e9ba98b2f20b8b8a13f2e961a78691a064dcd1ae0d5bcfaf26216b2bb9c68","README.md":"14f5fffdc485176a2ab2e04555231042d0f7d818dbf1a0749a1ecbd8a0d4d500","scripts/unicode.py":"53803e407327679983929fbbdaf874c44c21b6f775eb48690dd52528dd3f4a51","src/lib.rs":"1e67da407be73a423a1de030f1397864aa454925a8582e027e9a9246529bf0b6","src/tables.rs":"6303916c60cee9abfa380b345536177415f042f36df3479d35c17b3587e65479"},"package":"098ec66172ce21cd55f8bcc786ee209dd20e04eff70acfca30cb79924d173ae9"} \ No newline at end of file +{"files":{"Cargo.toml":"dce5bd5ce9da2e852b95c7c96ef36d7e70c36bf15eff3052a3fcb9ba9f8d3af5","LICENSE-APACHE":"7cbb56d1b5d83d735056b363ab20958524120afafc4ad8206e6be98cdec5d737","LICENSE-MIT":"7ad3ea8ca3caf894db98c3f31d5d4949173ffa93c883ef19a9e529ad48960f8c","README.md":"9d922b2906be36f007f89c6f4eae8976d90a01be8181928698a121b154bbb016","scripts/unicode.py":"ce98a6f184b6d4c44c855b80d92d6d570a42535df840a44be4eecd47d6320aea","src/lib.rs":"d2476ef2fbc805c9a34110dce7415b4ba21de7da6e19470a1b856966564e905f","src/tables.rs":"e78188904a06dc06a59ad4e8c30990060f06c3d8e5871437d531389fa5aabade"},"package":"7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc"} \ No newline at end of file diff --git a/vendor/unicode-script/Cargo.toml b/vendor/unicode-script/Cargo.toml index 6dfc01148..c2647d3ab 100644 --- a/vendor/unicode-script/Cargo.toml +++ b/vendor/unicode-script/Cargo.toml @@ -3,26 +3,38 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" name = "unicode-script" -version = "0.5.3" +version = "0.5.5" authors = ["Manish Goregaokar "] -exclude = ["target/*", "Cargo.lock", "scripts/tmp", "*.txt"] -description = "This crate exposes the Unicode `Script` and `Script_Extension` properties from [UAX #24](http://www.unicode.org/reports/tr24/)\n" +exclude = [ + "target/*", + "Cargo.lock", + "scripts/tmp", + "*.txt", +] +description = """ +This crate exposes the Unicode `Script` and `Script_Extension` properties from [UAX #24](http://www.unicode.org/reports/tr24/) +""" homepage = "https://github.com/unicode-rs/unicode-script" documentation = "https://docs.rs/unicode-script" readme = "README.md" -keywords = ["text", "unicode", "script", "language"] +keywords = [ + "text", + "unicode", + "script", + "language", +] license = "MIT/Apache-2.0" repository = "https://github.com/unicode-rs/unicode-script" + [dependencies.compiler_builtins] version = "0.1" optional = true @@ -39,4 +51,8 @@ package = "rustc-std-workspace-std" [features] bench = [] -rustc-dep-of-std = ["std", "core", "compiler_builtins"] +rustc-dep-of-std = [ + "std", + "core", + "compiler_builtins", +] diff --git a/vendor/unicode-script/LICENSE-APACHE b/vendor/unicode-script/LICENSE-APACHE new file mode 100644 index 000000000..aa718b553 --- /dev/null +++ b/vendor/unicode-script/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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 2021 The Unicode-rs Developers + +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. diff --git a/vendor/unicode-script/LICENSE-MIT b/vendor/unicode-script/LICENSE-MIT new file mode 100644 index 000000000..20c28a2ce --- /dev/null +++ b/vendor/unicode-script/LICENSE-MIT @@ -0,0 +1,27 @@ +MIT License + +Copyright (c) 2019 Manish Goregaokar + +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. diff --git a/vendor/unicode-script/README.md b/vendor/unicode-script/README.md index 85fd60b11..0afbce69b 100644 --- a/vendor/unicode-script/README.md +++ b/vendor/unicode-script/README.md @@ -1,7 +1,7 @@ # unicode-script [![Build Status](https://github.com/unicode-rs/unicode-script/workflows/Tests/badge.svg)](https://github.com/unicode-rs/unicode-script/actions) -[![Current Version](https://meritbadge.herokuapp.com/unicode-script)](https://crates.io/crates/unicode-script) +[![Current Version](https://img.shields.io/crates/v/unicode-script.svg)](https://crates.io/crates/unicode-script) [![License: MIT/Apache-2.0](https://img.shields.io/crates/l/unicode-script.svg)](#license) -This crate exposes the Unicode `Script` and `Script_Extension` properties from [UAX #24](http://www.unicode.org/reports/tr24/) \ No newline at end of file +This crate exposes the Unicode `Script` and `Script_Extension` properties from [UAX #24](http://www.unicode.org/reports/tr24/) diff --git a/vendor/unicode-script/scripts/unicode.py b/vendor/unicode-script/scripts/unicode.py index e40a92c6d..7b5c75c72 100644 --- a/vendor/unicode-script/scripts/unicode.py +++ b/vendor/unicode-script/scripts/unicode.py @@ -46,7 +46,7 @@ ending=''' } ''' -UNICODE_VERSION = (13, 0, 0) +UNICODE_VERSION = (15, 0, 0) UNICODE_VERSION_NUMBER = "%s.%s.%s" %UNICODE_VERSION @@ -59,7 +59,7 @@ def fetch(f): os.system("curl -O https://www.unicode.org/Public/emoji/%s.%s/%s" % (UNICODE_VERSION[0], UNICODE_VERSION[1], f)) else: - os.system("curl -O http://www.unicode.org/Public/%s/ucd/%s" + os.system("curl -O https://www.unicode.org/Public/%s/ucd/%s" % (UNICODE_VERSION_NUMBER, f)) if not os.path.exists(os.path.basename(f)): diff --git a/vendor/unicode-script/src/lib.rs b/vendor/unicode-script/src/lib.rs index d650ee0b2..63f129069 100644 --- a/vendor/unicode-script/src/lib.rs +++ b/vendor/unicode-script/src/lib.rs @@ -144,20 +144,20 @@ pub struct ScriptExtension { // A bitset for the scripts 65-128 second: u64, // A bitset for scripts after 128 - third: u32, + third: u64, // Both Common and Inherited are represented by all used bits being set, // this flag lets us distinguish the two. common: bool, } impl ScriptExtension { - // We don't use the complete u32 of `third`, so the "all" value is not just u32::MAX + // We don't use the complete u64 of `third`, so the "all" value is not just u32::MAX // Instead, we take the number of the next (unused) script bit, subtract 128 to bring - // it in the range of `third`, create a u32 with just that bit set, and subtract 1 + // it in the range of `third`, create a u64 with just that bit set, and subtract 1 // to create one with all the lower bits set. - const THIRD_MAX: u32 = ((1 << (NEXT_SCRIPT - 128)) - 1); + const THIRD_MAX: u64 = ((1 << (NEXT_SCRIPT - 128)) - 1); - pub(crate) const fn new(first: u64, second: u64, third: u32) -> Self { + pub(crate) const fn new(first: u64, second: u64, third: u64) -> Self { ScriptExtension { first, second, diff --git a/vendor/unicode-script/src/tables.rs b/vendor/unicode-script/src/tables.rs index e31a7229f..41035fcdc 100644 --- a/vendor/unicode-script/src/tables.rs +++ b/vendor/unicode-script/src/tables.rs @@ -20,7 +20,7 @@ use crate::ScriptExtension; /// The version of [Unicode](http://www.unicode.org/) /// that this version of unicode-script is based on. -pub const UNICODE_VERSION: (u64, u64, u64) = (13, 0, 0); +pub const UNICODE_VERSION: (u64, u64, u64) = (15, 0, 0); #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[non_exhaustive] @@ -84,266 +84,280 @@ pub enum Script { Chorasmian = 23, /// Copt Coptic = 24, + /// Cpmn + Cypro_Minoan = 25, /// Cprt - Cypriot = 25, + Cypriot = 26, /// Cyrl - Cyrillic = 26, + Cyrillic = 27, /// Deva - Devanagari = 27, + Devanagari = 28, /// Diak - Dives_Akuru = 28, + Dives_Akuru = 29, /// Dogr - Dogra = 29, + Dogra = 30, /// Dsrt - Deseret = 30, + Deseret = 31, /// Dupl - Duployan = 31, + Duployan = 32, /// Egyp - Egyptian_Hieroglyphs = 32, + Egyptian_Hieroglyphs = 33, /// Elba - Elbasan = 33, + Elbasan = 34, /// Elym - Elymaic = 34, + Elymaic = 35, /// Ethi - Ethiopic = 35, + Ethiopic = 36, /// Geor - Georgian = 36, + Georgian = 37, /// Glag - Glagolitic = 37, + Glagolitic = 38, /// Gong - Gunjala_Gondi = 38, + Gunjala_Gondi = 39, /// Gonm - Masaram_Gondi = 39, + Masaram_Gondi = 40, /// Goth - Gothic = 40, + Gothic = 41, /// Gran - Grantha = 41, + Grantha = 42, /// Grek - Greek = 42, + Greek = 43, /// Gujr - Gujarati = 43, + Gujarati = 44, /// Guru - Gurmukhi = 44, + Gurmukhi = 45, /// Hang - Hangul = 45, + Hangul = 46, /// Hani - Han = 46, + Han = 47, /// Hano - Hanunoo = 47, + Hanunoo = 48, /// Hatr - Hatran = 48, + Hatran = 49, /// Hebr - Hebrew = 49, + Hebrew = 50, /// Hira - Hiragana = 50, + Hiragana = 51, /// Hluw - Anatolian_Hieroglyphs = 51, + Anatolian_Hieroglyphs = 52, /// Hmng - Pahawh_Hmong = 52, + Pahawh_Hmong = 53, /// Hmnp - Nyiakeng_Puachue_Hmong = 53, + Nyiakeng_Puachue_Hmong = 54, /// Hung - Old_Hungarian = 54, + Old_Hungarian = 55, /// Ital - Old_Italic = 55, + Old_Italic = 56, /// Java - Javanese = 56, + Javanese = 57, /// Kali - Kayah_Li = 57, + Kayah_Li = 58, /// Kana - Katakana = 58, + Katakana = 59, + /// Kawi + Kawi = 60, /// Khar - Kharoshthi = 59, + Kharoshthi = 61, /// Khmr - Khmer = 60, + Khmer = 62, /// Khoj - Khojki = 61, + Khojki = 63, /// Kits - Khitan_Small_Script = 62, + Khitan_Small_Script = 64, /// Knda - Kannada = 63, + Kannada = 65, /// Kthi - Kaithi = 64, + Kaithi = 66, /// Lana - Tai_Tham = 65, + Tai_Tham = 67, /// Laoo - Lao = 66, + Lao = 68, /// Latn - Latin = 67, + Latin = 69, /// Lepc - Lepcha = 68, + Lepcha = 70, /// Limb - Limbu = 69, + Limbu = 71, /// Lina - Linear_A = 70, + Linear_A = 72, /// Linb - Linear_B = 71, + Linear_B = 73, /// Lisu - Lisu = 72, + Lisu = 74, /// Lyci - Lycian = 73, + Lycian = 75, /// Lydi - Lydian = 74, + Lydian = 76, /// Mahj - Mahajani = 75, + Mahajani = 77, /// Maka - Makasar = 76, + Makasar = 78, /// Mand - Mandaic = 77, + Mandaic = 79, /// Mani - Manichaean = 78, + Manichaean = 80, /// Marc - Marchen = 79, + Marchen = 81, /// Medf - Medefaidrin = 80, + Medefaidrin = 82, /// Mend - Mende_Kikakui = 81, + Mende_Kikakui = 83, /// Merc - Meroitic_Cursive = 82, + Meroitic_Cursive = 84, /// Mero - Meroitic_Hieroglyphs = 83, + Meroitic_Hieroglyphs = 85, /// Mlym - Malayalam = 84, + Malayalam = 86, /// Modi - Modi = 85, + Modi = 87, /// Mong - Mongolian = 86, + Mongolian = 88, /// Mroo - Mro = 87, + Mro = 89, /// Mtei - Meetei_Mayek = 88, + Meetei_Mayek = 90, /// Mult - Multani = 89, + Multani = 91, /// Mymr - Myanmar = 90, + Myanmar = 92, + /// Nagm + Nag_Mundari = 93, /// Nand - Nandinagari = 91, + Nandinagari = 94, /// Narb - Old_North_Arabian = 92, + Old_North_Arabian = 95, /// Nbat - Nabataean = 93, + Nabataean = 96, /// Newa - Newa = 94, + Newa = 97, /// Nkoo - Nko = 95, + Nko = 98, /// Nshu - Nushu = 96, + Nushu = 99, /// Ogam - Ogham = 97, + Ogham = 100, /// Olck - Ol_Chiki = 98, + Ol_Chiki = 101, /// Orkh - Old_Turkic = 99, + Old_Turkic = 102, /// Orya - Oriya = 100, + Oriya = 103, /// Osge - Osage = 101, + Osage = 104, /// Osma - Osmanya = 102, + Osmanya = 105, + /// Ougr + Old_Uyghur = 106, /// Palm - Palmyrene = 103, + Palmyrene = 107, /// Pauc - Pau_Cin_Hau = 104, + Pau_Cin_Hau = 108, /// Perm - Old_Permic = 105, + Old_Permic = 109, /// Phag - Phags_Pa = 106, + Phags_Pa = 110, /// Phli - Inscriptional_Pahlavi = 107, + Inscriptional_Pahlavi = 111, /// Phlp - Psalter_Pahlavi = 108, + Psalter_Pahlavi = 112, /// Phnx - Phoenician = 109, + Phoenician = 113, /// Plrd - Miao = 110, + Miao = 114, /// Prti - Inscriptional_Parthian = 111, + Inscriptional_Parthian = 115, /// Rjng - Rejang = 112, + Rejang = 116, /// Rohg - Hanifi_Rohingya = 113, + Hanifi_Rohingya = 117, /// Runr - Runic = 114, + Runic = 118, /// Samr - Samaritan = 115, + Samaritan = 119, /// Sarb - Old_South_Arabian = 116, + Old_South_Arabian = 120, /// Saur - Saurashtra = 117, + Saurashtra = 121, /// Sgnw - SignWriting = 118, + SignWriting = 122, /// Shaw - Shavian = 119, + Shavian = 123, /// Shrd - Sharada = 120, + Sharada = 124, /// Sidd - Siddham = 121, + Siddham = 125, /// Sind - Khudawadi = 122, + Khudawadi = 126, /// Sinh - Sinhala = 123, + Sinhala = 127, /// Sogd - Sogdian = 124, + Sogdian = 128, /// Sogo - Old_Sogdian = 125, + Old_Sogdian = 129, /// Sora - Sora_Sompeng = 126, + Sora_Sompeng = 130, /// Soyo - Soyombo = 127, + Soyombo = 131, /// Sund - Sundanese = 128, + Sundanese = 132, /// Sylo - Syloti_Nagri = 129, + Syloti_Nagri = 133, /// Syrc - Syriac = 130, + Syriac = 134, /// Tagb - Tagbanwa = 131, + Tagbanwa = 135, /// Takr - Takri = 132, + Takri = 136, /// Tale - Tai_Le = 133, + Tai_Le = 137, /// Talu - New_Tai_Lue = 134, + New_Tai_Lue = 138, /// Taml - Tamil = 135, + Tamil = 139, /// Tang - Tangut = 136, + Tangut = 140, /// Tavt - Tai_Viet = 137, + Tai_Viet = 141, /// Telu - Telugu = 138, + Telugu = 142, /// Tfng - Tifinagh = 139, + Tifinagh = 143, /// Tglg - Tagalog = 140, + Tagalog = 144, /// Thaa - Thaana = 141, + Thaana = 145, /// Thai - Thai = 142, + Thai = 146, /// Tibt - Tibetan = 143, + Tibetan = 147, /// Tirh - Tirhuta = 144, + Tirhuta = 148, + /// Tnsa + Tangsa = 149, + /// Toto + Toto = 150, /// Ugar - Ugaritic = 145, + Ugaritic = 151, /// Vaii - Vai = 146, + Vai = 152, + /// Vith + Vithkuqi = 153, /// Wara - Warang_Citi = 147, + Warang_Citi = 154, /// Wcho - Wancho = 148, + Wancho = 155, /// Xpeo - Old_Persian = 149, + Old_Persian = 156, /// Xsux - Cuneiform = 150, + Cuneiform = 157, /// Yezi - Yezidi = 151, + Yezidi = 158, /// Yiii - Yi = 152, + Yi = 159, /// Zanb - Zanabazar_Square = 153, + Zanabazar_Square = 160, } -pub const NEXT_SCRIPT: u8 = 154; +pub const NEXT_SCRIPT: u8 = 161; pub mod script_extensions { use crate::ScriptExtension; @@ -446,518 +460,544 @@ pub mod script_extensions { pub const COPTIC: ScriptExtension = ScriptExtension::new(0x1000000, 0, 0); /// Coptic pub const COPT: ScriptExtension = COPTIC; + /// Cypro_Minoan + pub const CYPRO_MINOAN: ScriptExtension = ScriptExtension::new(0x2000000, 0, 0); + /// Cypro_Minoan + pub const CPMN: ScriptExtension = CYPRO_MINOAN; /// Cypriot - pub const CYPRIOT: ScriptExtension = ScriptExtension::new(0x2000000, 0, 0); + pub const CYPRIOT: ScriptExtension = ScriptExtension::new(0x4000000, 0, 0); /// Cypriot pub const CPRT: ScriptExtension = CYPRIOT; /// Cyrillic - pub const CYRILLIC: ScriptExtension = ScriptExtension::new(0x4000000, 0, 0); + pub const CYRILLIC: ScriptExtension = ScriptExtension::new(0x8000000, 0, 0); /// Cyrillic pub const CYRL: ScriptExtension = CYRILLIC; /// Devanagari - pub const DEVANAGARI: ScriptExtension = ScriptExtension::new(0x8000000, 0, 0); + pub const DEVANAGARI: ScriptExtension = ScriptExtension::new(0x10000000, 0, 0); /// Devanagari pub const DEVA: ScriptExtension = DEVANAGARI; /// Dives_Akuru - pub const DIVES_AKURU: ScriptExtension = ScriptExtension::new(0x10000000, 0, 0); + pub const DIVES_AKURU: ScriptExtension = ScriptExtension::new(0x20000000, 0, 0); /// Dives_Akuru pub const DIAK: ScriptExtension = DIVES_AKURU; /// Dogra - pub const DOGRA: ScriptExtension = ScriptExtension::new(0x20000000, 0, 0); + pub const DOGRA: ScriptExtension = ScriptExtension::new(0x40000000, 0, 0); /// Dogra pub const DOGR: ScriptExtension = DOGRA; /// Deseret - pub const DESERET: ScriptExtension = ScriptExtension::new(0x40000000, 0, 0); + pub const DESERET: ScriptExtension = ScriptExtension::new(0x80000000, 0, 0); /// Deseret pub const DSRT: ScriptExtension = DESERET; /// Duployan - pub const DUPLOYAN: ScriptExtension = ScriptExtension::new(0x80000000, 0, 0); + pub const DUPLOYAN: ScriptExtension = ScriptExtension::new(0x100000000, 0, 0); /// Duployan pub const DUPL: ScriptExtension = DUPLOYAN; /// Egyptian_Hieroglyphs - pub const EGYPTIAN_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0x100000000, 0, 0); + pub const EGYPTIAN_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0x200000000, 0, 0); /// Egyptian_Hieroglyphs pub const EGYP: ScriptExtension = EGYPTIAN_HIEROGLYPHS; /// Elbasan - pub const ELBASAN: ScriptExtension = ScriptExtension::new(0x200000000, 0, 0); + pub const ELBASAN: ScriptExtension = ScriptExtension::new(0x400000000, 0, 0); /// Elbasan pub const ELBA: ScriptExtension = ELBASAN; /// Elymaic - pub const ELYMAIC: ScriptExtension = ScriptExtension::new(0x400000000, 0, 0); + pub const ELYMAIC: ScriptExtension = ScriptExtension::new(0x800000000, 0, 0); /// Elymaic pub const ELYM: ScriptExtension = ELYMAIC; /// Ethiopic - pub const ETHIOPIC: ScriptExtension = ScriptExtension::new(0x800000000, 0, 0); + pub const ETHIOPIC: ScriptExtension = ScriptExtension::new(0x1000000000, 0, 0); /// Ethiopic pub const ETHI: ScriptExtension = ETHIOPIC; /// Georgian - pub const GEORGIAN: ScriptExtension = ScriptExtension::new(0x1000000000, 0, 0); + pub const GEORGIAN: ScriptExtension = ScriptExtension::new(0x2000000000, 0, 0); /// Georgian pub const GEOR: ScriptExtension = GEORGIAN; /// Glagolitic - pub const GLAGOLITIC: ScriptExtension = ScriptExtension::new(0x2000000000, 0, 0); + pub const GLAGOLITIC: ScriptExtension = ScriptExtension::new(0x4000000000, 0, 0); /// Glagolitic pub const GLAG: ScriptExtension = GLAGOLITIC; /// Gunjala_Gondi - pub const GUNJALA_GONDI: ScriptExtension = ScriptExtension::new(0x4000000000, 0, 0); + pub const GUNJALA_GONDI: ScriptExtension = ScriptExtension::new(0x8000000000, 0, 0); /// Gunjala_Gondi pub const GONG: ScriptExtension = GUNJALA_GONDI; /// Masaram_Gondi - pub const MASARAM_GONDI: ScriptExtension = ScriptExtension::new(0x8000000000, 0, 0); + pub const MASARAM_GONDI: ScriptExtension = ScriptExtension::new(0x10000000000, 0, 0); /// Masaram_Gondi pub const GONM: ScriptExtension = MASARAM_GONDI; /// Gothic - pub const GOTHIC: ScriptExtension = ScriptExtension::new(0x10000000000, 0, 0); + pub const GOTHIC: ScriptExtension = ScriptExtension::new(0x20000000000, 0, 0); /// Gothic pub const GOTH: ScriptExtension = GOTHIC; /// Grantha - pub const GRANTHA: ScriptExtension = ScriptExtension::new(0x20000000000, 0, 0); + pub const GRANTHA: ScriptExtension = ScriptExtension::new(0x40000000000, 0, 0); /// Grantha pub const GRAN: ScriptExtension = GRANTHA; /// Greek - pub const GREEK: ScriptExtension = ScriptExtension::new(0x40000000000, 0, 0); + pub const GREEK: ScriptExtension = ScriptExtension::new(0x80000000000, 0, 0); /// Greek pub const GREK: ScriptExtension = GREEK; /// Gujarati - pub const GUJARATI: ScriptExtension = ScriptExtension::new(0x80000000000, 0, 0); + pub const GUJARATI: ScriptExtension = ScriptExtension::new(0x100000000000, 0, 0); /// Gujarati pub const GUJR: ScriptExtension = GUJARATI; /// Gurmukhi - pub const GURMUKHI: ScriptExtension = ScriptExtension::new(0x100000000000, 0, 0); + pub const GURMUKHI: ScriptExtension = ScriptExtension::new(0x200000000000, 0, 0); /// Gurmukhi pub const GURU: ScriptExtension = GURMUKHI; /// Hangul - pub const HANGUL: ScriptExtension = ScriptExtension::new(0x200000000000, 0, 0); + pub const HANGUL: ScriptExtension = ScriptExtension::new(0x400000000000, 0, 0); /// Hangul pub const HANG: ScriptExtension = HANGUL; /// Han - pub const HAN: ScriptExtension = ScriptExtension::new(0x400000000000, 0, 0); + pub const HAN: ScriptExtension = ScriptExtension::new(0x800000000000, 0, 0); /// Han pub const HANI: ScriptExtension = HAN; /// Hanunoo - pub const HANUNOO: ScriptExtension = ScriptExtension::new(0x800000000000, 0, 0); + pub const HANUNOO: ScriptExtension = ScriptExtension::new(0x1000000000000, 0, 0); /// Hanunoo pub const HANO: ScriptExtension = HANUNOO; /// Hatran - pub const HATRAN: ScriptExtension = ScriptExtension::new(0x1000000000000, 0, 0); + pub const HATRAN: ScriptExtension = ScriptExtension::new(0x2000000000000, 0, 0); /// Hatran pub const HATR: ScriptExtension = HATRAN; /// Hebrew - pub const HEBREW: ScriptExtension = ScriptExtension::new(0x2000000000000, 0, 0); + pub const HEBREW: ScriptExtension = ScriptExtension::new(0x4000000000000, 0, 0); /// Hebrew pub const HEBR: ScriptExtension = HEBREW; /// Hiragana - pub const HIRAGANA: ScriptExtension = ScriptExtension::new(0x4000000000000, 0, 0); + pub const HIRAGANA: ScriptExtension = ScriptExtension::new(0x8000000000000, 0, 0); /// Hiragana pub const HIRA: ScriptExtension = HIRAGANA; /// Anatolian_Hieroglyphs - pub const ANATOLIAN_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0x8000000000000, 0, 0); + pub const ANATOLIAN_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0x10000000000000, 0, 0); /// Anatolian_Hieroglyphs pub const HLUW: ScriptExtension = ANATOLIAN_HIEROGLYPHS; /// Pahawh_Hmong - pub const PAHAWH_HMONG: ScriptExtension = ScriptExtension::new(0x10000000000000, 0, 0); + pub const PAHAWH_HMONG: ScriptExtension = ScriptExtension::new(0x20000000000000, 0, 0); /// Pahawh_Hmong pub const HMNG: ScriptExtension = PAHAWH_HMONG; /// Nyiakeng_Puachue_Hmong - pub const NYIAKENG_PUACHUE_HMONG: ScriptExtension = ScriptExtension::new(0x20000000000000, 0, 0); + pub const NYIAKENG_PUACHUE_HMONG: ScriptExtension = ScriptExtension::new(0x40000000000000, 0, 0); /// Nyiakeng_Puachue_Hmong pub const HMNP: ScriptExtension = NYIAKENG_PUACHUE_HMONG; /// Old_Hungarian - pub const OLD_HUNGARIAN: ScriptExtension = ScriptExtension::new(0x40000000000000, 0, 0); + pub const OLD_HUNGARIAN: ScriptExtension = ScriptExtension::new(0x80000000000000, 0, 0); /// Old_Hungarian pub const HUNG: ScriptExtension = OLD_HUNGARIAN; /// Old_Italic - pub const OLD_ITALIC: ScriptExtension = ScriptExtension::new(0x80000000000000, 0, 0); + pub const OLD_ITALIC: ScriptExtension = ScriptExtension::new(0x100000000000000, 0, 0); /// Old_Italic pub const ITAL: ScriptExtension = OLD_ITALIC; /// Javanese - pub const JAVANESE: ScriptExtension = ScriptExtension::new(0x100000000000000, 0, 0); + pub const JAVANESE: ScriptExtension = ScriptExtension::new(0x200000000000000, 0, 0); /// Javanese pub const JAVA: ScriptExtension = JAVANESE; /// Kayah_Li - pub const KAYAH_LI: ScriptExtension = ScriptExtension::new(0x200000000000000, 0, 0); + pub const KAYAH_LI: ScriptExtension = ScriptExtension::new(0x400000000000000, 0, 0); /// Kayah_Li pub const KALI: ScriptExtension = KAYAH_LI; /// Katakana - pub const KATAKANA: ScriptExtension = ScriptExtension::new(0x400000000000000, 0, 0); + pub const KATAKANA: ScriptExtension = ScriptExtension::new(0x800000000000000, 0, 0); /// Katakana pub const KANA: ScriptExtension = KATAKANA; + /// Kawi + pub const KAWI: ScriptExtension = ScriptExtension::new(0x1000000000000000, 0, 0); /// Kharoshthi - pub const KHAROSHTHI: ScriptExtension = ScriptExtension::new(0x800000000000000, 0, 0); + pub const KHAROSHTHI: ScriptExtension = ScriptExtension::new(0x2000000000000000, 0, 0); /// Kharoshthi pub const KHAR: ScriptExtension = KHAROSHTHI; /// Khmer - pub const KHMER: ScriptExtension = ScriptExtension::new(0x1000000000000000, 0, 0); + pub const KHMER: ScriptExtension = ScriptExtension::new(0x4000000000000000, 0, 0); /// Khmer pub const KHMR: ScriptExtension = KHMER; /// Khojki - pub const KHOJKI: ScriptExtension = ScriptExtension::new(0x2000000000000000, 0, 0); + pub const KHOJKI: ScriptExtension = ScriptExtension::new(0x8000000000000000, 0, 0); /// Khojki pub const KHOJ: ScriptExtension = KHOJKI; /// Khitan_Small_Script - pub const KHITAN_SMALL_SCRIPT: ScriptExtension = ScriptExtension::new(0x4000000000000000, 0, 0); + pub const KHITAN_SMALL_SCRIPT: ScriptExtension = ScriptExtension::new(0, 0x1, 0); /// Khitan_Small_Script pub const KITS: ScriptExtension = KHITAN_SMALL_SCRIPT; /// Kannada - pub const KANNADA: ScriptExtension = ScriptExtension::new(0x8000000000000000, 0, 0); + pub const KANNADA: ScriptExtension = ScriptExtension::new(0, 0x2, 0); /// Kannada pub const KNDA: ScriptExtension = KANNADA; /// Kaithi - pub const KAITHI: ScriptExtension = ScriptExtension::new(0, 0x1, 0); + pub const KAITHI: ScriptExtension = ScriptExtension::new(0, 0x4, 0); /// Kaithi pub const KTHI: ScriptExtension = KAITHI; /// Tai_Tham - pub const TAI_THAM: ScriptExtension = ScriptExtension::new(0, 0x2, 0); + pub const TAI_THAM: ScriptExtension = ScriptExtension::new(0, 0x8, 0); /// Tai_Tham pub const LANA: ScriptExtension = TAI_THAM; /// Lao - pub const LAO: ScriptExtension = ScriptExtension::new(0, 0x4, 0); + pub const LAO: ScriptExtension = ScriptExtension::new(0, 0x10, 0); /// Lao pub const LAOO: ScriptExtension = LAO; /// Latin - pub const LATIN: ScriptExtension = ScriptExtension::new(0, 0x8, 0); + pub const LATIN: ScriptExtension = ScriptExtension::new(0, 0x20, 0); /// Latin pub const LATN: ScriptExtension = LATIN; /// Lepcha - pub const LEPCHA: ScriptExtension = ScriptExtension::new(0, 0x10, 0); + pub const LEPCHA: ScriptExtension = ScriptExtension::new(0, 0x40, 0); /// Lepcha pub const LEPC: ScriptExtension = LEPCHA; /// Limbu - pub const LIMBU: ScriptExtension = ScriptExtension::new(0, 0x20, 0); + pub const LIMBU: ScriptExtension = ScriptExtension::new(0, 0x80, 0); /// Limbu pub const LIMB: ScriptExtension = LIMBU; /// Linear_A - pub const LINEAR_A: ScriptExtension = ScriptExtension::new(0, 0x40, 0); + pub const LINEAR_A: ScriptExtension = ScriptExtension::new(0, 0x100, 0); /// Linear_A pub const LINA: ScriptExtension = LINEAR_A; /// Linear_B - pub const LINEAR_B: ScriptExtension = ScriptExtension::new(0, 0x80, 0); + pub const LINEAR_B: ScriptExtension = ScriptExtension::new(0, 0x200, 0); /// Linear_B pub const LINB: ScriptExtension = LINEAR_B; /// Lisu - pub const LISU: ScriptExtension = ScriptExtension::new(0, 0x100, 0); + pub const LISU: ScriptExtension = ScriptExtension::new(0, 0x400, 0); /// Lycian - pub const LYCIAN: ScriptExtension = ScriptExtension::new(0, 0x200, 0); + pub const LYCIAN: ScriptExtension = ScriptExtension::new(0, 0x800, 0); /// Lycian pub const LYCI: ScriptExtension = LYCIAN; /// Lydian - pub const LYDIAN: ScriptExtension = ScriptExtension::new(0, 0x400, 0); + pub const LYDIAN: ScriptExtension = ScriptExtension::new(0, 0x1000, 0); /// Lydian pub const LYDI: ScriptExtension = LYDIAN; /// Mahajani - pub const MAHAJANI: ScriptExtension = ScriptExtension::new(0, 0x800, 0); + pub const MAHAJANI: ScriptExtension = ScriptExtension::new(0, 0x2000, 0); /// Mahajani pub const MAHJ: ScriptExtension = MAHAJANI; /// Makasar - pub const MAKASAR: ScriptExtension = ScriptExtension::new(0, 0x1000, 0); + pub const MAKASAR: ScriptExtension = ScriptExtension::new(0, 0x4000, 0); /// Makasar pub const MAKA: ScriptExtension = MAKASAR; /// Mandaic - pub const MANDAIC: ScriptExtension = ScriptExtension::new(0, 0x2000, 0); + pub const MANDAIC: ScriptExtension = ScriptExtension::new(0, 0x8000, 0); /// Mandaic pub const MAND: ScriptExtension = MANDAIC; /// Manichaean - pub const MANICHAEAN: ScriptExtension = ScriptExtension::new(0, 0x4000, 0); + pub const MANICHAEAN: ScriptExtension = ScriptExtension::new(0, 0x10000, 0); /// Manichaean pub const MANI: ScriptExtension = MANICHAEAN; /// Marchen - pub const MARCHEN: ScriptExtension = ScriptExtension::new(0, 0x8000, 0); + pub const MARCHEN: ScriptExtension = ScriptExtension::new(0, 0x20000, 0); /// Marchen pub const MARC: ScriptExtension = MARCHEN; /// Medefaidrin - pub const MEDEFAIDRIN: ScriptExtension = ScriptExtension::new(0, 0x10000, 0); + pub const MEDEFAIDRIN: ScriptExtension = ScriptExtension::new(0, 0x40000, 0); /// Medefaidrin pub const MEDF: ScriptExtension = MEDEFAIDRIN; /// Mende_Kikakui - pub const MENDE_KIKAKUI: ScriptExtension = ScriptExtension::new(0, 0x20000, 0); + pub const MENDE_KIKAKUI: ScriptExtension = ScriptExtension::new(0, 0x80000, 0); /// Mende_Kikakui pub const MEND: ScriptExtension = MENDE_KIKAKUI; /// Meroitic_Cursive - pub const MEROITIC_CURSIVE: ScriptExtension = ScriptExtension::new(0, 0x40000, 0); + pub const MEROITIC_CURSIVE: ScriptExtension = ScriptExtension::new(0, 0x100000, 0); /// Meroitic_Cursive pub const MERC: ScriptExtension = MEROITIC_CURSIVE; /// Meroitic_Hieroglyphs - pub const MEROITIC_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0, 0x80000, 0); + pub const MEROITIC_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0, 0x200000, 0); /// Meroitic_Hieroglyphs pub const MERO: ScriptExtension = MEROITIC_HIEROGLYPHS; /// Malayalam - pub const MALAYALAM: ScriptExtension = ScriptExtension::new(0, 0x100000, 0); + pub const MALAYALAM: ScriptExtension = ScriptExtension::new(0, 0x400000, 0); /// Malayalam pub const MLYM: ScriptExtension = MALAYALAM; /// Modi - pub const MODI: ScriptExtension = ScriptExtension::new(0, 0x200000, 0); + pub const MODI: ScriptExtension = ScriptExtension::new(0, 0x800000, 0); /// Mongolian - pub const MONGOLIAN: ScriptExtension = ScriptExtension::new(0, 0x400000, 0); + pub const MONGOLIAN: ScriptExtension = ScriptExtension::new(0, 0x1000000, 0); /// Mongolian pub const MONG: ScriptExtension = MONGOLIAN; /// Mro - pub const MRO: ScriptExtension = ScriptExtension::new(0, 0x800000, 0); + pub const MRO: ScriptExtension = ScriptExtension::new(0, 0x2000000, 0); /// Mro pub const MROO: ScriptExtension = MRO; /// Meetei_Mayek - pub const MEETEI_MAYEK: ScriptExtension = ScriptExtension::new(0, 0x1000000, 0); + pub const MEETEI_MAYEK: ScriptExtension = ScriptExtension::new(0, 0x4000000, 0); /// Meetei_Mayek pub const MTEI: ScriptExtension = MEETEI_MAYEK; /// Multani - pub const MULTANI: ScriptExtension = ScriptExtension::new(0, 0x2000000, 0); + pub const MULTANI: ScriptExtension = ScriptExtension::new(0, 0x8000000, 0); /// Multani pub const MULT: ScriptExtension = MULTANI; /// Myanmar - pub const MYANMAR: ScriptExtension = ScriptExtension::new(0, 0x4000000, 0); + pub const MYANMAR: ScriptExtension = ScriptExtension::new(0, 0x10000000, 0); /// Myanmar pub const MYMR: ScriptExtension = MYANMAR; + /// Nag_Mundari + pub const NAG_MUNDARI: ScriptExtension = ScriptExtension::new(0, 0x20000000, 0); + /// Nag_Mundari + pub const NAGM: ScriptExtension = NAG_MUNDARI; /// Nandinagari - pub const NANDINAGARI: ScriptExtension = ScriptExtension::new(0, 0x8000000, 0); + pub const NANDINAGARI: ScriptExtension = ScriptExtension::new(0, 0x40000000, 0); /// Nandinagari pub const NAND: ScriptExtension = NANDINAGARI; /// Old_North_Arabian - pub const OLD_NORTH_ARABIAN: ScriptExtension = ScriptExtension::new(0, 0x10000000, 0); + pub const OLD_NORTH_ARABIAN: ScriptExtension = ScriptExtension::new(0, 0x80000000, 0); /// Old_North_Arabian pub const NARB: ScriptExtension = OLD_NORTH_ARABIAN; /// Nabataean - pub const NABATAEAN: ScriptExtension = ScriptExtension::new(0, 0x20000000, 0); + pub const NABATAEAN: ScriptExtension = ScriptExtension::new(0, 0x100000000, 0); /// Nabataean pub const NBAT: ScriptExtension = NABATAEAN; /// Newa - pub const NEWA: ScriptExtension = ScriptExtension::new(0, 0x40000000, 0); + pub const NEWA: ScriptExtension = ScriptExtension::new(0, 0x200000000, 0); /// Nko - pub const NKO: ScriptExtension = ScriptExtension::new(0, 0x80000000, 0); + pub const NKO: ScriptExtension = ScriptExtension::new(0, 0x400000000, 0); /// Nko pub const NKOO: ScriptExtension = NKO; /// Nushu - pub const NUSHU: ScriptExtension = ScriptExtension::new(0, 0x100000000, 0); + pub const NUSHU: ScriptExtension = ScriptExtension::new(0, 0x800000000, 0); /// Nushu pub const NSHU: ScriptExtension = NUSHU; /// Ogham - pub const OGHAM: ScriptExtension = ScriptExtension::new(0, 0x200000000, 0); + pub const OGHAM: ScriptExtension = ScriptExtension::new(0, 0x1000000000, 0); /// Ogham pub const OGAM: ScriptExtension = OGHAM; /// Ol_Chiki - pub const OL_CHIKI: ScriptExtension = ScriptExtension::new(0, 0x400000000, 0); + pub const OL_CHIKI: ScriptExtension = ScriptExtension::new(0, 0x2000000000, 0); /// Ol_Chiki pub const OLCK: ScriptExtension = OL_CHIKI; /// Old_Turkic - pub const OLD_TURKIC: ScriptExtension = ScriptExtension::new(0, 0x800000000, 0); + pub const OLD_TURKIC: ScriptExtension = ScriptExtension::new(0, 0x4000000000, 0); /// Old_Turkic pub const ORKH: ScriptExtension = OLD_TURKIC; /// Oriya - pub const ORIYA: ScriptExtension = ScriptExtension::new(0, 0x1000000000, 0); + pub const ORIYA: ScriptExtension = ScriptExtension::new(0, 0x8000000000, 0); /// Oriya pub const ORYA: ScriptExtension = ORIYA; /// Osage - pub const OSAGE: ScriptExtension = ScriptExtension::new(0, 0x2000000000, 0); + pub const OSAGE: ScriptExtension = ScriptExtension::new(0, 0x10000000000, 0); /// Osage pub const OSGE: ScriptExtension = OSAGE; /// Osmanya - pub const OSMANYA: ScriptExtension = ScriptExtension::new(0, 0x4000000000, 0); + pub const OSMANYA: ScriptExtension = ScriptExtension::new(0, 0x20000000000, 0); /// Osmanya pub const OSMA: ScriptExtension = OSMANYA; + /// Old_Uyghur + pub const OLD_UYGHUR: ScriptExtension = ScriptExtension::new(0, 0x40000000000, 0); + /// Old_Uyghur + pub const OUGR: ScriptExtension = OLD_UYGHUR; /// Palmyrene - pub const PALMYRENE: ScriptExtension = ScriptExtension::new(0, 0x8000000000, 0); + pub const PALMYRENE: ScriptExtension = ScriptExtension::new(0, 0x80000000000, 0); /// Palmyrene pub const PALM: ScriptExtension = PALMYRENE; /// Pau_Cin_Hau - pub const PAU_CIN_HAU: ScriptExtension = ScriptExtension::new(0, 0x10000000000, 0); + pub const PAU_CIN_HAU: ScriptExtension = ScriptExtension::new(0, 0x100000000000, 0); /// Pau_Cin_Hau pub const PAUC: ScriptExtension = PAU_CIN_HAU; /// Old_Permic - pub const OLD_PERMIC: ScriptExtension = ScriptExtension::new(0, 0x20000000000, 0); + pub const OLD_PERMIC: ScriptExtension = ScriptExtension::new(0, 0x200000000000, 0); /// Old_Permic pub const PERM: ScriptExtension = OLD_PERMIC; /// Phags_Pa - pub const PHAGS_PA: ScriptExtension = ScriptExtension::new(0, 0x40000000000, 0); + pub const PHAGS_PA: ScriptExtension = ScriptExtension::new(0, 0x400000000000, 0); /// Phags_Pa pub const PHAG: ScriptExtension = PHAGS_PA; /// Inscriptional_Pahlavi - pub const INSCRIPTIONAL_PAHLAVI: ScriptExtension = ScriptExtension::new(0, 0x80000000000, 0); + pub const INSCRIPTIONAL_PAHLAVI: ScriptExtension = ScriptExtension::new(0, 0x800000000000, 0); /// Inscriptional_Pahlavi pub const PHLI: ScriptExtension = INSCRIPTIONAL_PAHLAVI; /// Psalter_Pahlavi - pub const PSALTER_PAHLAVI: ScriptExtension = ScriptExtension::new(0, 0x100000000000, 0); + pub const PSALTER_PAHLAVI: ScriptExtension = ScriptExtension::new(0, 0x1000000000000, 0); /// Psalter_Pahlavi pub const PHLP: ScriptExtension = PSALTER_PAHLAVI; /// Phoenician - pub const PHOENICIAN: ScriptExtension = ScriptExtension::new(0, 0x200000000000, 0); + pub const PHOENICIAN: ScriptExtension = ScriptExtension::new(0, 0x2000000000000, 0); /// Phoenician pub const PHNX: ScriptExtension = PHOENICIAN; /// Miao - pub const MIAO: ScriptExtension = ScriptExtension::new(0, 0x400000000000, 0); + pub const MIAO: ScriptExtension = ScriptExtension::new(0, 0x4000000000000, 0); /// Miao pub const PLRD: ScriptExtension = MIAO; /// Inscriptional_Parthian - pub const INSCRIPTIONAL_PARTHIAN: ScriptExtension = ScriptExtension::new(0, 0x800000000000, 0); + pub const INSCRIPTIONAL_PARTHIAN: ScriptExtension = ScriptExtension::new(0, 0x8000000000000, 0); /// Inscriptional_Parthian pub const PRTI: ScriptExtension = INSCRIPTIONAL_PARTHIAN; /// Rejang - pub const REJANG: ScriptExtension = ScriptExtension::new(0, 0x1000000000000, 0); + pub const REJANG: ScriptExtension = ScriptExtension::new(0, 0x10000000000000, 0); /// Rejang pub const RJNG: ScriptExtension = REJANG; /// Hanifi_Rohingya - pub const HANIFI_ROHINGYA: ScriptExtension = ScriptExtension::new(0, 0x2000000000000, 0); + pub const HANIFI_ROHINGYA: ScriptExtension = ScriptExtension::new(0, 0x20000000000000, 0); /// Hanifi_Rohingya pub const ROHG: ScriptExtension = HANIFI_ROHINGYA; /// Runic - pub const RUNIC: ScriptExtension = ScriptExtension::new(0, 0x4000000000000, 0); + pub const RUNIC: ScriptExtension = ScriptExtension::new(0, 0x40000000000000, 0); /// Runic pub const RUNR: ScriptExtension = RUNIC; /// Samaritan - pub const SAMARITAN: ScriptExtension = ScriptExtension::new(0, 0x8000000000000, 0); + pub const SAMARITAN: ScriptExtension = ScriptExtension::new(0, 0x80000000000000, 0); /// Samaritan pub const SAMR: ScriptExtension = SAMARITAN; /// Old_South_Arabian - pub const OLD_SOUTH_ARABIAN: ScriptExtension = ScriptExtension::new(0, 0x10000000000000, 0); + pub const OLD_SOUTH_ARABIAN: ScriptExtension = ScriptExtension::new(0, 0x100000000000000, 0); /// Old_South_Arabian pub const SARB: ScriptExtension = OLD_SOUTH_ARABIAN; /// Saurashtra - pub const SAURASHTRA: ScriptExtension = ScriptExtension::new(0, 0x20000000000000, 0); + pub const SAURASHTRA: ScriptExtension = ScriptExtension::new(0, 0x200000000000000, 0); /// Saurashtra pub const SAUR: ScriptExtension = SAURASHTRA; /// SignWriting - pub const SIGNWRITING: ScriptExtension = ScriptExtension::new(0, 0x40000000000000, 0); + pub const SIGNWRITING: ScriptExtension = ScriptExtension::new(0, 0x400000000000000, 0); /// SignWriting pub const SGNW: ScriptExtension = SIGNWRITING; /// Shavian - pub const SHAVIAN: ScriptExtension = ScriptExtension::new(0, 0x80000000000000, 0); + pub const SHAVIAN: ScriptExtension = ScriptExtension::new(0, 0x800000000000000, 0); /// Shavian pub const SHAW: ScriptExtension = SHAVIAN; /// Sharada - pub const SHARADA: ScriptExtension = ScriptExtension::new(0, 0x100000000000000, 0); + pub const SHARADA: ScriptExtension = ScriptExtension::new(0, 0x1000000000000000, 0); /// Sharada pub const SHRD: ScriptExtension = SHARADA; /// Siddham - pub const SIDDHAM: ScriptExtension = ScriptExtension::new(0, 0x200000000000000, 0); + pub const SIDDHAM: ScriptExtension = ScriptExtension::new(0, 0x2000000000000000, 0); /// Siddham pub const SIDD: ScriptExtension = SIDDHAM; /// Khudawadi - pub const KHUDAWADI: ScriptExtension = ScriptExtension::new(0, 0x400000000000000, 0); + pub const KHUDAWADI: ScriptExtension = ScriptExtension::new(0, 0x4000000000000000, 0); /// Khudawadi pub const SIND: ScriptExtension = KHUDAWADI; /// Sinhala - pub const SINHALA: ScriptExtension = ScriptExtension::new(0, 0x800000000000000, 0); + pub const SINHALA: ScriptExtension = ScriptExtension::new(0, 0x8000000000000000, 0); /// Sinhala pub const SINH: ScriptExtension = SINHALA; /// Sogdian - pub const SOGDIAN: ScriptExtension = ScriptExtension::new(0, 0x1000000000000000, 0); + pub const SOGDIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x1); /// Sogdian pub const SOGD: ScriptExtension = SOGDIAN; /// Old_Sogdian - pub const OLD_SOGDIAN: ScriptExtension = ScriptExtension::new(0, 0x2000000000000000, 0); + pub const OLD_SOGDIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x2); /// Old_Sogdian pub const SOGO: ScriptExtension = OLD_SOGDIAN; /// Sora_Sompeng - pub const SORA_SOMPENG: ScriptExtension = ScriptExtension::new(0, 0x4000000000000000, 0); + pub const SORA_SOMPENG: ScriptExtension = ScriptExtension::new(0, 0, 0x4); /// Sora_Sompeng pub const SORA: ScriptExtension = SORA_SOMPENG; /// Soyombo - pub const SOYOMBO: ScriptExtension = ScriptExtension::new(0, 0x8000000000000000, 0); + pub const SOYOMBO: ScriptExtension = ScriptExtension::new(0, 0, 0x8); /// Soyombo pub const SOYO: ScriptExtension = SOYOMBO; /// Sundanese - pub const SUNDANESE: ScriptExtension = ScriptExtension::new(0, 0, 0x1); + pub const SUNDANESE: ScriptExtension = ScriptExtension::new(0, 0, 0x10); /// Sundanese pub const SUND: ScriptExtension = SUNDANESE; /// Syloti_Nagri - pub const SYLOTI_NAGRI: ScriptExtension = ScriptExtension::new(0, 0, 0x2); + pub const SYLOTI_NAGRI: ScriptExtension = ScriptExtension::new(0, 0, 0x20); /// Syloti_Nagri pub const SYLO: ScriptExtension = SYLOTI_NAGRI; /// Syriac - pub const SYRIAC: ScriptExtension = ScriptExtension::new(0, 0, 0x4); + pub const SYRIAC: ScriptExtension = ScriptExtension::new(0, 0, 0x40); /// Syriac pub const SYRC: ScriptExtension = SYRIAC; /// Tagbanwa - pub const TAGBANWA: ScriptExtension = ScriptExtension::new(0, 0, 0x8); + pub const TAGBANWA: ScriptExtension = ScriptExtension::new(0, 0, 0x80); /// Tagbanwa pub const TAGB: ScriptExtension = TAGBANWA; /// Takri - pub const TAKRI: ScriptExtension = ScriptExtension::new(0, 0, 0x10); + pub const TAKRI: ScriptExtension = ScriptExtension::new(0, 0, 0x100); /// Takri pub const TAKR: ScriptExtension = TAKRI; /// Tai_Le - pub const TAI_LE: ScriptExtension = ScriptExtension::new(0, 0, 0x20); + pub const TAI_LE: ScriptExtension = ScriptExtension::new(0, 0, 0x200); /// Tai_Le pub const TALE: ScriptExtension = TAI_LE; /// New_Tai_Lue - pub const NEW_TAI_LUE: ScriptExtension = ScriptExtension::new(0, 0, 0x40); + pub const NEW_TAI_LUE: ScriptExtension = ScriptExtension::new(0, 0, 0x400); /// New_Tai_Lue pub const TALU: ScriptExtension = NEW_TAI_LUE; /// Tamil - pub const TAMIL: ScriptExtension = ScriptExtension::new(0, 0, 0x80); + pub const TAMIL: ScriptExtension = ScriptExtension::new(0, 0, 0x800); /// Tamil pub const TAML: ScriptExtension = TAMIL; /// Tangut - pub const TANGUT: ScriptExtension = ScriptExtension::new(0, 0, 0x100); + pub const TANGUT: ScriptExtension = ScriptExtension::new(0, 0, 0x1000); /// Tangut pub const TANG: ScriptExtension = TANGUT; /// Tai_Viet - pub const TAI_VIET: ScriptExtension = ScriptExtension::new(0, 0, 0x200); + pub const TAI_VIET: ScriptExtension = ScriptExtension::new(0, 0, 0x2000); /// Tai_Viet pub const TAVT: ScriptExtension = TAI_VIET; /// Telugu - pub const TELUGU: ScriptExtension = ScriptExtension::new(0, 0, 0x400); + pub const TELUGU: ScriptExtension = ScriptExtension::new(0, 0, 0x4000); /// Telugu pub const TELU: ScriptExtension = TELUGU; /// Tifinagh - pub const TIFINAGH: ScriptExtension = ScriptExtension::new(0, 0, 0x800); + pub const TIFINAGH: ScriptExtension = ScriptExtension::new(0, 0, 0x8000); /// Tifinagh pub const TFNG: ScriptExtension = TIFINAGH; /// Tagalog - pub const TAGALOG: ScriptExtension = ScriptExtension::new(0, 0, 0x1000); + pub const TAGALOG: ScriptExtension = ScriptExtension::new(0, 0, 0x10000); /// Tagalog pub const TGLG: ScriptExtension = TAGALOG; /// Thaana - pub const THAANA: ScriptExtension = ScriptExtension::new(0, 0, 0x2000); + pub const THAANA: ScriptExtension = ScriptExtension::new(0, 0, 0x20000); /// Thaana pub const THAA: ScriptExtension = THAANA; /// Thai - pub const THAI: ScriptExtension = ScriptExtension::new(0, 0, 0x4000); + pub const THAI: ScriptExtension = ScriptExtension::new(0, 0, 0x40000); /// Tibetan - pub const TIBETAN: ScriptExtension = ScriptExtension::new(0, 0, 0x8000); + pub const TIBETAN: ScriptExtension = ScriptExtension::new(0, 0, 0x80000); /// Tibetan pub const TIBT: ScriptExtension = TIBETAN; /// Tirhuta - pub const TIRHUTA: ScriptExtension = ScriptExtension::new(0, 0, 0x10000); + pub const TIRHUTA: ScriptExtension = ScriptExtension::new(0, 0, 0x100000); /// Tirhuta pub const TIRH: ScriptExtension = TIRHUTA; + /// Tangsa + pub const TANGSA: ScriptExtension = ScriptExtension::new(0, 0, 0x200000); + /// Tangsa + pub const TNSA: ScriptExtension = TANGSA; + /// Toto + pub const TOTO: ScriptExtension = ScriptExtension::new(0, 0, 0x400000); /// Ugaritic - pub const UGARITIC: ScriptExtension = ScriptExtension::new(0, 0, 0x20000); + pub const UGARITIC: ScriptExtension = ScriptExtension::new(0, 0, 0x800000); /// Ugaritic pub const UGAR: ScriptExtension = UGARITIC; /// Vai - pub const VAI: ScriptExtension = ScriptExtension::new(0, 0, 0x40000); + pub const VAI: ScriptExtension = ScriptExtension::new(0, 0, 0x1000000); /// Vai pub const VAII: ScriptExtension = VAI; + /// Vithkuqi + pub const VITHKUQI: ScriptExtension = ScriptExtension::new(0, 0, 0x2000000); + /// Vithkuqi + pub const VITH: ScriptExtension = VITHKUQI; /// Warang_Citi - pub const WARANG_CITI: ScriptExtension = ScriptExtension::new(0, 0, 0x80000); + pub const WARANG_CITI: ScriptExtension = ScriptExtension::new(0, 0, 0x4000000); /// Warang_Citi pub const WARA: ScriptExtension = WARANG_CITI; /// Wancho - pub const WANCHO: ScriptExtension = ScriptExtension::new(0, 0, 0x100000); + pub const WANCHO: ScriptExtension = ScriptExtension::new(0, 0, 0x8000000); /// Wancho pub const WCHO: ScriptExtension = WANCHO; /// Old_Persian - pub const OLD_PERSIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x200000); + pub const OLD_PERSIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x10000000); /// Old_Persian pub const XPEO: ScriptExtension = OLD_PERSIAN; /// Cuneiform - pub const CUNEIFORM: ScriptExtension = ScriptExtension::new(0, 0, 0x400000); + pub const CUNEIFORM: ScriptExtension = ScriptExtension::new(0, 0, 0x20000000); /// Cuneiform pub const XSUX: ScriptExtension = CUNEIFORM; /// Yezidi - pub const YEZIDI: ScriptExtension = ScriptExtension::new(0, 0, 0x800000); + pub const YEZIDI: ScriptExtension = ScriptExtension::new(0, 0, 0x40000000); /// Yezidi pub const YEZI: ScriptExtension = YEZIDI; /// Yi - pub const YI: ScriptExtension = ScriptExtension::new(0, 0, 0x1000000); + pub const YI: ScriptExtension = ScriptExtension::new(0, 0, 0x80000000); /// Yi pub const YIII: ScriptExtension = YI; /// Zanabazar_Square - pub const ZANABAZAR_SQUARE: ScriptExtension = ScriptExtension::new(0, 0, 0x2000000); + pub const ZANABAZAR_SQUARE: ScriptExtension = ScriptExtension::new(0, 0, 0x100000000); /// Zanabazar_Square pub const ZANB: ScriptExtension = ZANABAZAR_SQUARE; /// Arabic, Coptic pub const ARAB_COPT: ScriptExtension = ARAB.union(COPT); /// Arabic, Hanifi_Rohingya pub const ARAB_ROHG: ScriptExtension = ARAB.union(ROHG); + /// Arabic, Nko + pub const ARAB_NKOO: ScriptExtension = ARAB.union(NKOO); /// Arabic, Syriac pub const ARAB_SYRC: ScriptExtension = ARAB.union(SYRC); /// Arabic, Thaana @@ -1002,6 +1042,8 @@ pub mod script_extensions { pub const KNDA_NAND: ScriptExtension = KNDA.union(NAND); /// Latin, Mongolian pub const LATN_MONG: ScriptExtension = LATN.union(MONG); + /// Manichaean, Old_Uyghur + pub const MANI_OUGR: ScriptExtension = MANI.union(OUGR); /// Mongolian, Phags_Pa pub const MONG_PHAG: ScriptExtension = MONG.union(PHAG); /// Arabic, Syriac, Thaana @@ -1012,6 +1054,8 @@ pub mod script_extensions { pub const BENG_CAKM_SYLO: ScriptExtension = BENG.union(CAKM).union(SYLO); /// Chakma, Myanmar, Tai_Le pub const CAKM_MYMR_TALE: ScriptExtension = CAKM.union(MYMR).union(TALE); + /// Cypro_Minoan, Cypriot, Linear_B + pub const CPMN_CPRT_LINB: ScriptExtension = CPMN.union(CPRT).union(LINB); /// Cypriot, Linear_A, Linear_B pub const CPRT_LINA_LINB: ScriptExtension = CPRT.union(LINA).union(LINB); /// Devanagari, Grantha, Kannada @@ -1028,18 +1072,20 @@ pub mod script_extensions { pub const BUHD_HANO_TAGB_TGLG: ScriptExtension = BUHD.union(HANO).union(TAGB).union(TGLG); /// Devanagari, Dogra, Kaithi, Mahajani pub const DEVA_DOGR_KTHI_MAHJ: ScriptExtension = DEVA.union(DOGR).union(KTHI).union(MAHJ); - /// Arabic, Hanifi_Rohingya, Syriac, Thaana, Yezidi - pub const ARAB_ROHG_SYRC_THAA_YEZI: ScriptExtension = ARAB.union(ROHG).union(SYRC).union(THAA).union(YEZI); /// Bopomofo, Hangul, Han, Hiragana, Katakana pub const BOPO_HANG_HANI_HIRA_KANA: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA); + /// Arabic, Nko, Hanifi_Rohingya, Syriac, Thaana, Yezidi + pub const ARAB_NKOO_ROHG_SYRC_THAA_YEZI: ScriptExtension = ARAB.union(NKOO).union(ROHG).union(SYRC).union(THAA).union(YEZI); /// Bopomofo, Hangul, Han, Hiragana, Katakana, Yi pub const BOPO_HANG_HANI_HIRA_KANA_YIII: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA).union(YIII); /// Devanagari, Kannada, Malayalam, Oriya, Tamil, Telugu pub const DEVA_KNDA_MLYM_ORYA_TAML_TELU: ScriptExtension = DEVA.union(KNDA).union(MLYM).union(ORYA).union(TAML).union(TELU); - /// Adlam, Arabic, Mandaic, Manichaean, Psalter_Pahlavi, Hanifi_Rohingya, Sogdian, Syriac - pub const ADLM_ARAB_MAND_MANI_PHLP_ROHG_SOGD_SYRC: ScriptExtension = ADLM.union(ARAB).union(MAND).union(MANI).union(PHLP).union(ROHG).union(SOGD).union(SYRC); + /// Adlam, Arabic, Nko, Hanifi_Rohingya, Syriac, Thaana, Yezidi + pub const ADLM_ARAB_NKOO_ROHG_SYRC_THAA_YEZI: ScriptExtension = ADLM.union(ARAB).union(NKOO).union(ROHG).union(SYRC).union(THAA).union(YEZI); /// Bengali, Devanagari, Grantha, Kannada, Nandinagari, Oriya, Telugu, Tirhuta pub const BENG_DEVA_GRAN_KNDA_NAND_ORYA_TELU_TIRH: ScriptExtension = BENG.union(DEVA).union(GRAN).union(KNDA).union(NAND).union(ORYA).union(TELU).union(TIRH); + /// Adlam, Arabic, Mandaic, Manichaean, Old_Uyghur, Psalter_Pahlavi, Hanifi_Rohingya, Sogdian, Syriac + pub const ADLM_ARAB_MAND_MANI_OUGR_PHLP_ROHG_SOGD_SYRC: ScriptExtension = ADLM.union(ARAB).union(MAND).union(MANI).union(OUGR).union(PHLP).union(ROHG).union(SOGD).union(SYRC); /// Devanagari, Dogra, Gujarati, Gurmukhi, Khojki, Kaithi, Mahajani, Modi, Khudawadi, Takri, Tirhuta pub const DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SIND_TAKR_TIRH: ScriptExtension = DEVA.union(DOGR).union(GUJR).union(GURU).union(KHOJ).union(KTHI).union(MAHJ).union(MODI).union(SIND).union(TAKR).union(TIRH); /// Bengali, Devanagari, Grantha, Gujarati, Gurmukhi, Kannada, Latin, Malayalam, Oriya, Tamil, Telugu, Tirhuta @@ -1089,6 +1135,7 @@ impl Script { Script::Cherokee => "Cherokee", Script::Chorasmian => "Chorasmian", Script::Coptic => "Coptic", + Script::Cypro_Minoan => "Cypro_Minoan", Script::Cypriot => "Cypriot", Script::Cyrillic => "Cyrillic", Script::Devanagari => "Devanagari", @@ -1123,6 +1170,7 @@ impl Script { Script::Javanese => "Javanese", Script::Kayah_Li => "Kayah_Li", Script::Katakana => "Katakana", + Script::Kawi => "Kawi", Script::Kharoshthi => "Kharoshthi", Script::Khmer => "Khmer", Script::Khojki => "Khojki", @@ -1155,6 +1203,7 @@ impl Script { Script::Meetei_Mayek => "Meetei_Mayek", Script::Multani => "Multani", Script::Myanmar => "Myanmar", + Script::Nag_Mundari => "Nag_Mundari", Script::Nandinagari => "Nandinagari", Script::Old_North_Arabian => "Old_North_Arabian", Script::Nabataean => "Nabataean", @@ -1167,6 +1216,7 @@ impl Script { Script::Oriya => "Oriya", Script::Osage => "Osage", Script::Osmanya => "Osmanya", + Script::Old_Uyghur => "Old_Uyghur", Script::Palmyrene => "Palmyrene", Script::Pau_Cin_Hau => "Pau_Cin_Hau", Script::Old_Permic => "Old_Permic", @@ -1209,8 +1259,11 @@ impl Script { Script::Thai => "Thai", Script::Tibetan => "Tibetan", Script::Tirhuta => "Tirhuta", + Script::Tangsa => "Tangsa", + Script::Toto => "Toto", Script::Ugaritic => "Ugaritic", Script::Vai => "Vai", + Script::Vithkuqi => "Vithkuqi", Script::Warang_Citi => "Warang_Citi", Script::Wancho => "Wancho", Script::Old_Persian => "Old_Persian", @@ -1252,6 +1305,7 @@ impl Script { "Cherokee" => Some(Script::Cherokee), "Chorasmian" => Some(Script::Chorasmian), "Coptic" => Some(Script::Coptic), + "Cypro_Minoan" => Some(Script::Cypro_Minoan), "Cypriot" => Some(Script::Cypriot), "Cyrillic" => Some(Script::Cyrillic), "Devanagari" => Some(Script::Devanagari), @@ -1286,6 +1340,7 @@ impl Script { "Javanese" => Some(Script::Javanese), "Kayah_Li" => Some(Script::Kayah_Li), "Katakana" => Some(Script::Katakana), + "Kawi" => Some(Script::Kawi), "Kharoshthi" => Some(Script::Kharoshthi), "Khmer" => Some(Script::Khmer), "Khojki" => Some(Script::Khojki), @@ -1318,6 +1373,7 @@ impl Script { "Meetei_Mayek" => Some(Script::Meetei_Mayek), "Multani" => Some(Script::Multani), "Myanmar" => Some(Script::Myanmar), + "Nag_Mundari" => Some(Script::Nag_Mundari), "Nandinagari" => Some(Script::Nandinagari), "Old_North_Arabian" => Some(Script::Old_North_Arabian), "Nabataean" => Some(Script::Nabataean), @@ -1330,6 +1386,7 @@ impl Script { "Oriya" => Some(Script::Oriya), "Osage" => Some(Script::Osage), "Osmanya" => Some(Script::Osmanya), + "Old_Uyghur" => Some(Script::Old_Uyghur), "Palmyrene" => Some(Script::Palmyrene), "Pau_Cin_Hau" => Some(Script::Pau_Cin_Hau), "Old_Permic" => Some(Script::Old_Permic), @@ -1372,8 +1429,11 @@ impl Script { "Thai" => Some(Script::Thai), "Tibetan" => Some(Script::Tibetan), "Tirhuta" => Some(Script::Tirhuta), + "Tangsa" => Some(Script::Tangsa), + "Toto" => Some(Script::Toto), "Ugaritic" => Some(Script::Ugaritic), "Vai" => Some(Script::Vai), + "Vithkuqi" => Some(Script::Vithkuqi), "Warang_Citi" => Some(Script::Warang_Citi), "Wancho" => Some(Script::Wancho), "Old_Persian" => Some(Script::Old_Persian), @@ -1416,6 +1476,7 @@ impl Script { Script::Cherokee => "Cher", Script::Chorasmian => "Chrs", Script::Coptic => "Copt", + Script::Cypro_Minoan => "Cpmn", Script::Cypriot => "Cprt", Script::Cyrillic => "Cyrl", Script::Devanagari => "Deva", @@ -1450,6 +1511,7 @@ impl Script { Script::Javanese => "Java", Script::Kayah_Li => "Kali", Script::Katakana => "Kana", + Script::Kawi => "Kawi", Script::Kharoshthi => "Khar", Script::Khmer => "Khmr", Script::Khojki => "Khoj", @@ -1482,6 +1544,7 @@ impl Script { Script::Meetei_Mayek => "Mtei", Script::Multani => "Mult", Script::Myanmar => "Mymr", + Script::Nag_Mundari => "Nagm", Script::Nandinagari => "Nand", Script::Old_North_Arabian => "Narb", Script::Nabataean => "Nbat", @@ -1494,6 +1557,7 @@ impl Script { Script::Oriya => "Orya", Script::Osage => "Osge", Script::Osmanya => "Osma", + Script::Old_Uyghur => "Ougr", Script::Palmyrene => "Palm", Script::Pau_Cin_Hau => "Pauc", Script::Old_Permic => "Perm", @@ -1536,8 +1600,11 @@ impl Script { Script::Thai => "Thai", Script::Tibetan => "Tibt", Script::Tirhuta => "Tirh", + Script::Tangsa => "Tnsa", + Script::Toto => "Toto", Script::Ugaritic => "Ugar", Script::Vai => "Vaii", + Script::Vithkuqi => "Vith", Script::Warang_Citi => "Wara", Script::Wancho => "Wcho", Script::Old_Persian => "Xpeo", @@ -1578,6 +1645,7 @@ impl Script { "Cher" => Some(Script::Cherokee), "Chrs" => Some(Script::Chorasmian), "Copt" => Some(Script::Coptic), + "Cpmn" => Some(Script::Cypro_Minoan), "Cprt" => Some(Script::Cypriot), "Cyrl" => Some(Script::Cyrillic), "Deva" => Some(Script::Devanagari), @@ -1612,6 +1680,7 @@ impl Script { "Java" => Some(Script::Javanese), "Kali" => Some(Script::Kayah_Li), "Kana" => Some(Script::Katakana), + "Kawi" => Some(Script::Kawi), "Khar" => Some(Script::Kharoshthi), "Khmr" => Some(Script::Khmer), "Khoj" => Some(Script::Khojki), @@ -1644,6 +1713,7 @@ impl Script { "Mtei" => Some(Script::Meetei_Mayek), "Mult" => Some(Script::Multani), "Mymr" => Some(Script::Myanmar), + "Nagm" => Some(Script::Nag_Mundari), "Nand" => Some(Script::Nandinagari), "Narb" => Some(Script::Old_North_Arabian), "Nbat" => Some(Script::Nabataean), @@ -1656,6 +1726,7 @@ impl Script { "Orya" => Some(Script::Oriya), "Osge" => Some(Script::Osage), "Osma" => Some(Script::Osmanya), + "Ougr" => Some(Script::Old_Uyghur), "Palm" => Some(Script::Palmyrene), "Pauc" => Some(Script::Pau_Cin_Hau), "Perm" => Some(Script::Old_Permic), @@ -1698,8 +1769,11 @@ impl Script { "Thai" => Some(Script::Thai), "Tibt" => Some(Script::Tibetan), "Tirh" => Some(Script::Tirhuta), + "Tnsa" => Some(Script::Tangsa), + "Toto" => Some(Script::Toto), "Ugar" => Some(Script::Ugaritic), "Vaii" => Some(Script::Vai), + "Vith" => Some(Script::Vithkuqi), "Wara" => Some(Script::Warang_Citi), "Wcho" => Some(Script::Wancho), "Xpeo" => Some(Script::Old_Persian), @@ -1739,135 +1813,142 @@ impl Script { 22 => Script::Cherokee, 23 => Script::Chorasmian, 24 => Script::Coptic, - 25 => Script::Cypriot, - 26 => Script::Cyrillic, - 27 => Script::Devanagari, - 28 => Script::Dives_Akuru, - 29 => Script::Dogra, - 30 => Script::Deseret, - 31 => Script::Duployan, - 32 => Script::Egyptian_Hieroglyphs, - 33 => Script::Elbasan, - 34 => Script::Elymaic, - 35 => Script::Ethiopic, - 36 => Script::Georgian, - 37 => Script::Glagolitic, - 38 => Script::Gunjala_Gondi, - 39 => Script::Masaram_Gondi, - 40 => Script::Gothic, - 41 => Script::Grantha, - 42 => Script::Greek, - 43 => Script::Gujarati, - 44 => Script::Gurmukhi, - 45 => Script::Hangul, - 46 => Script::Han, - 47 => Script::Hanunoo, - 48 => Script::Hatran, - 49 => Script::Hebrew, - 50 => Script::Hiragana, - 51 => Script::Anatolian_Hieroglyphs, - 52 => Script::Pahawh_Hmong, - 53 => Script::Nyiakeng_Puachue_Hmong, - 54 => Script::Old_Hungarian, - 55 => Script::Old_Italic, - 56 => Script::Javanese, - 57 => Script::Kayah_Li, - 58 => Script::Katakana, - 59 => Script::Kharoshthi, - 60 => Script::Khmer, - 61 => Script::Khojki, - 62 => Script::Khitan_Small_Script, - 63 => Script::Kannada, - 64 => Script::Kaithi, - 65 => Script::Tai_Tham, - 66 => Script::Lao, - 67 => Script::Latin, - 68 => Script::Lepcha, - 69 => Script::Limbu, - 70 => Script::Linear_A, - 71 => Script::Linear_B, - 72 => Script::Lisu, - 73 => Script::Lycian, - 74 => Script::Lydian, - 75 => Script::Mahajani, - 76 => Script::Makasar, - 77 => Script::Mandaic, - 78 => Script::Manichaean, - 79 => Script::Marchen, - 80 => Script::Medefaidrin, - 81 => Script::Mende_Kikakui, - 82 => Script::Meroitic_Cursive, - 83 => Script::Meroitic_Hieroglyphs, - 84 => Script::Malayalam, - 85 => Script::Modi, - 86 => Script::Mongolian, - 87 => Script::Mro, - 88 => Script::Meetei_Mayek, - 89 => Script::Multani, - 90 => Script::Myanmar, - 91 => Script::Nandinagari, - 92 => Script::Old_North_Arabian, - 93 => Script::Nabataean, - 94 => Script::Newa, - 95 => Script::Nko, - 96 => Script::Nushu, - 97 => Script::Ogham, - 98 => Script::Ol_Chiki, - 99 => Script::Old_Turkic, - 100 => Script::Oriya, - 101 => Script::Osage, - 102 => Script::Osmanya, - 103 => Script::Palmyrene, - 104 => Script::Pau_Cin_Hau, - 105 => Script::Old_Permic, - 106 => Script::Phags_Pa, - 107 => Script::Inscriptional_Pahlavi, - 108 => Script::Psalter_Pahlavi, - 109 => Script::Phoenician, - 110 => Script::Miao, - 111 => Script::Inscriptional_Parthian, - 112 => Script::Rejang, - 113 => Script::Hanifi_Rohingya, - 114 => Script::Runic, - 115 => Script::Samaritan, - 116 => Script::Old_South_Arabian, - 117 => Script::Saurashtra, - 118 => Script::SignWriting, - 119 => Script::Shavian, - 120 => Script::Sharada, - 121 => Script::Siddham, - 122 => Script::Khudawadi, - 123 => Script::Sinhala, - 124 => Script::Sogdian, - 125 => Script::Old_Sogdian, - 126 => Script::Sora_Sompeng, - 127 => Script::Soyombo, - 128 => Script::Sundanese, - 129 => Script::Syloti_Nagri, - 130 => Script::Syriac, - 131 => Script::Tagbanwa, - 132 => Script::Takri, - 133 => Script::Tai_Le, - 134 => Script::New_Tai_Lue, - 135 => Script::Tamil, - 136 => Script::Tangut, - 137 => Script::Tai_Viet, - 138 => Script::Telugu, - 139 => Script::Tifinagh, - 140 => Script::Tagalog, - 141 => Script::Thaana, - 142 => Script::Thai, - 143 => Script::Tibetan, - 144 => Script::Tirhuta, - 145 => Script::Ugaritic, - 146 => Script::Vai, - 147 => Script::Warang_Citi, - 148 => Script::Wancho, - 149 => Script::Old_Persian, - 150 => Script::Cuneiform, - 151 => Script::Yezidi, - 152 => Script::Yi, - 153 => Script::Zanabazar_Square, + 25 => Script::Cypro_Minoan, + 26 => Script::Cypriot, + 27 => Script::Cyrillic, + 28 => Script::Devanagari, + 29 => Script::Dives_Akuru, + 30 => Script::Dogra, + 31 => Script::Deseret, + 32 => Script::Duployan, + 33 => Script::Egyptian_Hieroglyphs, + 34 => Script::Elbasan, + 35 => Script::Elymaic, + 36 => Script::Ethiopic, + 37 => Script::Georgian, + 38 => Script::Glagolitic, + 39 => Script::Gunjala_Gondi, + 40 => Script::Masaram_Gondi, + 41 => Script::Gothic, + 42 => Script::Grantha, + 43 => Script::Greek, + 44 => Script::Gujarati, + 45 => Script::Gurmukhi, + 46 => Script::Hangul, + 47 => Script::Han, + 48 => Script::Hanunoo, + 49 => Script::Hatran, + 50 => Script::Hebrew, + 51 => Script::Hiragana, + 52 => Script::Anatolian_Hieroglyphs, + 53 => Script::Pahawh_Hmong, + 54 => Script::Nyiakeng_Puachue_Hmong, + 55 => Script::Old_Hungarian, + 56 => Script::Old_Italic, + 57 => Script::Javanese, + 58 => Script::Kayah_Li, + 59 => Script::Katakana, + 60 => Script::Kawi, + 61 => Script::Kharoshthi, + 62 => Script::Khmer, + 63 => Script::Khojki, + 64 => Script::Khitan_Small_Script, + 65 => Script::Kannada, + 66 => Script::Kaithi, + 67 => Script::Tai_Tham, + 68 => Script::Lao, + 69 => Script::Latin, + 70 => Script::Lepcha, + 71 => Script::Limbu, + 72 => Script::Linear_A, + 73 => Script::Linear_B, + 74 => Script::Lisu, + 75 => Script::Lycian, + 76 => Script::Lydian, + 77 => Script::Mahajani, + 78 => Script::Makasar, + 79 => Script::Mandaic, + 80 => Script::Manichaean, + 81 => Script::Marchen, + 82 => Script::Medefaidrin, + 83 => Script::Mende_Kikakui, + 84 => Script::Meroitic_Cursive, + 85 => Script::Meroitic_Hieroglyphs, + 86 => Script::Malayalam, + 87 => Script::Modi, + 88 => Script::Mongolian, + 89 => Script::Mro, + 90 => Script::Meetei_Mayek, + 91 => Script::Multani, + 92 => Script::Myanmar, + 93 => Script::Nag_Mundari, + 94 => Script::Nandinagari, + 95 => Script::Old_North_Arabian, + 96 => Script::Nabataean, + 97 => Script::Newa, + 98 => Script::Nko, + 99 => Script::Nushu, + 100 => Script::Ogham, + 101 => Script::Ol_Chiki, + 102 => Script::Old_Turkic, + 103 => Script::Oriya, + 104 => Script::Osage, + 105 => Script::Osmanya, + 106 => Script::Old_Uyghur, + 107 => Script::Palmyrene, + 108 => Script::Pau_Cin_Hau, + 109 => Script::Old_Permic, + 110 => Script::Phags_Pa, + 111 => Script::Inscriptional_Pahlavi, + 112 => Script::Psalter_Pahlavi, + 113 => Script::Phoenician, + 114 => Script::Miao, + 115 => Script::Inscriptional_Parthian, + 116 => Script::Rejang, + 117 => Script::Hanifi_Rohingya, + 118 => Script::Runic, + 119 => Script::Samaritan, + 120 => Script::Old_South_Arabian, + 121 => Script::Saurashtra, + 122 => Script::SignWriting, + 123 => Script::Shavian, + 124 => Script::Sharada, + 125 => Script::Siddham, + 126 => Script::Khudawadi, + 127 => Script::Sinhala, + 128 => Script::Sogdian, + 129 => Script::Old_Sogdian, + 130 => Script::Sora_Sompeng, + 131 => Script::Soyombo, + 132 => Script::Sundanese, + 133 => Script::Syloti_Nagri, + 134 => Script::Syriac, + 135 => Script::Tagbanwa, + 136 => Script::Takri, + 137 => Script::Tai_Le, + 138 => Script::New_Tai_Lue, + 139 => Script::Tamil, + 140 => Script::Tangut, + 141 => Script::Tai_Viet, + 142 => Script::Telugu, + 143 => Script::Tifinagh, + 144 => Script::Tagalog, + 145 => Script::Thaana, + 146 => Script::Thai, + 147 => Script::Tibetan, + 148 => Script::Tirhuta, + 149 => Script::Tangsa, + 150 => Script::Toto, + 151 => Script::Ugaritic, + 152 => Script::Vai, + 153 => Script::Vithkuqi, + 154 => Script::Warang_Citi, + 155 => Script::Wancho, + 156 => Script::Old_Persian, + 157 => Script::Cuneiform, + 158 => Script::Yezidi, + 159 => Script::Yi, + 160 => Script::Zanabazar_Square, _ => unreachable!(), } } @@ -1966,7 +2047,7 @@ pub fn get_script_extension(c: char) -> Option { Script::Arabic), ('\u{60b}', '\u{60b}', Script::Arabic), ('\u{60c}', '\u{60c}', Script::Common), ('\u{60d}', '\u{60d}', Script::Arabic), ('\u{60e}', '\u{60f}', Script::Arabic), ('\u{610}', '\u{61a}', Script::Arabic), ('\u{61b}', '\u{61b}', - Script::Common), ('\u{61c}', '\u{61c}', Script::Arabic), ('\u{61e}', '\u{61e}', + Script::Common), ('\u{61c}', '\u{61c}', Script::Arabic), ('\u{61d}', '\u{61e}', Script::Arabic), ('\u{61f}', '\u{61f}', Script::Common), ('\u{620}', '\u{63f}', Script::Arabic), ('\u{640}', '\u{640}', Script::Common), ('\u{641}', '\u{64a}', Script::Arabic), ('\u{64b}', '\u{655}', Script::Inherited), ('\u{656}', '\u{65f}', @@ -1996,105 +2077,109 @@ pub fn get_script_extension(c: char) -> Option { Script::Samaritan), ('\u{829}', '\u{82d}', Script::Samaritan), ('\u{830}', '\u{83e}', Script::Samaritan), ('\u{840}', '\u{858}', Script::Mandaic), ('\u{859}', '\u{85b}', Script::Mandaic), ('\u{85e}', '\u{85e}', Script::Mandaic), ('\u{860}', '\u{86a}', - Script::Syriac), ('\u{8a0}', '\u{8b4}', Script::Arabic), ('\u{8b6}', '\u{8c7}', - Script::Arabic), ('\u{8d3}', '\u{8e1}', Script::Arabic), ('\u{8e2}', '\u{8e2}', - Script::Common), ('\u{8e3}', '\u{8ff}', Script::Arabic), ('\u{900}', '\u{902}', - Script::Devanagari), ('\u{903}', '\u{903}', Script::Devanagari), ('\u{904}', '\u{939}', - Script::Devanagari), ('\u{93a}', '\u{93a}', Script::Devanagari), ('\u{93b}', '\u{93b}', - Script::Devanagari), ('\u{93c}', '\u{93c}', Script::Devanagari), ('\u{93d}', '\u{93d}', - Script::Devanagari), ('\u{93e}', '\u{940}', Script::Devanagari), ('\u{941}', '\u{948}', - Script::Devanagari), ('\u{949}', '\u{94c}', Script::Devanagari), ('\u{94d}', '\u{94d}', - Script::Devanagari), ('\u{94e}', '\u{94f}', Script::Devanagari), ('\u{950}', '\u{950}', - Script::Devanagari), ('\u{951}', '\u{954}', Script::Inherited), ('\u{955}', '\u{957}', - Script::Devanagari), ('\u{958}', '\u{961}', Script::Devanagari), ('\u{962}', '\u{963}', - Script::Devanagari), ('\u{964}', '\u{965}', Script::Common), ('\u{966}', '\u{96f}', - Script::Devanagari), ('\u{970}', '\u{970}', Script::Devanagari), ('\u{971}', '\u{971}', - Script::Devanagari), ('\u{972}', '\u{97f}', Script::Devanagari), ('\u{980}', '\u{980}', - Script::Bengali), ('\u{981}', '\u{981}', Script::Bengali), ('\u{982}', '\u{983}', - Script::Bengali), ('\u{985}', '\u{98c}', Script::Bengali), ('\u{98f}', '\u{990}', - Script::Bengali), ('\u{993}', '\u{9a8}', Script::Bengali), ('\u{9aa}', '\u{9b0}', - Script::Bengali), ('\u{9b2}', '\u{9b2}', Script::Bengali), ('\u{9b6}', '\u{9b9}', - Script::Bengali), ('\u{9bc}', '\u{9bc}', Script::Bengali), ('\u{9bd}', '\u{9bd}', - Script::Bengali), ('\u{9be}', '\u{9c0}', Script::Bengali), ('\u{9c1}', '\u{9c4}', - Script::Bengali), ('\u{9c7}', '\u{9c8}', Script::Bengali), ('\u{9cb}', '\u{9cc}', - Script::Bengali), ('\u{9cd}', '\u{9cd}', Script::Bengali), ('\u{9ce}', '\u{9ce}', - Script::Bengali), ('\u{9d7}', '\u{9d7}', Script::Bengali), ('\u{9dc}', '\u{9dd}', - Script::Bengali), ('\u{9df}', '\u{9e1}', Script::Bengali), ('\u{9e2}', '\u{9e3}', - Script::Bengali), ('\u{9e6}', '\u{9ef}', Script::Bengali), ('\u{9f0}', '\u{9f1}', - Script::Bengali), ('\u{9f2}', '\u{9f3}', Script::Bengali), ('\u{9f4}', '\u{9f9}', - Script::Bengali), ('\u{9fa}', '\u{9fa}', Script::Bengali), ('\u{9fb}', '\u{9fb}', - Script::Bengali), ('\u{9fc}', '\u{9fc}', Script::Bengali), ('\u{9fd}', '\u{9fd}', - Script::Bengali), ('\u{9fe}', '\u{9fe}', Script::Bengali), ('\u{a01}', '\u{a02}', - Script::Gurmukhi), ('\u{a03}', '\u{a03}', Script::Gurmukhi), ('\u{a05}', '\u{a0a}', - Script::Gurmukhi), ('\u{a0f}', '\u{a10}', Script::Gurmukhi), ('\u{a13}', '\u{a28}', - Script::Gurmukhi), ('\u{a2a}', '\u{a30}', Script::Gurmukhi), ('\u{a32}', '\u{a33}', - Script::Gurmukhi), ('\u{a35}', '\u{a36}', Script::Gurmukhi), ('\u{a38}', '\u{a39}', - Script::Gurmukhi), ('\u{a3c}', '\u{a3c}', Script::Gurmukhi), ('\u{a3e}', '\u{a40}', - Script::Gurmukhi), ('\u{a41}', '\u{a42}', Script::Gurmukhi), ('\u{a47}', '\u{a48}', - Script::Gurmukhi), ('\u{a4b}', '\u{a4d}', Script::Gurmukhi), ('\u{a51}', '\u{a51}', - Script::Gurmukhi), ('\u{a59}', '\u{a5c}', Script::Gurmukhi), ('\u{a5e}', '\u{a5e}', - Script::Gurmukhi), ('\u{a66}', '\u{a6f}', Script::Gurmukhi), ('\u{a70}', '\u{a71}', - Script::Gurmukhi), ('\u{a72}', '\u{a74}', Script::Gurmukhi), ('\u{a75}', '\u{a75}', - Script::Gurmukhi), ('\u{a76}', '\u{a76}', Script::Gurmukhi), ('\u{a81}', '\u{a82}', - Script::Gujarati), ('\u{a83}', '\u{a83}', Script::Gujarati), ('\u{a85}', '\u{a8d}', - Script::Gujarati), ('\u{a8f}', '\u{a91}', Script::Gujarati), ('\u{a93}', '\u{aa8}', - Script::Gujarati), ('\u{aaa}', '\u{ab0}', Script::Gujarati), ('\u{ab2}', '\u{ab3}', - Script::Gujarati), ('\u{ab5}', '\u{ab9}', Script::Gujarati), ('\u{abc}', '\u{abc}', - Script::Gujarati), ('\u{abd}', '\u{abd}', Script::Gujarati), ('\u{abe}', '\u{ac0}', - Script::Gujarati), ('\u{ac1}', '\u{ac5}', Script::Gujarati), ('\u{ac7}', '\u{ac8}', - Script::Gujarati), ('\u{ac9}', '\u{ac9}', Script::Gujarati), ('\u{acb}', '\u{acc}', - Script::Gujarati), ('\u{acd}', '\u{acd}', Script::Gujarati), ('\u{ad0}', '\u{ad0}', - Script::Gujarati), ('\u{ae0}', '\u{ae1}', Script::Gujarati), ('\u{ae2}', '\u{ae3}', - Script::Gujarati), ('\u{ae6}', '\u{aef}', Script::Gujarati), ('\u{af0}', '\u{af0}', - Script::Gujarati), ('\u{af1}', '\u{af1}', Script::Gujarati), ('\u{af9}', '\u{af9}', - Script::Gujarati), ('\u{afa}', '\u{aff}', Script::Gujarati), ('\u{b01}', '\u{b01}', - Script::Oriya), ('\u{b02}', '\u{b03}', Script::Oriya), ('\u{b05}', '\u{b0c}', - Script::Oriya), ('\u{b0f}', '\u{b10}', Script::Oriya), ('\u{b13}', '\u{b28}', - Script::Oriya), ('\u{b2a}', '\u{b30}', Script::Oriya), ('\u{b32}', '\u{b33}', - Script::Oriya), ('\u{b35}', '\u{b39}', Script::Oriya), ('\u{b3c}', '\u{b3c}', - Script::Oriya), ('\u{b3d}', '\u{b3d}', Script::Oriya), ('\u{b3e}', '\u{b3e}', - Script::Oriya), ('\u{b3f}', '\u{b3f}', Script::Oriya), ('\u{b40}', '\u{b40}', - Script::Oriya), ('\u{b41}', '\u{b44}', Script::Oriya), ('\u{b47}', '\u{b48}', - Script::Oriya), ('\u{b4b}', '\u{b4c}', Script::Oriya), ('\u{b4d}', '\u{b4d}', - Script::Oriya), ('\u{b55}', '\u{b56}', Script::Oriya), ('\u{b57}', '\u{b57}', - Script::Oriya), ('\u{b5c}', '\u{b5d}', Script::Oriya), ('\u{b5f}', '\u{b61}', - Script::Oriya), ('\u{b62}', '\u{b63}', Script::Oriya), ('\u{b66}', '\u{b6f}', - Script::Oriya), ('\u{b70}', '\u{b70}', Script::Oriya), ('\u{b71}', '\u{b71}', - Script::Oriya), ('\u{b72}', '\u{b77}', Script::Oriya), ('\u{b82}', '\u{b82}', - Script::Tamil), ('\u{b83}', '\u{b83}', Script::Tamil), ('\u{b85}', '\u{b8a}', - Script::Tamil), ('\u{b8e}', '\u{b90}', Script::Tamil), ('\u{b92}', '\u{b95}', - Script::Tamil), ('\u{b99}', '\u{b9a}', Script::Tamil), ('\u{b9c}', '\u{b9c}', - Script::Tamil), ('\u{b9e}', '\u{b9f}', Script::Tamil), ('\u{ba3}', '\u{ba4}', - Script::Tamil), ('\u{ba8}', '\u{baa}', Script::Tamil), ('\u{bae}', '\u{bb9}', - Script::Tamil), ('\u{bbe}', '\u{bbf}', Script::Tamil), ('\u{bc0}', '\u{bc0}', - Script::Tamil), ('\u{bc1}', '\u{bc2}', Script::Tamil), ('\u{bc6}', '\u{bc8}', - Script::Tamil), ('\u{bca}', '\u{bcc}', Script::Tamil), ('\u{bcd}', '\u{bcd}', - Script::Tamil), ('\u{bd0}', '\u{bd0}', Script::Tamil), ('\u{bd7}', '\u{bd7}', - Script::Tamil), ('\u{be6}', '\u{bef}', Script::Tamil), ('\u{bf0}', '\u{bf2}', - Script::Tamil), ('\u{bf3}', '\u{bf8}', Script::Tamil), ('\u{bf9}', '\u{bf9}', - Script::Tamil), ('\u{bfa}', '\u{bfa}', Script::Tamil), ('\u{c00}', '\u{c00}', - Script::Telugu), ('\u{c01}', '\u{c03}', Script::Telugu), ('\u{c04}', '\u{c04}', - Script::Telugu), ('\u{c05}', '\u{c0c}', Script::Telugu), ('\u{c0e}', '\u{c10}', - Script::Telugu), ('\u{c12}', '\u{c28}', Script::Telugu), ('\u{c2a}', '\u{c39}', + Script::Syriac), ('\u{870}', '\u{887}', Script::Arabic), ('\u{888}', '\u{888}', + Script::Arabic), ('\u{889}', '\u{88e}', Script::Arabic), ('\u{890}', '\u{891}', + Script::Arabic), ('\u{898}', '\u{89f}', Script::Arabic), ('\u{8a0}', '\u{8c8}', + Script::Arabic), ('\u{8c9}', '\u{8c9}', Script::Arabic), ('\u{8ca}', '\u{8e1}', + Script::Arabic), ('\u{8e2}', '\u{8e2}', Script::Common), ('\u{8e3}', '\u{8ff}', + Script::Arabic), ('\u{900}', '\u{902}', Script::Devanagari), ('\u{903}', '\u{903}', + Script::Devanagari), ('\u{904}', '\u{939}', Script::Devanagari), ('\u{93a}', '\u{93a}', + Script::Devanagari), ('\u{93b}', '\u{93b}', Script::Devanagari), ('\u{93c}', '\u{93c}', + Script::Devanagari), ('\u{93d}', '\u{93d}', Script::Devanagari), ('\u{93e}', '\u{940}', + Script::Devanagari), ('\u{941}', '\u{948}', Script::Devanagari), ('\u{949}', '\u{94c}', + Script::Devanagari), ('\u{94d}', '\u{94d}', Script::Devanagari), ('\u{94e}', '\u{94f}', + Script::Devanagari), ('\u{950}', '\u{950}', Script::Devanagari), ('\u{951}', '\u{954}', + Script::Inherited), ('\u{955}', '\u{957}', Script::Devanagari), ('\u{958}', '\u{961}', + Script::Devanagari), ('\u{962}', '\u{963}', Script::Devanagari), ('\u{964}', '\u{965}', + Script::Common), ('\u{966}', '\u{96f}', Script::Devanagari), ('\u{970}', '\u{970}', + Script::Devanagari), ('\u{971}', '\u{971}', Script::Devanagari), ('\u{972}', '\u{97f}', + Script::Devanagari), ('\u{980}', '\u{980}', Script::Bengali), ('\u{981}', '\u{981}', + Script::Bengali), ('\u{982}', '\u{983}', Script::Bengali), ('\u{985}', '\u{98c}', + Script::Bengali), ('\u{98f}', '\u{990}', Script::Bengali), ('\u{993}', '\u{9a8}', + Script::Bengali), ('\u{9aa}', '\u{9b0}', Script::Bengali), ('\u{9b2}', '\u{9b2}', + Script::Bengali), ('\u{9b6}', '\u{9b9}', Script::Bengali), ('\u{9bc}', '\u{9bc}', + Script::Bengali), ('\u{9bd}', '\u{9bd}', Script::Bengali), ('\u{9be}', '\u{9c0}', + Script::Bengali), ('\u{9c1}', '\u{9c4}', Script::Bengali), ('\u{9c7}', '\u{9c8}', + Script::Bengali), ('\u{9cb}', '\u{9cc}', Script::Bengali), ('\u{9cd}', '\u{9cd}', + Script::Bengali), ('\u{9ce}', '\u{9ce}', Script::Bengali), ('\u{9d7}', '\u{9d7}', + Script::Bengali), ('\u{9dc}', '\u{9dd}', Script::Bengali), ('\u{9df}', '\u{9e1}', + Script::Bengali), ('\u{9e2}', '\u{9e3}', Script::Bengali), ('\u{9e6}', '\u{9ef}', + Script::Bengali), ('\u{9f0}', '\u{9f1}', Script::Bengali), ('\u{9f2}', '\u{9f3}', + Script::Bengali), ('\u{9f4}', '\u{9f9}', Script::Bengali), ('\u{9fa}', '\u{9fa}', + Script::Bengali), ('\u{9fb}', '\u{9fb}', Script::Bengali), ('\u{9fc}', '\u{9fc}', + Script::Bengali), ('\u{9fd}', '\u{9fd}', Script::Bengali), ('\u{9fe}', '\u{9fe}', + Script::Bengali), ('\u{a01}', '\u{a02}', Script::Gurmukhi), ('\u{a03}', '\u{a03}', + Script::Gurmukhi), ('\u{a05}', '\u{a0a}', Script::Gurmukhi), ('\u{a0f}', '\u{a10}', + Script::Gurmukhi), ('\u{a13}', '\u{a28}', Script::Gurmukhi), ('\u{a2a}', '\u{a30}', + Script::Gurmukhi), ('\u{a32}', '\u{a33}', Script::Gurmukhi), ('\u{a35}', '\u{a36}', + Script::Gurmukhi), ('\u{a38}', '\u{a39}', Script::Gurmukhi), ('\u{a3c}', '\u{a3c}', + Script::Gurmukhi), ('\u{a3e}', '\u{a40}', Script::Gurmukhi), ('\u{a41}', '\u{a42}', + Script::Gurmukhi), ('\u{a47}', '\u{a48}', Script::Gurmukhi), ('\u{a4b}', '\u{a4d}', + Script::Gurmukhi), ('\u{a51}', '\u{a51}', Script::Gurmukhi), ('\u{a59}', '\u{a5c}', + Script::Gurmukhi), ('\u{a5e}', '\u{a5e}', Script::Gurmukhi), ('\u{a66}', '\u{a6f}', + Script::Gurmukhi), ('\u{a70}', '\u{a71}', Script::Gurmukhi), ('\u{a72}', '\u{a74}', + Script::Gurmukhi), ('\u{a75}', '\u{a75}', Script::Gurmukhi), ('\u{a76}', '\u{a76}', + Script::Gurmukhi), ('\u{a81}', '\u{a82}', Script::Gujarati), ('\u{a83}', '\u{a83}', + Script::Gujarati), ('\u{a85}', '\u{a8d}', Script::Gujarati), ('\u{a8f}', '\u{a91}', + Script::Gujarati), ('\u{a93}', '\u{aa8}', Script::Gujarati), ('\u{aaa}', '\u{ab0}', + Script::Gujarati), ('\u{ab2}', '\u{ab3}', Script::Gujarati), ('\u{ab5}', '\u{ab9}', + Script::Gujarati), ('\u{abc}', '\u{abc}', Script::Gujarati), ('\u{abd}', '\u{abd}', + Script::Gujarati), ('\u{abe}', '\u{ac0}', Script::Gujarati), ('\u{ac1}', '\u{ac5}', + Script::Gujarati), ('\u{ac7}', '\u{ac8}', Script::Gujarati), ('\u{ac9}', '\u{ac9}', + Script::Gujarati), ('\u{acb}', '\u{acc}', Script::Gujarati), ('\u{acd}', '\u{acd}', + Script::Gujarati), ('\u{ad0}', '\u{ad0}', Script::Gujarati), ('\u{ae0}', '\u{ae1}', + Script::Gujarati), ('\u{ae2}', '\u{ae3}', Script::Gujarati), ('\u{ae6}', '\u{aef}', + Script::Gujarati), ('\u{af0}', '\u{af0}', Script::Gujarati), ('\u{af1}', '\u{af1}', + Script::Gujarati), ('\u{af9}', '\u{af9}', Script::Gujarati), ('\u{afa}', '\u{aff}', + Script::Gujarati), ('\u{b01}', '\u{b01}', Script::Oriya), ('\u{b02}', '\u{b03}', + Script::Oriya), ('\u{b05}', '\u{b0c}', Script::Oriya), ('\u{b0f}', '\u{b10}', + Script::Oriya), ('\u{b13}', '\u{b28}', Script::Oriya), ('\u{b2a}', '\u{b30}', + Script::Oriya), ('\u{b32}', '\u{b33}', Script::Oriya), ('\u{b35}', '\u{b39}', + Script::Oriya), ('\u{b3c}', '\u{b3c}', Script::Oriya), ('\u{b3d}', '\u{b3d}', + Script::Oriya), ('\u{b3e}', '\u{b3e}', Script::Oriya), ('\u{b3f}', '\u{b3f}', + Script::Oriya), ('\u{b40}', '\u{b40}', Script::Oriya), ('\u{b41}', '\u{b44}', + Script::Oriya), ('\u{b47}', '\u{b48}', Script::Oriya), ('\u{b4b}', '\u{b4c}', + Script::Oriya), ('\u{b4d}', '\u{b4d}', Script::Oriya), ('\u{b55}', '\u{b56}', + Script::Oriya), ('\u{b57}', '\u{b57}', Script::Oriya), ('\u{b5c}', '\u{b5d}', + Script::Oriya), ('\u{b5f}', '\u{b61}', Script::Oriya), ('\u{b62}', '\u{b63}', + Script::Oriya), ('\u{b66}', '\u{b6f}', Script::Oriya), ('\u{b70}', '\u{b70}', + Script::Oriya), ('\u{b71}', '\u{b71}', Script::Oriya), ('\u{b72}', '\u{b77}', + Script::Oriya), ('\u{b82}', '\u{b82}', Script::Tamil), ('\u{b83}', '\u{b83}', + Script::Tamil), ('\u{b85}', '\u{b8a}', Script::Tamil), ('\u{b8e}', '\u{b90}', + Script::Tamil), ('\u{b92}', '\u{b95}', Script::Tamil), ('\u{b99}', '\u{b9a}', + Script::Tamil), ('\u{b9c}', '\u{b9c}', Script::Tamil), ('\u{b9e}', '\u{b9f}', + Script::Tamil), ('\u{ba3}', '\u{ba4}', Script::Tamil), ('\u{ba8}', '\u{baa}', + Script::Tamil), ('\u{bae}', '\u{bb9}', Script::Tamil), ('\u{bbe}', '\u{bbf}', + Script::Tamil), ('\u{bc0}', '\u{bc0}', Script::Tamil), ('\u{bc1}', '\u{bc2}', + Script::Tamil), ('\u{bc6}', '\u{bc8}', Script::Tamil), ('\u{bca}', '\u{bcc}', + Script::Tamil), ('\u{bcd}', '\u{bcd}', Script::Tamil), ('\u{bd0}', '\u{bd0}', + Script::Tamil), ('\u{bd7}', '\u{bd7}', Script::Tamil), ('\u{be6}', '\u{bef}', + Script::Tamil), ('\u{bf0}', '\u{bf2}', Script::Tamil), ('\u{bf3}', '\u{bf8}', + Script::Tamil), ('\u{bf9}', '\u{bf9}', Script::Tamil), ('\u{bfa}', '\u{bfa}', + Script::Tamil), ('\u{c00}', '\u{c00}', Script::Telugu), ('\u{c01}', '\u{c03}', + Script::Telugu), ('\u{c04}', '\u{c04}', Script::Telugu), ('\u{c05}', '\u{c0c}', + Script::Telugu), ('\u{c0e}', '\u{c10}', Script::Telugu), ('\u{c12}', '\u{c28}', + Script::Telugu), ('\u{c2a}', '\u{c39}', Script::Telugu), ('\u{c3c}', '\u{c3c}', Script::Telugu), ('\u{c3d}', '\u{c3d}', Script::Telugu), ('\u{c3e}', '\u{c40}', Script::Telugu), ('\u{c41}', '\u{c44}', Script::Telugu), ('\u{c46}', '\u{c48}', Script::Telugu), ('\u{c4a}', '\u{c4d}', Script::Telugu), ('\u{c55}', '\u{c56}', - Script::Telugu), ('\u{c58}', '\u{c5a}', Script::Telugu), ('\u{c60}', '\u{c61}', - Script::Telugu), ('\u{c62}', '\u{c63}', Script::Telugu), ('\u{c66}', '\u{c6f}', - Script::Telugu), ('\u{c77}', '\u{c77}', Script::Telugu), ('\u{c78}', '\u{c7e}', - Script::Telugu), ('\u{c7f}', '\u{c7f}', Script::Telugu), ('\u{c80}', '\u{c80}', - Script::Kannada), ('\u{c81}', '\u{c81}', Script::Kannada), ('\u{c82}', '\u{c83}', - Script::Kannada), ('\u{c84}', '\u{c84}', Script::Kannada), ('\u{c85}', '\u{c8c}', - Script::Kannada), ('\u{c8e}', '\u{c90}', Script::Kannada), ('\u{c92}', '\u{ca8}', - Script::Kannada), ('\u{caa}', '\u{cb3}', Script::Kannada), ('\u{cb5}', '\u{cb9}', - Script::Kannada), ('\u{cbc}', '\u{cbc}', Script::Kannada), ('\u{cbd}', '\u{cbd}', - Script::Kannada), ('\u{cbe}', '\u{cbe}', Script::Kannada), ('\u{cbf}', '\u{cbf}', - Script::Kannada), ('\u{cc0}', '\u{cc4}', Script::Kannada), ('\u{cc6}', '\u{cc6}', - Script::Kannada), ('\u{cc7}', '\u{cc8}', Script::Kannada), ('\u{cca}', '\u{ccb}', - Script::Kannada), ('\u{ccc}', '\u{ccd}', Script::Kannada), ('\u{cd5}', '\u{cd6}', - Script::Kannada), ('\u{cde}', '\u{cde}', Script::Kannada), ('\u{ce0}', '\u{ce1}', - Script::Kannada), ('\u{ce2}', '\u{ce3}', Script::Kannada), ('\u{ce6}', '\u{cef}', - Script::Kannada), ('\u{cf1}', '\u{cf2}', Script::Kannada), ('\u{d00}', '\u{d01}', + Script::Telugu), ('\u{c58}', '\u{c5a}', Script::Telugu), ('\u{c5d}', '\u{c5d}', + Script::Telugu), ('\u{c60}', '\u{c61}', Script::Telugu), ('\u{c62}', '\u{c63}', + Script::Telugu), ('\u{c66}', '\u{c6f}', Script::Telugu), ('\u{c77}', '\u{c77}', + Script::Telugu), ('\u{c78}', '\u{c7e}', Script::Telugu), ('\u{c7f}', '\u{c7f}', + Script::Telugu), ('\u{c80}', '\u{c80}', Script::Kannada), ('\u{c81}', '\u{c81}', + Script::Kannada), ('\u{c82}', '\u{c83}', Script::Kannada), ('\u{c84}', '\u{c84}', + Script::Kannada), ('\u{c85}', '\u{c8c}', Script::Kannada), ('\u{c8e}', '\u{c90}', + Script::Kannada), ('\u{c92}', '\u{ca8}', Script::Kannada), ('\u{caa}', '\u{cb3}', + Script::Kannada), ('\u{cb5}', '\u{cb9}', Script::Kannada), ('\u{cbc}', '\u{cbc}', + Script::Kannada), ('\u{cbd}', '\u{cbd}', Script::Kannada), ('\u{cbe}', '\u{cbe}', + Script::Kannada), ('\u{cbf}', '\u{cbf}', Script::Kannada), ('\u{cc0}', '\u{cc4}', + Script::Kannada), ('\u{cc6}', '\u{cc6}', Script::Kannada), ('\u{cc7}', '\u{cc8}', + Script::Kannada), ('\u{cca}', '\u{ccb}', Script::Kannada), ('\u{ccc}', '\u{ccd}', + Script::Kannada), ('\u{cd5}', '\u{cd6}', Script::Kannada), ('\u{cdd}', '\u{cde}', + Script::Kannada), ('\u{ce0}', '\u{ce1}', Script::Kannada), ('\u{ce2}', '\u{ce3}', + Script::Kannada), ('\u{ce6}', '\u{cef}', Script::Kannada), ('\u{cf1}', '\u{cf2}', + Script::Kannada), ('\u{cf3}', '\u{cf3}', Script::Kannada), ('\u{d00}', '\u{d01}', Script::Malayalam), ('\u{d02}', '\u{d03}', Script::Malayalam), ('\u{d04}', '\u{d0c}', Script::Malayalam), ('\u{d0e}', '\u{d10}', Script::Malayalam), ('\u{d12}', '\u{d3a}', Script::Malayalam), ('\u{d3b}', '\u{d3c}', Script::Malayalam), ('\u{d3d}', '\u{d3d}', @@ -2124,7 +2209,7 @@ pub fn get_script_extension(c: char) -> Option { '\u{ea5}', Script::Lao), ('\u{ea7}', '\u{eb0}', Script::Lao), ('\u{eb1}', '\u{eb1}', Script::Lao), ('\u{eb2}', '\u{eb3}', Script::Lao), ('\u{eb4}', '\u{ebc}', Script::Lao), ('\u{ebd}', '\u{ebd}', Script::Lao), ('\u{ec0}', '\u{ec4}', Script::Lao), ('\u{ec6}', - '\u{ec6}', Script::Lao), ('\u{ec8}', '\u{ecd}', Script::Lao), ('\u{ed0}', '\u{ed9}', + '\u{ec6}', Script::Lao), ('\u{ec8}', '\u{ece}', Script::Lao), ('\u{ed0}', '\u{ed9}', Script::Lao), ('\u{edc}', '\u{edf}', Script::Lao), ('\u{f00}', '\u{f00}', Script::Tibetan), ('\u{f01}', '\u{f03}', Script::Tibetan), ('\u{f04}', '\u{f12}', Script::Tibetan), ('\u{f13}', '\u{f13}', Script::Tibetan), ('\u{f14}', '\u{f14}', @@ -2185,9 +2270,10 @@ pub fn get_script_extension(c: char) -> Option { ('\u{169b}', '\u{169b}', Script::Ogham), ('\u{169c}', '\u{169c}', Script::Ogham), ('\u{16a0}', '\u{16ea}', Script::Runic), ('\u{16eb}', '\u{16ed}', Script::Common), ('\u{16ee}', '\u{16f0}', Script::Runic), ('\u{16f1}', '\u{16f8}', Script::Runic), - ('\u{1700}', '\u{170c}', Script::Tagalog), ('\u{170e}', '\u{1711}', Script::Tagalog), - ('\u{1712}', '\u{1714}', Script::Tagalog), ('\u{1720}', '\u{1731}', Script::Hanunoo), - ('\u{1732}', '\u{1734}', Script::Hanunoo), ('\u{1735}', '\u{1736}', Script::Common), + ('\u{1700}', '\u{1711}', Script::Tagalog), ('\u{1712}', '\u{1714}', Script::Tagalog), + ('\u{1715}', '\u{1715}', Script::Tagalog), ('\u{171f}', '\u{171f}', Script::Tagalog), + ('\u{1720}', '\u{1731}', Script::Hanunoo), ('\u{1732}', '\u{1733}', Script::Hanunoo), + ('\u{1734}', '\u{1734}', Script::Hanunoo), ('\u{1735}', '\u{1736}', Script::Common), ('\u{1740}', '\u{1751}', Script::Buhid), ('\u{1752}', '\u{1753}', Script::Buhid), ('\u{1760}', '\u{176c}', Script::Tagbanwa), ('\u{176e}', '\u{1770}', Script::Tagbanwa), ('\u{1772}', '\u{1773}', Script::Tagbanwa), ('\u{1780}', '\u{17b3}', Script::Khmer), @@ -2202,197 +2288,197 @@ pub fn get_script_extension(c: char) -> Option { ('\u{1802}', '\u{1803}', Script::Common), ('\u{1804}', '\u{1804}', Script::Mongolian), ('\u{1805}', '\u{1805}', Script::Common), ('\u{1806}', '\u{1806}', Script::Mongolian), ('\u{1807}', '\u{180a}', Script::Mongolian), ('\u{180b}', '\u{180d}', Script::Mongolian), - ('\u{180e}', '\u{180e}', Script::Mongolian), ('\u{1810}', '\u{1819}', Script::Mongolian), - ('\u{1820}', '\u{1842}', Script::Mongolian), ('\u{1843}', '\u{1843}', Script::Mongolian), - ('\u{1844}', '\u{1878}', Script::Mongolian), ('\u{1880}', '\u{1884}', Script::Mongolian), - ('\u{1885}', '\u{1886}', Script::Mongolian), ('\u{1887}', '\u{18a8}', Script::Mongolian), - ('\u{18a9}', '\u{18a9}', Script::Mongolian), ('\u{18aa}', '\u{18aa}', Script::Mongolian), - ('\u{18b0}', '\u{18f5}', Script::Canadian_Aboriginal), ('\u{1900}', '\u{191e}', - Script::Limbu), ('\u{1920}', '\u{1922}', Script::Limbu), ('\u{1923}', '\u{1926}', - Script::Limbu), ('\u{1927}', '\u{1928}', Script::Limbu), ('\u{1929}', '\u{192b}', - Script::Limbu), ('\u{1930}', '\u{1931}', Script::Limbu), ('\u{1932}', '\u{1932}', - Script::Limbu), ('\u{1933}', '\u{1938}', Script::Limbu), ('\u{1939}', '\u{193b}', - Script::Limbu), ('\u{1940}', '\u{1940}', Script::Limbu), ('\u{1944}', '\u{1945}', - Script::Limbu), ('\u{1946}', '\u{194f}', Script::Limbu), ('\u{1950}', '\u{196d}', - Script::Tai_Le), ('\u{1970}', '\u{1974}', Script::Tai_Le), ('\u{1980}', '\u{19ab}', - Script::New_Tai_Lue), ('\u{19b0}', '\u{19c9}', Script::New_Tai_Lue), ('\u{19d0}', - '\u{19d9}', Script::New_Tai_Lue), ('\u{19da}', '\u{19da}', Script::New_Tai_Lue), - ('\u{19de}', '\u{19df}', Script::New_Tai_Lue), ('\u{19e0}', '\u{19ff}', Script::Khmer), - ('\u{1a00}', '\u{1a16}', Script::Buginese), ('\u{1a17}', '\u{1a18}', Script::Buginese), - ('\u{1a19}', '\u{1a1a}', Script::Buginese), ('\u{1a1b}', '\u{1a1b}', Script::Buginese), - ('\u{1a1e}', '\u{1a1f}', Script::Buginese), ('\u{1a20}', '\u{1a54}', Script::Tai_Tham), - ('\u{1a55}', '\u{1a55}', Script::Tai_Tham), ('\u{1a56}', '\u{1a56}', Script::Tai_Tham), - ('\u{1a57}', '\u{1a57}', Script::Tai_Tham), ('\u{1a58}', '\u{1a5e}', Script::Tai_Tham), - ('\u{1a60}', '\u{1a60}', Script::Tai_Tham), ('\u{1a61}', '\u{1a61}', Script::Tai_Tham), - ('\u{1a62}', '\u{1a62}', Script::Tai_Tham), ('\u{1a63}', '\u{1a64}', Script::Tai_Tham), - ('\u{1a65}', '\u{1a6c}', Script::Tai_Tham), ('\u{1a6d}', '\u{1a72}', Script::Tai_Tham), - ('\u{1a73}', '\u{1a7c}', Script::Tai_Tham), ('\u{1a7f}', '\u{1a7f}', Script::Tai_Tham), - ('\u{1a80}', '\u{1a89}', Script::Tai_Tham), ('\u{1a90}', '\u{1a99}', Script::Tai_Tham), - ('\u{1aa0}', '\u{1aa6}', Script::Tai_Tham), ('\u{1aa7}', '\u{1aa7}', Script::Tai_Tham), - ('\u{1aa8}', '\u{1aad}', Script::Tai_Tham), ('\u{1ab0}', '\u{1abd}', Script::Inherited), - ('\u{1abe}', '\u{1abe}', Script::Inherited), ('\u{1abf}', '\u{1ac0}', Script::Inherited), - ('\u{1b00}', '\u{1b03}', Script::Balinese), ('\u{1b04}', '\u{1b04}', Script::Balinese), - ('\u{1b05}', '\u{1b33}', Script::Balinese), ('\u{1b34}', '\u{1b34}', Script::Balinese), - ('\u{1b35}', '\u{1b35}', Script::Balinese), ('\u{1b36}', '\u{1b3a}', Script::Balinese), - ('\u{1b3b}', '\u{1b3b}', Script::Balinese), ('\u{1b3c}', '\u{1b3c}', Script::Balinese), - ('\u{1b3d}', '\u{1b41}', Script::Balinese), ('\u{1b42}', '\u{1b42}', Script::Balinese), - ('\u{1b43}', '\u{1b44}', Script::Balinese), ('\u{1b45}', '\u{1b4b}', Script::Balinese), - ('\u{1b50}', '\u{1b59}', Script::Balinese), ('\u{1b5a}', '\u{1b60}', Script::Balinese), - ('\u{1b61}', '\u{1b6a}', Script::Balinese), ('\u{1b6b}', '\u{1b73}', Script::Balinese), - ('\u{1b74}', '\u{1b7c}', Script::Balinese), ('\u{1b80}', '\u{1b81}', Script::Sundanese), - ('\u{1b82}', '\u{1b82}', Script::Sundanese), ('\u{1b83}', '\u{1ba0}', Script::Sundanese), - ('\u{1ba1}', '\u{1ba1}', Script::Sundanese), ('\u{1ba2}', '\u{1ba5}', Script::Sundanese), - ('\u{1ba6}', '\u{1ba7}', Script::Sundanese), ('\u{1ba8}', '\u{1ba9}', Script::Sundanese), - ('\u{1baa}', '\u{1baa}', Script::Sundanese), ('\u{1bab}', '\u{1bad}', Script::Sundanese), - ('\u{1bae}', '\u{1baf}', Script::Sundanese), ('\u{1bb0}', '\u{1bb9}', Script::Sundanese), - ('\u{1bba}', '\u{1bbf}', Script::Sundanese), ('\u{1bc0}', '\u{1be5}', Script::Batak), - ('\u{1be6}', '\u{1be6}', Script::Batak), ('\u{1be7}', '\u{1be7}', Script::Batak), - ('\u{1be8}', '\u{1be9}', Script::Batak), ('\u{1bea}', '\u{1bec}', Script::Batak), - ('\u{1bed}', '\u{1bed}', Script::Batak), ('\u{1bee}', '\u{1bee}', Script::Batak), - ('\u{1bef}', '\u{1bf1}', Script::Batak), ('\u{1bf2}', '\u{1bf3}', Script::Batak), - ('\u{1bfc}', '\u{1bff}', Script::Batak), ('\u{1c00}', '\u{1c23}', Script::Lepcha), - ('\u{1c24}', '\u{1c2b}', Script::Lepcha), ('\u{1c2c}', '\u{1c33}', Script::Lepcha), - ('\u{1c34}', '\u{1c35}', Script::Lepcha), ('\u{1c36}', '\u{1c37}', Script::Lepcha), - ('\u{1c3b}', '\u{1c3f}', Script::Lepcha), ('\u{1c40}', '\u{1c49}', Script::Lepcha), - ('\u{1c4d}', '\u{1c4f}', Script::Lepcha), ('\u{1c50}', '\u{1c59}', Script::Ol_Chiki), - ('\u{1c5a}', '\u{1c77}', Script::Ol_Chiki), ('\u{1c78}', '\u{1c7d}', Script::Ol_Chiki), - ('\u{1c7e}', '\u{1c7f}', Script::Ol_Chiki), ('\u{1c80}', '\u{1c88}', Script::Cyrillic), - ('\u{1c90}', '\u{1cba}', Script::Georgian), ('\u{1cbd}', '\u{1cbf}', Script::Georgian), - ('\u{1cc0}', '\u{1cc7}', Script::Sundanese), ('\u{1cd0}', '\u{1cd2}', Script::Inherited), - ('\u{1cd3}', '\u{1cd3}', Script::Common), ('\u{1cd4}', '\u{1ce0}', Script::Inherited), - ('\u{1ce1}', '\u{1ce1}', Script::Common), ('\u{1ce2}', '\u{1ce8}', Script::Inherited), - ('\u{1ce9}', '\u{1cec}', Script::Common), ('\u{1ced}', '\u{1ced}', Script::Inherited), - ('\u{1cee}', '\u{1cf3}', Script::Common), ('\u{1cf4}', '\u{1cf4}', Script::Inherited), - ('\u{1cf5}', '\u{1cf6}', Script::Common), ('\u{1cf7}', '\u{1cf7}', Script::Common), - ('\u{1cf8}', '\u{1cf9}', Script::Inherited), ('\u{1cfa}', '\u{1cfa}', Script::Common), - ('\u{1d00}', '\u{1d25}', Script::Latin), ('\u{1d26}', '\u{1d2a}', Script::Greek), - ('\u{1d2b}', '\u{1d2b}', Script::Cyrillic), ('\u{1d2c}', '\u{1d5c}', Script::Latin), - ('\u{1d5d}', '\u{1d61}', Script::Greek), ('\u{1d62}', '\u{1d65}', Script::Latin), - ('\u{1d66}', '\u{1d6a}', Script::Greek), ('\u{1d6b}', '\u{1d77}', Script::Latin), - ('\u{1d78}', '\u{1d78}', Script::Cyrillic), ('\u{1d79}', '\u{1d9a}', Script::Latin), - ('\u{1d9b}', '\u{1dbe}', Script::Latin), ('\u{1dbf}', '\u{1dbf}', Script::Greek), - ('\u{1dc0}', '\u{1df9}', Script::Inherited), ('\u{1dfb}', '\u{1dff}', Script::Inherited), - ('\u{1e00}', '\u{1eff}', Script::Latin), ('\u{1f00}', '\u{1f15}', Script::Greek), - ('\u{1f18}', '\u{1f1d}', Script::Greek), ('\u{1f20}', '\u{1f45}', Script::Greek), - ('\u{1f48}', '\u{1f4d}', Script::Greek), ('\u{1f50}', '\u{1f57}', Script::Greek), - ('\u{1f59}', '\u{1f59}', Script::Greek), ('\u{1f5b}', '\u{1f5b}', Script::Greek), - ('\u{1f5d}', '\u{1f5d}', Script::Greek), ('\u{1f5f}', '\u{1f7d}', Script::Greek), - ('\u{1f80}', '\u{1fb4}', Script::Greek), ('\u{1fb6}', '\u{1fbc}', Script::Greek), - ('\u{1fbd}', '\u{1fbd}', Script::Greek), ('\u{1fbe}', '\u{1fbe}', Script::Greek), - ('\u{1fbf}', '\u{1fc1}', Script::Greek), ('\u{1fc2}', '\u{1fc4}', Script::Greek), - ('\u{1fc6}', '\u{1fcc}', Script::Greek), ('\u{1fcd}', '\u{1fcf}', Script::Greek), - ('\u{1fd0}', '\u{1fd3}', Script::Greek), ('\u{1fd6}', '\u{1fdb}', Script::Greek), - ('\u{1fdd}', '\u{1fdf}', Script::Greek), ('\u{1fe0}', '\u{1fec}', Script::Greek), - ('\u{1fed}', '\u{1fef}', Script::Greek), ('\u{1ff2}', '\u{1ff4}', Script::Greek), - ('\u{1ff6}', '\u{1ffc}', Script::Greek), ('\u{1ffd}', '\u{1ffe}', Script::Greek), - ('\u{2000}', '\u{200a}', Script::Common), ('\u{200b}', '\u{200b}', Script::Common), - ('\u{200c}', '\u{200d}', Script::Inherited), ('\u{200e}', '\u{200f}', Script::Common), - ('\u{2010}', '\u{2015}', Script::Common), ('\u{2016}', '\u{2017}', Script::Common), - ('\u{2018}', '\u{2018}', Script::Common), ('\u{2019}', '\u{2019}', Script::Common), - ('\u{201a}', '\u{201a}', Script::Common), ('\u{201b}', '\u{201c}', Script::Common), - ('\u{201d}', '\u{201d}', Script::Common), ('\u{201e}', '\u{201e}', Script::Common), - ('\u{201f}', '\u{201f}', Script::Common), ('\u{2020}', '\u{2027}', Script::Common), - ('\u{2028}', '\u{2028}', Script::Common), ('\u{2029}', '\u{2029}', Script::Common), - ('\u{202a}', '\u{202e}', Script::Common), ('\u{202f}', '\u{202f}', Script::Common), - ('\u{2030}', '\u{2038}', Script::Common), ('\u{2039}', '\u{2039}', Script::Common), - ('\u{203a}', '\u{203a}', Script::Common), ('\u{203b}', '\u{203e}', Script::Common), - ('\u{203f}', '\u{2040}', Script::Common), ('\u{2041}', '\u{2043}', Script::Common), - ('\u{2044}', '\u{2044}', Script::Common), ('\u{2045}', '\u{2045}', Script::Common), - ('\u{2046}', '\u{2046}', Script::Common), ('\u{2047}', '\u{2051}', Script::Common), - ('\u{2052}', '\u{2052}', Script::Common), ('\u{2053}', '\u{2053}', Script::Common), - ('\u{2054}', '\u{2054}', Script::Common), ('\u{2055}', '\u{205e}', Script::Common), - ('\u{205f}', '\u{205f}', Script::Common), ('\u{2060}', '\u{2064}', Script::Common), - ('\u{2066}', '\u{206f}', Script::Common), ('\u{2070}', '\u{2070}', Script::Common), - ('\u{2071}', '\u{2071}', Script::Latin), ('\u{2074}', '\u{2079}', Script::Common), - ('\u{207a}', '\u{207c}', Script::Common), ('\u{207d}', '\u{207d}', Script::Common), - ('\u{207e}', '\u{207e}', Script::Common), ('\u{207f}', '\u{207f}', Script::Latin), - ('\u{2080}', '\u{2089}', Script::Common), ('\u{208a}', '\u{208c}', Script::Common), - ('\u{208d}', '\u{208d}', Script::Common), ('\u{208e}', '\u{208e}', Script::Common), - ('\u{2090}', '\u{209c}', Script::Latin), ('\u{20a0}', '\u{20bf}', Script::Common), - ('\u{20d0}', '\u{20dc}', Script::Inherited), ('\u{20dd}', '\u{20e0}', Script::Inherited), - ('\u{20e1}', '\u{20e1}', Script::Inherited), ('\u{20e2}', '\u{20e4}', Script::Inherited), - ('\u{20e5}', '\u{20f0}', Script::Inherited), ('\u{2100}', '\u{2101}', Script::Common), - ('\u{2102}', '\u{2102}', Script::Common), ('\u{2103}', '\u{2106}', Script::Common), - ('\u{2107}', '\u{2107}', Script::Common), ('\u{2108}', '\u{2109}', Script::Common), - ('\u{210a}', '\u{2113}', Script::Common), ('\u{2114}', '\u{2114}', Script::Common), - ('\u{2115}', '\u{2115}', Script::Common), ('\u{2116}', '\u{2117}', Script::Common), - ('\u{2118}', '\u{2118}', Script::Common), ('\u{2119}', '\u{211d}', Script::Common), - ('\u{211e}', '\u{2123}', Script::Common), ('\u{2124}', '\u{2124}', Script::Common), - ('\u{2125}', '\u{2125}', Script::Common), ('\u{2126}', '\u{2126}', Script::Greek), - ('\u{2127}', '\u{2127}', Script::Common), ('\u{2128}', '\u{2128}', Script::Common), - ('\u{2129}', '\u{2129}', Script::Common), ('\u{212a}', '\u{212b}', Script::Latin), - ('\u{212c}', '\u{212d}', Script::Common), ('\u{212e}', '\u{212e}', Script::Common), - ('\u{212f}', '\u{2131}', Script::Common), ('\u{2132}', '\u{2132}', Script::Latin), - ('\u{2133}', '\u{2134}', Script::Common), ('\u{2135}', '\u{2138}', Script::Common), - ('\u{2139}', '\u{2139}', Script::Common), ('\u{213a}', '\u{213b}', Script::Common), - ('\u{213c}', '\u{213f}', Script::Common), ('\u{2140}', '\u{2144}', Script::Common), - ('\u{2145}', '\u{2149}', Script::Common), ('\u{214a}', '\u{214a}', Script::Common), - ('\u{214b}', '\u{214b}', Script::Common), ('\u{214c}', '\u{214d}', Script::Common), - ('\u{214e}', '\u{214e}', Script::Latin), ('\u{214f}', '\u{214f}', Script::Common), - ('\u{2150}', '\u{215f}', Script::Common), ('\u{2160}', '\u{2182}', Script::Latin), - ('\u{2183}', '\u{2184}', Script::Latin), ('\u{2185}', '\u{2188}', Script::Latin), - ('\u{2189}', '\u{2189}', Script::Common), ('\u{218a}', '\u{218b}', Script::Common), - ('\u{2190}', '\u{2194}', Script::Common), ('\u{2195}', '\u{2199}', Script::Common), - ('\u{219a}', '\u{219b}', Script::Common), ('\u{219c}', '\u{219f}', Script::Common), - ('\u{21a0}', '\u{21a0}', Script::Common), ('\u{21a1}', '\u{21a2}', Script::Common), - ('\u{21a3}', '\u{21a3}', Script::Common), ('\u{21a4}', '\u{21a5}', Script::Common), - ('\u{21a6}', '\u{21a6}', Script::Common), ('\u{21a7}', '\u{21ad}', Script::Common), - ('\u{21ae}', '\u{21ae}', Script::Common), ('\u{21af}', '\u{21cd}', Script::Common), - ('\u{21ce}', '\u{21cf}', Script::Common), ('\u{21d0}', '\u{21d1}', Script::Common), - ('\u{21d2}', '\u{21d2}', Script::Common), ('\u{21d3}', '\u{21d3}', Script::Common), - ('\u{21d4}', '\u{21d4}', Script::Common), ('\u{21d5}', '\u{21f3}', Script::Common), - ('\u{21f4}', '\u{22ff}', Script::Common), ('\u{2300}', '\u{2307}', Script::Common), - ('\u{2308}', '\u{2308}', Script::Common), ('\u{2309}', '\u{2309}', Script::Common), - ('\u{230a}', '\u{230a}', Script::Common), ('\u{230b}', '\u{230b}', Script::Common), - ('\u{230c}', '\u{231f}', Script::Common), ('\u{2320}', '\u{2321}', Script::Common), - ('\u{2322}', '\u{2328}', Script::Common), ('\u{2329}', '\u{2329}', Script::Common), - ('\u{232a}', '\u{232a}', Script::Common), ('\u{232b}', '\u{237b}', Script::Common), - ('\u{237c}', '\u{237c}', Script::Common), ('\u{237d}', '\u{239a}', Script::Common), - ('\u{239b}', '\u{23b3}', Script::Common), ('\u{23b4}', '\u{23db}', Script::Common), - ('\u{23dc}', '\u{23e1}', Script::Common), ('\u{23e2}', '\u{2426}', Script::Common), - ('\u{2440}', '\u{244a}', Script::Common), ('\u{2460}', '\u{249b}', Script::Common), - ('\u{249c}', '\u{24e9}', Script::Common), ('\u{24ea}', '\u{24ff}', Script::Common), - ('\u{2500}', '\u{25b6}', Script::Common), ('\u{25b7}', '\u{25b7}', Script::Common), - ('\u{25b8}', '\u{25c0}', Script::Common), ('\u{25c1}', '\u{25c1}', Script::Common), - ('\u{25c2}', '\u{25f7}', Script::Common), ('\u{25f8}', '\u{25ff}', Script::Common), - ('\u{2600}', '\u{266e}', Script::Common), ('\u{266f}', '\u{266f}', Script::Common), - ('\u{2670}', '\u{2767}', Script::Common), ('\u{2768}', '\u{2768}', Script::Common), - ('\u{2769}', '\u{2769}', Script::Common), ('\u{276a}', '\u{276a}', Script::Common), - ('\u{276b}', '\u{276b}', Script::Common), ('\u{276c}', '\u{276c}', Script::Common), - ('\u{276d}', '\u{276d}', Script::Common), ('\u{276e}', '\u{276e}', Script::Common), - ('\u{276f}', '\u{276f}', Script::Common), ('\u{2770}', '\u{2770}', Script::Common), - ('\u{2771}', '\u{2771}', Script::Common), ('\u{2772}', '\u{2772}', Script::Common), - ('\u{2773}', '\u{2773}', Script::Common), ('\u{2774}', '\u{2774}', Script::Common), - ('\u{2775}', '\u{2775}', Script::Common), ('\u{2776}', '\u{2793}', Script::Common), - ('\u{2794}', '\u{27bf}', Script::Common), ('\u{27c0}', '\u{27c4}', Script::Common), - ('\u{27c5}', '\u{27c5}', Script::Common), ('\u{27c6}', '\u{27c6}', Script::Common), - ('\u{27c7}', '\u{27e5}', Script::Common), ('\u{27e6}', '\u{27e6}', Script::Common), - ('\u{27e7}', '\u{27e7}', Script::Common), ('\u{27e8}', '\u{27e8}', Script::Common), - ('\u{27e9}', '\u{27e9}', Script::Common), ('\u{27ea}', '\u{27ea}', Script::Common), - ('\u{27eb}', '\u{27eb}', Script::Common), ('\u{27ec}', '\u{27ec}', Script::Common), - ('\u{27ed}', '\u{27ed}', Script::Common), ('\u{27ee}', '\u{27ee}', Script::Common), - ('\u{27ef}', '\u{27ef}', Script::Common), ('\u{27f0}', '\u{27ff}', Script::Common), - ('\u{2800}', '\u{28ff}', Script::Braille), ('\u{2900}', '\u{2982}', Script::Common), - ('\u{2983}', '\u{2983}', Script::Common), ('\u{2984}', '\u{2984}', Script::Common), - ('\u{2985}', '\u{2985}', Script::Common), ('\u{2986}', '\u{2986}', Script::Common), - ('\u{2987}', '\u{2987}', Script::Common), ('\u{2988}', '\u{2988}', Script::Common), - ('\u{2989}', '\u{2989}', Script::Common), ('\u{298a}', '\u{298a}', Script::Common), - ('\u{298b}', '\u{298b}', Script::Common), ('\u{298c}', '\u{298c}', Script::Common), - ('\u{298d}', '\u{298d}', Script::Common), ('\u{298e}', '\u{298e}', Script::Common), - ('\u{298f}', '\u{298f}', Script::Common), ('\u{2990}', '\u{2990}', Script::Common), - ('\u{2991}', '\u{2991}', Script::Common), ('\u{2992}', '\u{2992}', Script::Common), - ('\u{2993}', '\u{2993}', Script::Common), ('\u{2994}', '\u{2994}', Script::Common), - ('\u{2995}', '\u{2995}', Script::Common), ('\u{2996}', '\u{2996}', Script::Common), - ('\u{2997}', '\u{2997}', Script::Common), ('\u{2998}', '\u{2998}', Script::Common), - ('\u{2999}', '\u{29d7}', Script::Common), ('\u{29d8}', '\u{29d8}', Script::Common), - ('\u{29d9}', '\u{29d9}', Script::Common), ('\u{29da}', '\u{29da}', Script::Common), - ('\u{29db}', '\u{29db}', Script::Common), ('\u{29dc}', '\u{29fb}', Script::Common), - ('\u{29fc}', '\u{29fc}', Script::Common), ('\u{29fd}', '\u{29fd}', Script::Common), - ('\u{29fe}', '\u{2aff}', Script::Common), ('\u{2b00}', '\u{2b2f}', Script::Common), - ('\u{2b30}', '\u{2b44}', Script::Common), ('\u{2b45}', '\u{2b46}', Script::Common), - ('\u{2b47}', '\u{2b4c}', Script::Common), ('\u{2b4d}', '\u{2b73}', Script::Common), - ('\u{2b76}', '\u{2b95}', Script::Common), ('\u{2b97}', '\u{2bff}', Script::Common), - ('\u{2c00}', '\u{2c2e}', Script::Glagolitic), ('\u{2c30}', '\u{2c5e}', + ('\u{180e}', '\u{180e}', Script::Mongolian), ('\u{180f}', '\u{180f}', Script::Mongolian), + ('\u{1810}', '\u{1819}', Script::Mongolian), ('\u{1820}', '\u{1842}', Script::Mongolian), + ('\u{1843}', '\u{1843}', Script::Mongolian), ('\u{1844}', '\u{1878}', Script::Mongolian), + ('\u{1880}', '\u{1884}', Script::Mongolian), ('\u{1885}', '\u{1886}', Script::Mongolian), + ('\u{1887}', '\u{18a8}', Script::Mongolian), ('\u{18a9}', '\u{18a9}', Script::Mongolian), + ('\u{18aa}', '\u{18aa}', Script::Mongolian), ('\u{18b0}', '\u{18f5}', + Script::Canadian_Aboriginal), ('\u{1900}', '\u{191e}', Script::Limbu), ('\u{1920}', + '\u{1922}', Script::Limbu), ('\u{1923}', '\u{1926}', Script::Limbu), ('\u{1927}', + '\u{1928}', Script::Limbu), ('\u{1929}', '\u{192b}', Script::Limbu), ('\u{1930}', + '\u{1931}', Script::Limbu), ('\u{1932}', '\u{1932}', Script::Limbu), ('\u{1933}', + '\u{1938}', Script::Limbu), ('\u{1939}', '\u{193b}', Script::Limbu), ('\u{1940}', + '\u{1940}', Script::Limbu), ('\u{1944}', '\u{1945}', Script::Limbu), ('\u{1946}', + '\u{194f}', Script::Limbu), ('\u{1950}', '\u{196d}', Script::Tai_Le), ('\u{1970}', + '\u{1974}', Script::Tai_Le), ('\u{1980}', '\u{19ab}', Script::New_Tai_Lue), ('\u{19b0}', + '\u{19c9}', Script::New_Tai_Lue), ('\u{19d0}', '\u{19d9}', Script::New_Tai_Lue), + ('\u{19da}', '\u{19da}', Script::New_Tai_Lue), ('\u{19de}', '\u{19df}', + Script::New_Tai_Lue), ('\u{19e0}', '\u{19ff}', Script::Khmer), ('\u{1a00}', '\u{1a16}', + Script::Buginese), ('\u{1a17}', '\u{1a18}', Script::Buginese), ('\u{1a19}', '\u{1a1a}', + Script::Buginese), ('\u{1a1b}', '\u{1a1b}', Script::Buginese), ('\u{1a1e}', '\u{1a1f}', + Script::Buginese), ('\u{1a20}', '\u{1a54}', Script::Tai_Tham), ('\u{1a55}', '\u{1a55}', + Script::Tai_Tham), ('\u{1a56}', '\u{1a56}', Script::Tai_Tham), ('\u{1a57}', '\u{1a57}', + Script::Tai_Tham), ('\u{1a58}', '\u{1a5e}', Script::Tai_Tham), ('\u{1a60}', '\u{1a60}', + Script::Tai_Tham), ('\u{1a61}', '\u{1a61}', Script::Tai_Tham), ('\u{1a62}', '\u{1a62}', + Script::Tai_Tham), ('\u{1a63}', '\u{1a64}', Script::Tai_Tham), ('\u{1a65}', '\u{1a6c}', + Script::Tai_Tham), ('\u{1a6d}', '\u{1a72}', Script::Tai_Tham), ('\u{1a73}', '\u{1a7c}', + Script::Tai_Tham), ('\u{1a7f}', '\u{1a7f}', Script::Tai_Tham), ('\u{1a80}', '\u{1a89}', + Script::Tai_Tham), ('\u{1a90}', '\u{1a99}', Script::Tai_Tham), ('\u{1aa0}', '\u{1aa6}', + Script::Tai_Tham), ('\u{1aa7}', '\u{1aa7}', Script::Tai_Tham), ('\u{1aa8}', '\u{1aad}', + Script::Tai_Tham), ('\u{1ab0}', '\u{1abd}', Script::Inherited), ('\u{1abe}', '\u{1abe}', + Script::Inherited), ('\u{1abf}', '\u{1ace}', Script::Inherited), ('\u{1b00}', '\u{1b03}', + Script::Balinese), ('\u{1b04}', '\u{1b04}', Script::Balinese), ('\u{1b05}', '\u{1b33}', + Script::Balinese), ('\u{1b34}', '\u{1b34}', Script::Balinese), ('\u{1b35}', '\u{1b35}', + Script::Balinese), ('\u{1b36}', '\u{1b3a}', Script::Balinese), ('\u{1b3b}', '\u{1b3b}', + Script::Balinese), ('\u{1b3c}', '\u{1b3c}', Script::Balinese), ('\u{1b3d}', '\u{1b41}', + Script::Balinese), ('\u{1b42}', '\u{1b42}', Script::Balinese), ('\u{1b43}', '\u{1b44}', + Script::Balinese), ('\u{1b45}', '\u{1b4c}', Script::Balinese), ('\u{1b50}', '\u{1b59}', + Script::Balinese), ('\u{1b5a}', '\u{1b60}', Script::Balinese), ('\u{1b61}', '\u{1b6a}', + Script::Balinese), ('\u{1b6b}', '\u{1b73}', Script::Balinese), ('\u{1b74}', '\u{1b7c}', + Script::Balinese), ('\u{1b7d}', '\u{1b7e}', Script::Balinese), ('\u{1b80}', '\u{1b81}', + Script::Sundanese), ('\u{1b82}', '\u{1b82}', Script::Sundanese), ('\u{1b83}', '\u{1ba0}', + Script::Sundanese), ('\u{1ba1}', '\u{1ba1}', Script::Sundanese), ('\u{1ba2}', '\u{1ba5}', + Script::Sundanese), ('\u{1ba6}', '\u{1ba7}', Script::Sundanese), ('\u{1ba8}', '\u{1ba9}', + Script::Sundanese), ('\u{1baa}', '\u{1baa}', Script::Sundanese), ('\u{1bab}', '\u{1bad}', + Script::Sundanese), ('\u{1bae}', '\u{1baf}', Script::Sundanese), ('\u{1bb0}', '\u{1bb9}', + Script::Sundanese), ('\u{1bba}', '\u{1bbf}', Script::Sundanese), ('\u{1bc0}', '\u{1be5}', + Script::Batak), ('\u{1be6}', '\u{1be6}', Script::Batak), ('\u{1be7}', '\u{1be7}', + Script::Batak), ('\u{1be8}', '\u{1be9}', Script::Batak), ('\u{1bea}', '\u{1bec}', + Script::Batak), ('\u{1bed}', '\u{1bed}', Script::Batak), ('\u{1bee}', '\u{1bee}', + Script::Batak), ('\u{1bef}', '\u{1bf1}', Script::Batak), ('\u{1bf2}', '\u{1bf3}', + Script::Batak), ('\u{1bfc}', '\u{1bff}', Script::Batak), ('\u{1c00}', '\u{1c23}', + Script::Lepcha), ('\u{1c24}', '\u{1c2b}', Script::Lepcha), ('\u{1c2c}', '\u{1c33}', + Script::Lepcha), ('\u{1c34}', '\u{1c35}', Script::Lepcha), ('\u{1c36}', '\u{1c37}', + Script::Lepcha), ('\u{1c3b}', '\u{1c3f}', Script::Lepcha), ('\u{1c40}', '\u{1c49}', + Script::Lepcha), ('\u{1c4d}', '\u{1c4f}', Script::Lepcha), ('\u{1c50}', '\u{1c59}', + Script::Ol_Chiki), ('\u{1c5a}', '\u{1c77}', Script::Ol_Chiki), ('\u{1c78}', '\u{1c7d}', + Script::Ol_Chiki), ('\u{1c7e}', '\u{1c7f}', Script::Ol_Chiki), ('\u{1c80}', '\u{1c88}', + Script::Cyrillic), ('\u{1c90}', '\u{1cba}', Script::Georgian), ('\u{1cbd}', '\u{1cbf}', + Script::Georgian), ('\u{1cc0}', '\u{1cc7}', Script::Sundanese), ('\u{1cd0}', '\u{1cd2}', + Script::Inherited), ('\u{1cd3}', '\u{1cd3}', Script::Common), ('\u{1cd4}', '\u{1ce0}', + Script::Inherited), ('\u{1ce1}', '\u{1ce1}', Script::Common), ('\u{1ce2}', '\u{1ce8}', + Script::Inherited), ('\u{1ce9}', '\u{1cec}', Script::Common), ('\u{1ced}', '\u{1ced}', + Script::Inherited), ('\u{1cee}', '\u{1cf3}', Script::Common), ('\u{1cf4}', '\u{1cf4}', + Script::Inherited), ('\u{1cf5}', '\u{1cf6}', Script::Common), ('\u{1cf7}', '\u{1cf7}', + Script::Common), ('\u{1cf8}', '\u{1cf9}', Script::Inherited), ('\u{1cfa}', '\u{1cfa}', + Script::Common), ('\u{1d00}', '\u{1d25}', Script::Latin), ('\u{1d26}', '\u{1d2a}', + Script::Greek), ('\u{1d2b}', '\u{1d2b}', Script::Cyrillic), ('\u{1d2c}', '\u{1d5c}', + Script::Latin), ('\u{1d5d}', '\u{1d61}', Script::Greek), ('\u{1d62}', '\u{1d65}', + Script::Latin), ('\u{1d66}', '\u{1d6a}', Script::Greek), ('\u{1d6b}', '\u{1d77}', + Script::Latin), ('\u{1d78}', '\u{1d78}', Script::Cyrillic), ('\u{1d79}', '\u{1d9a}', + Script::Latin), ('\u{1d9b}', '\u{1dbe}', Script::Latin), ('\u{1dbf}', '\u{1dbf}', + Script::Greek), ('\u{1dc0}', '\u{1dff}', Script::Inherited), ('\u{1e00}', '\u{1eff}', + Script::Latin), ('\u{1f00}', '\u{1f15}', Script::Greek), ('\u{1f18}', '\u{1f1d}', + Script::Greek), ('\u{1f20}', '\u{1f45}', Script::Greek), ('\u{1f48}', '\u{1f4d}', + Script::Greek), ('\u{1f50}', '\u{1f57}', Script::Greek), ('\u{1f59}', '\u{1f59}', + Script::Greek), ('\u{1f5b}', '\u{1f5b}', Script::Greek), ('\u{1f5d}', '\u{1f5d}', + Script::Greek), ('\u{1f5f}', '\u{1f7d}', Script::Greek), ('\u{1f80}', '\u{1fb4}', + Script::Greek), ('\u{1fb6}', '\u{1fbc}', Script::Greek), ('\u{1fbd}', '\u{1fbd}', + Script::Greek), ('\u{1fbe}', '\u{1fbe}', Script::Greek), ('\u{1fbf}', '\u{1fc1}', + Script::Greek), ('\u{1fc2}', '\u{1fc4}', Script::Greek), ('\u{1fc6}', '\u{1fcc}', + Script::Greek), ('\u{1fcd}', '\u{1fcf}', Script::Greek), ('\u{1fd0}', '\u{1fd3}', + Script::Greek), ('\u{1fd6}', '\u{1fdb}', Script::Greek), ('\u{1fdd}', '\u{1fdf}', + Script::Greek), ('\u{1fe0}', '\u{1fec}', Script::Greek), ('\u{1fed}', '\u{1fef}', + Script::Greek), ('\u{1ff2}', '\u{1ff4}', Script::Greek), ('\u{1ff6}', '\u{1ffc}', + Script::Greek), ('\u{1ffd}', '\u{1ffe}', Script::Greek), ('\u{2000}', '\u{200a}', + Script::Common), ('\u{200b}', '\u{200b}', Script::Common), ('\u{200c}', '\u{200d}', + Script::Inherited), ('\u{200e}', '\u{200f}', Script::Common), ('\u{2010}', '\u{2015}', + Script::Common), ('\u{2016}', '\u{2017}', Script::Common), ('\u{2018}', '\u{2018}', + Script::Common), ('\u{2019}', '\u{2019}', Script::Common), ('\u{201a}', '\u{201a}', + Script::Common), ('\u{201b}', '\u{201c}', Script::Common), ('\u{201d}', '\u{201d}', + Script::Common), ('\u{201e}', '\u{201e}', Script::Common), ('\u{201f}', '\u{201f}', + Script::Common), ('\u{2020}', '\u{2027}', Script::Common), ('\u{2028}', '\u{2028}', + Script::Common), ('\u{2029}', '\u{2029}', Script::Common), ('\u{202a}', '\u{202e}', + Script::Common), ('\u{202f}', '\u{202f}', Script::Common), ('\u{2030}', '\u{2038}', + Script::Common), ('\u{2039}', '\u{2039}', Script::Common), ('\u{203a}', '\u{203a}', + Script::Common), ('\u{203b}', '\u{203e}', Script::Common), ('\u{203f}', '\u{2040}', + Script::Common), ('\u{2041}', '\u{2043}', Script::Common), ('\u{2044}', '\u{2044}', + Script::Common), ('\u{2045}', '\u{2045}', Script::Common), ('\u{2046}', '\u{2046}', + Script::Common), ('\u{2047}', '\u{2051}', Script::Common), ('\u{2052}', '\u{2052}', + Script::Common), ('\u{2053}', '\u{2053}', Script::Common), ('\u{2054}', '\u{2054}', + Script::Common), ('\u{2055}', '\u{205e}', Script::Common), ('\u{205f}', '\u{205f}', + Script::Common), ('\u{2060}', '\u{2064}', Script::Common), ('\u{2066}', '\u{206f}', + Script::Common), ('\u{2070}', '\u{2070}', Script::Common), ('\u{2071}', '\u{2071}', + Script::Latin), ('\u{2074}', '\u{2079}', Script::Common), ('\u{207a}', '\u{207c}', + Script::Common), ('\u{207d}', '\u{207d}', Script::Common), ('\u{207e}', '\u{207e}', + Script::Common), ('\u{207f}', '\u{207f}', Script::Latin), ('\u{2080}', '\u{2089}', + Script::Common), ('\u{208a}', '\u{208c}', Script::Common), ('\u{208d}', '\u{208d}', + Script::Common), ('\u{208e}', '\u{208e}', Script::Common), ('\u{2090}', '\u{209c}', + Script::Latin), ('\u{20a0}', '\u{20c0}', Script::Common), ('\u{20d0}', '\u{20dc}', + Script::Inherited), ('\u{20dd}', '\u{20e0}', Script::Inherited), ('\u{20e1}', '\u{20e1}', + Script::Inherited), ('\u{20e2}', '\u{20e4}', Script::Inherited), ('\u{20e5}', '\u{20f0}', + Script::Inherited), ('\u{2100}', '\u{2101}', Script::Common), ('\u{2102}', '\u{2102}', + Script::Common), ('\u{2103}', '\u{2106}', Script::Common), ('\u{2107}', '\u{2107}', + Script::Common), ('\u{2108}', '\u{2109}', Script::Common), ('\u{210a}', '\u{2113}', + Script::Common), ('\u{2114}', '\u{2114}', Script::Common), ('\u{2115}', '\u{2115}', + Script::Common), ('\u{2116}', '\u{2117}', Script::Common), ('\u{2118}', '\u{2118}', + Script::Common), ('\u{2119}', '\u{211d}', Script::Common), ('\u{211e}', '\u{2123}', + Script::Common), ('\u{2124}', '\u{2124}', Script::Common), ('\u{2125}', '\u{2125}', + Script::Common), ('\u{2126}', '\u{2126}', Script::Greek), ('\u{2127}', '\u{2127}', + Script::Common), ('\u{2128}', '\u{2128}', Script::Common), ('\u{2129}', '\u{2129}', + Script::Common), ('\u{212a}', '\u{212b}', Script::Latin), ('\u{212c}', '\u{212d}', + Script::Common), ('\u{212e}', '\u{212e}', Script::Common), ('\u{212f}', '\u{2131}', + Script::Common), ('\u{2132}', '\u{2132}', Script::Latin), ('\u{2133}', '\u{2134}', + Script::Common), ('\u{2135}', '\u{2138}', Script::Common), ('\u{2139}', '\u{2139}', + Script::Common), ('\u{213a}', '\u{213b}', Script::Common), ('\u{213c}', '\u{213f}', + Script::Common), ('\u{2140}', '\u{2144}', Script::Common), ('\u{2145}', '\u{2149}', + Script::Common), ('\u{214a}', '\u{214a}', Script::Common), ('\u{214b}', '\u{214b}', + Script::Common), ('\u{214c}', '\u{214d}', Script::Common), ('\u{214e}', '\u{214e}', + Script::Latin), ('\u{214f}', '\u{214f}', Script::Common), ('\u{2150}', '\u{215f}', + Script::Common), ('\u{2160}', '\u{2182}', Script::Latin), ('\u{2183}', '\u{2184}', + Script::Latin), ('\u{2185}', '\u{2188}', Script::Latin), ('\u{2189}', '\u{2189}', + Script::Common), ('\u{218a}', '\u{218b}', Script::Common), ('\u{2190}', '\u{2194}', + Script::Common), ('\u{2195}', '\u{2199}', Script::Common), ('\u{219a}', '\u{219b}', + Script::Common), ('\u{219c}', '\u{219f}', Script::Common), ('\u{21a0}', '\u{21a0}', + Script::Common), ('\u{21a1}', '\u{21a2}', Script::Common), ('\u{21a3}', '\u{21a3}', + Script::Common), ('\u{21a4}', '\u{21a5}', Script::Common), ('\u{21a6}', '\u{21a6}', + Script::Common), ('\u{21a7}', '\u{21ad}', Script::Common), ('\u{21ae}', '\u{21ae}', + Script::Common), ('\u{21af}', '\u{21cd}', Script::Common), ('\u{21ce}', '\u{21cf}', + Script::Common), ('\u{21d0}', '\u{21d1}', Script::Common), ('\u{21d2}', '\u{21d2}', + Script::Common), ('\u{21d3}', '\u{21d3}', Script::Common), ('\u{21d4}', '\u{21d4}', + Script::Common), ('\u{21d5}', '\u{21f3}', Script::Common), ('\u{21f4}', '\u{22ff}', + Script::Common), ('\u{2300}', '\u{2307}', Script::Common), ('\u{2308}', '\u{2308}', + Script::Common), ('\u{2309}', '\u{2309}', Script::Common), ('\u{230a}', '\u{230a}', + Script::Common), ('\u{230b}', '\u{230b}', Script::Common), ('\u{230c}', '\u{231f}', + Script::Common), ('\u{2320}', '\u{2321}', Script::Common), ('\u{2322}', '\u{2328}', + Script::Common), ('\u{2329}', '\u{2329}', Script::Common), ('\u{232a}', '\u{232a}', + Script::Common), ('\u{232b}', '\u{237b}', Script::Common), ('\u{237c}', '\u{237c}', + Script::Common), ('\u{237d}', '\u{239a}', Script::Common), ('\u{239b}', '\u{23b3}', + Script::Common), ('\u{23b4}', '\u{23db}', Script::Common), ('\u{23dc}', '\u{23e1}', + Script::Common), ('\u{23e2}', '\u{2426}', Script::Common), ('\u{2440}', '\u{244a}', + Script::Common), ('\u{2460}', '\u{249b}', Script::Common), ('\u{249c}', '\u{24e9}', + Script::Common), ('\u{24ea}', '\u{24ff}', Script::Common), ('\u{2500}', '\u{25b6}', + Script::Common), ('\u{25b7}', '\u{25b7}', Script::Common), ('\u{25b8}', '\u{25c0}', + Script::Common), ('\u{25c1}', '\u{25c1}', Script::Common), ('\u{25c2}', '\u{25f7}', + Script::Common), ('\u{25f8}', '\u{25ff}', Script::Common), ('\u{2600}', '\u{266e}', + Script::Common), ('\u{266f}', '\u{266f}', Script::Common), ('\u{2670}', '\u{2767}', + Script::Common), ('\u{2768}', '\u{2768}', Script::Common), ('\u{2769}', '\u{2769}', + Script::Common), ('\u{276a}', '\u{276a}', Script::Common), ('\u{276b}', '\u{276b}', + Script::Common), ('\u{276c}', '\u{276c}', Script::Common), ('\u{276d}', '\u{276d}', + Script::Common), ('\u{276e}', '\u{276e}', Script::Common), ('\u{276f}', '\u{276f}', + Script::Common), ('\u{2770}', '\u{2770}', Script::Common), ('\u{2771}', '\u{2771}', + Script::Common), ('\u{2772}', '\u{2772}', Script::Common), ('\u{2773}', '\u{2773}', + Script::Common), ('\u{2774}', '\u{2774}', Script::Common), ('\u{2775}', '\u{2775}', + Script::Common), ('\u{2776}', '\u{2793}', Script::Common), ('\u{2794}', '\u{27bf}', + Script::Common), ('\u{27c0}', '\u{27c4}', Script::Common), ('\u{27c5}', '\u{27c5}', + Script::Common), ('\u{27c6}', '\u{27c6}', Script::Common), ('\u{27c7}', '\u{27e5}', + Script::Common), ('\u{27e6}', '\u{27e6}', Script::Common), ('\u{27e7}', '\u{27e7}', + Script::Common), ('\u{27e8}', '\u{27e8}', Script::Common), ('\u{27e9}', '\u{27e9}', + Script::Common), ('\u{27ea}', '\u{27ea}', Script::Common), ('\u{27eb}', '\u{27eb}', + Script::Common), ('\u{27ec}', '\u{27ec}', Script::Common), ('\u{27ed}', '\u{27ed}', + Script::Common), ('\u{27ee}', '\u{27ee}', Script::Common), ('\u{27ef}', '\u{27ef}', + Script::Common), ('\u{27f0}', '\u{27ff}', Script::Common), ('\u{2800}', '\u{28ff}', + Script::Braille), ('\u{2900}', '\u{2982}', Script::Common), ('\u{2983}', '\u{2983}', + Script::Common), ('\u{2984}', '\u{2984}', Script::Common), ('\u{2985}', '\u{2985}', + Script::Common), ('\u{2986}', '\u{2986}', Script::Common), ('\u{2987}', '\u{2987}', + Script::Common), ('\u{2988}', '\u{2988}', Script::Common), ('\u{2989}', '\u{2989}', + Script::Common), ('\u{298a}', '\u{298a}', Script::Common), ('\u{298b}', '\u{298b}', + Script::Common), ('\u{298c}', '\u{298c}', Script::Common), ('\u{298d}', '\u{298d}', + Script::Common), ('\u{298e}', '\u{298e}', Script::Common), ('\u{298f}', '\u{298f}', + Script::Common), ('\u{2990}', '\u{2990}', Script::Common), ('\u{2991}', '\u{2991}', + Script::Common), ('\u{2992}', '\u{2992}', Script::Common), ('\u{2993}', '\u{2993}', + Script::Common), ('\u{2994}', '\u{2994}', Script::Common), ('\u{2995}', '\u{2995}', + Script::Common), ('\u{2996}', '\u{2996}', Script::Common), ('\u{2997}', '\u{2997}', + Script::Common), ('\u{2998}', '\u{2998}', Script::Common), ('\u{2999}', '\u{29d7}', + Script::Common), ('\u{29d8}', '\u{29d8}', Script::Common), ('\u{29d9}', '\u{29d9}', + Script::Common), ('\u{29da}', '\u{29da}', Script::Common), ('\u{29db}', '\u{29db}', + Script::Common), ('\u{29dc}', '\u{29fb}', Script::Common), ('\u{29fc}', '\u{29fc}', + Script::Common), ('\u{29fd}', '\u{29fd}', Script::Common), ('\u{29fe}', '\u{2aff}', + Script::Common), ('\u{2b00}', '\u{2b2f}', Script::Common), ('\u{2b30}', '\u{2b44}', + Script::Common), ('\u{2b45}', '\u{2b46}', Script::Common), ('\u{2b47}', '\u{2b4c}', + Script::Common), ('\u{2b4d}', '\u{2b73}', Script::Common), ('\u{2b76}', '\u{2b95}', + Script::Common), ('\u{2b97}', '\u{2bff}', Script::Common), ('\u{2c00}', '\u{2c5f}', Script::Glagolitic), ('\u{2c60}', '\u{2c7b}', Script::Latin), ('\u{2c7c}', '\u{2c7d}', Script::Latin), ('\u{2c7e}', '\u{2c7f}', Script::Latin), ('\u{2c80}', '\u{2ce4}', Script::Coptic), ('\u{2ce5}', '\u{2cea}', Script::Coptic), ('\u{2ceb}', '\u{2cee}', @@ -2426,68 +2512,74 @@ pub fn get_script_extension(c: char) -> Option { Script::Common), ('\u{2e3a}', '\u{2e3b}', Script::Common), ('\u{2e3c}', '\u{2e3f}', Script::Common), ('\u{2e40}', '\u{2e40}', Script::Common), ('\u{2e41}', '\u{2e41}', Script::Common), ('\u{2e42}', '\u{2e42}', Script::Common), ('\u{2e43}', '\u{2e4f}', - Script::Common), ('\u{2e50}', '\u{2e51}', Script::Common), ('\u{2e52}', '\u{2e52}', - Script::Common), ('\u{2e80}', '\u{2e99}', Script::Han), ('\u{2e9b}', '\u{2ef3}', - Script::Han), ('\u{2f00}', '\u{2fd5}', Script::Han), ('\u{2ff0}', '\u{2ffb}', - Script::Common), ('\u{3000}', '\u{3000}', Script::Common), ('\u{3001}', '\u{3003}', - Script::Common), ('\u{3004}', '\u{3004}', Script::Common), ('\u{3005}', '\u{3005}', - Script::Han), ('\u{3006}', '\u{3006}', Script::Common), ('\u{3007}', '\u{3007}', - Script::Han), ('\u{3008}', '\u{3008}', Script::Common), ('\u{3009}', '\u{3009}', - Script::Common), ('\u{300a}', '\u{300a}', Script::Common), ('\u{300b}', '\u{300b}', - Script::Common), ('\u{300c}', '\u{300c}', Script::Common), ('\u{300d}', '\u{300d}', - Script::Common), ('\u{300e}', '\u{300e}', Script::Common), ('\u{300f}', '\u{300f}', - Script::Common), ('\u{3010}', '\u{3010}', Script::Common), ('\u{3011}', '\u{3011}', - Script::Common), ('\u{3012}', '\u{3013}', Script::Common), ('\u{3014}', '\u{3014}', - Script::Common), ('\u{3015}', '\u{3015}', Script::Common), ('\u{3016}', '\u{3016}', - Script::Common), ('\u{3017}', '\u{3017}', Script::Common), ('\u{3018}', '\u{3018}', - Script::Common), ('\u{3019}', '\u{3019}', Script::Common), ('\u{301a}', '\u{301a}', - Script::Common), ('\u{301b}', '\u{301b}', Script::Common), ('\u{301c}', '\u{301c}', - Script::Common), ('\u{301d}', '\u{301d}', Script::Common), ('\u{301e}', '\u{301f}', - Script::Common), ('\u{3020}', '\u{3020}', Script::Common), ('\u{3021}', '\u{3029}', - Script::Han), ('\u{302a}', '\u{302d}', Script::Inherited), ('\u{302e}', '\u{302f}', - Script::Hangul), ('\u{3030}', '\u{3030}', Script::Common), ('\u{3031}', '\u{3035}', - Script::Common), ('\u{3036}', '\u{3037}', Script::Common), ('\u{3038}', '\u{303a}', - Script::Han), ('\u{303b}', '\u{303b}', Script::Han), ('\u{303c}', '\u{303c}', - Script::Common), ('\u{303d}', '\u{303d}', Script::Common), ('\u{303e}', '\u{303f}', - Script::Common), ('\u{3041}', '\u{3096}', Script::Hiragana), ('\u{3099}', '\u{309a}', - Script::Inherited), ('\u{309b}', '\u{309c}', Script::Common), ('\u{309d}', '\u{309e}', - Script::Hiragana), ('\u{309f}', '\u{309f}', Script::Hiragana), ('\u{30a0}', '\u{30a0}', - Script::Common), ('\u{30a1}', '\u{30fa}', Script::Katakana), ('\u{30fb}', '\u{30fb}', - Script::Common), ('\u{30fc}', '\u{30fc}', Script::Common), ('\u{30fd}', '\u{30fe}', - Script::Katakana), ('\u{30ff}', '\u{30ff}', Script::Katakana), ('\u{3105}', '\u{312f}', - Script::Bopomofo), ('\u{3131}', '\u{318e}', Script::Hangul), ('\u{3190}', '\u{3191}', - Script::Common), ('\u{3192}', '\u{3195}', Script::Common), ('\u{3196}', '\u{319f}', - Script::Common), ('\u{31a0}', '\u{31bf}', Script::Bopomofo), ('\u{31c0}', '\u{31e3}', - Script::Common), ('\u{31f0}', '\u{31ff}', Script::Katakana), ('\u{3200}', '\u{321e}', - Script::Hangul), ('\u{3220}', '\u{3229}', Script::Common), ('\u{322a}', '\u{3247}', - Script::Common), ('\u{3248}', '\u{324f}', Script::Common), ('\u{3250}', '\u{3250}', - Script::Common), ('\u{3251}', '\u{325f}', Script::Common), ('\u{3260}', '\u{327e}', - Script::Hangul), ('\u{327f}', '\u{327f}', Script::Common), ('\u{3280}', '\u{3289}', - Script::Common), ('\u{328a}', '\u{32b0}', Script::Common), ('\u{32b1}', '\u{32bf}', - Script::Common), ('\u{32c0}', '\u{32cf}', Script::Common), ('\u{32d0}', '\u{32fe}', - Script::Katakana), ('\u{32ff}', '\u{32ff}', Script::Common), ('\u{3300}', '\u{3357}', - Script::Katakana), ('\u{3358}', '\u{33ff}', Script::Common), ('\u{3400}', '\u{4dbf}', - Script::Han), ('\u{4dc0}', '\u{4dff}', Script::Common), ('\u{4e00}', '\u{9ffc}', - Script::Han), ('\u{a000}', '\u{a014}', Script::Yi), ('\u{a015}', '\u{a015}', Script::Yi), - ('\u{a016}', '\u{a48c}', Script::Yi), ('\u{a490}', '\u{a4c6}', Script::Yi), ('\u{a4d0}', - '\u{a4f7}', Script::Lisu), ('\u{a4f8}', '\u{a4fd}', Script::Lisu), ('\u{a4fe}', - '\u{a4ff}', Script::Lisu), ('\u{a500}', '\u{a60b}', Script::Vai), ('\u{a60c}', '\u{a60c}', - Script::Vai), ('\u{a60d}', '\u{a60f}', Script::Vai), ('\u{a610}', '\u{a61f}', - Script::Vai), ('\u{a620}', '\u{a629}', Script::Vai), ('\u{a62a}', '\u{a62b}', - Script::Vai), ('\u{a640}', '\u{a66d}', Script::Cyrillic), ('\u{a66e}', '\u{a66e}', - Script::Cyrillic), ('\u{a66f}', '\u{a66f}', Script::Cyrillic), ('\u{a670}', '\u{a672}', - Script::Cyrillic), ('\u{a673}', '\u{a673}', Script::Cyrillic), ('\u{a674}', '\u{a67d}', - Script::Cyrillic), ('\u{a67e}', '\u{a67e}', Script::Cyrillic), ('\u{a67f}', '\u{a67f}', - Script::Cyrillic), ('\u{a680}', '\u{a69b}', Script::Cyrillic), ('\u{a69c}', '\u{a69d}', - Script::Cyrillic), ('\u{a69e}', '\u{a69f}', Script::Cyrillic), ('\u{a6a0}', '\u{a6e5}', - Script::Bamum), ('\u{a6e6}', '\u{a6ef}', Script::Bamum), ('\u{a6f0}', '\u{a6f1}', - Script::Bamum), ('\u{a6f2}', '\u{a6f7}', Script::Bamum), ('\u{a700}', '\u{a716}', - Script::Common), ('\u{a717}', '\u{a71f}', Script::Common), ('\u{a720}', '\u{a721}', - Script::Common), ('\u{a722}', '\u{a76f}', Script::Latin), ('\u{a770}', '\u{a770}', - Script::Latin), ('\u{a771}', '\u{a787}', Script::Latin), ('\u{a788}', '\u{a788}', - Script::Common), ('\u{a789}', '\u{a78a}', Script::Common), ('\u{a78b}', '\u{a78e}', - Script::Latin), ('\u{a78f}', '\u{a78f}', Script::Latin), ('\u{a790}', '\u{a7bf}', - Script::Latin), ('\u{a7c2}', '\u{a7ca}', Script::Latin), ('\u{a7f5}', '\u{a7f6}', + Script::Common), ('\u{2e50}', '\u{2e51}', Script::Common), ('\u{2e52}', '\u{2e54}', + Script::Common), ('\u{2e55}', '\u{2e55}', Script::Common), ('\u{2e56}', '\u{2e56}', + Script::Common), ('\u{2e57}', '\u{2e57}', Script::Common), ('\u{2e58}', '\u{2e58}', + Script::Common), ('\u{2e59}', '\u{2e59}', Script::Common), ('\u{2e5a}', '\u{2e5a}', + Script::Common), ('\u{2e5b}', '\u{2e5b}', Script::Common), ('\u{2e5c}', '\u{2e5c}', + Script::Common), ('\u{2e5d}', '\u{2e5d}', Script::Common), ('\u{2e80}', '\u{2e99}', + Script::Han), ('\u{2e9b}', '\u{2ef3}', Script::Han), ('\u{2f00}', '\u{2fd5}', + Script::Han), ('\u{2ff0}', '\u{2ffb}', Script::Common), ('\u{3000}', '\u{3000}', + Script::Common), ('\u{3001}', '\u{3003}', Script::Common), ('\u{3004}', '\u{3004}', + Script::Common), ('\u{3005}', '\u{3005}', Script::Han), ('\u{3006}', '\u{3006}', + Script::Common), ('\u{3007}', '\u{3007}', Script::Han), ('\u{3008}', '\u{3008}', + Script::Common), ('\u{3009}', '\u{3009}', Script::Common), ('\u{300a}', '\u{300a}', + Script::Common), ('\u{300b}', '\u{300b}', Script::Common), ('\u{300c}', '\u{300c}', + Script::Common), ('\u{300d}', '\u{300d}', Script::Common), ('\u{300e}', '\u{300e}', + Script::Common), ('\u{300f}', '\u{300f}', Script::Common), ('\u{3010}', '\u{3010}', + Script::Common), ('\u{3011}', '\u{3011}', Script::Common), ('\u{3012}', '\u{3013}', + Script::Common), ('\u{3014}', '\u{3014}', Script::Common), ('\u{3015}', '\u{3015}', + Script::Common), ('\u{3016}', '\u{3016}', Script::Common), ('\u{3017}', '\u{3017}', + Script::Common), ('\u{3018}', '\u{3018}', Script::Common), ('\u{3019}', '\u{3019}', + Script::Common), ('\u{301a}', '\u{301a}', Script::Common), ('\u{301b}', '\u{301b}', + Script::Common), ('\u{301c}', '\u{301c}', Script::Common), ('\u{301d}', '\u{301d}', + Script::Common), ('\u{301e}', '\u{301f}', Script::Common), ('\u{3020}', '\u{3020}', + Script::Common), ('\u{3021}', '\u{3029}', Script::Han), ('\u{302a}', '\u{302d}', + Script::Inherited), ('\u{302e}', '\u{302f}', Script::Hangul), ('\u{3030}', '\u{3030}', + Script::Common), ('\u{3031}', '\u{3035}', Script::Common), ('\u{3036}', '\u{3037}', + Script::Common), ('\u{3038}', '\u{303a}', Script::Han), ('\u{303b}', '\u{303b}', + Script::Han), ('\u{303c}', '\u{303c}', Script::Common), ('\u{303d}', '\u{303d}', + Script::Common), ('\u{303e}', '\u{303f}', Script::Common), ('\u{3041}', '\u{3096}', + Script::Hiragana), ('\u{3099}', '\u{309a}', Script::Inherited), ('\u{309b}', '\u{309c}', + Script::Common), ('\u{309d}', '\u{309e}', Script::Hiragana), ('\u{309f}', '\u{309f}', + Script::Hiragana), ('\u{30a0}', '\u{30a0}', Script::Common), ('\u{30a1}', '\u{30fa}', + Script::Katakana), ('\u{30fb}', '\u{30fb}', Script::Common), ('\u{30fc}', '\u{30fc}', + Script::Common), ('\u{30fd}', '\u{30fe}', Script::Katakana), ('\u{30ff}', '\u{30ff}', + Script::Katakana), ('\u{3105}', '\u{312f}', Script::Bopomofo), ('\u{3131}', '\u{318e}', + Script::Hangul), ('\u{3190}', '\u{3191}', Script::Common), ('\u{3192}', '\u{3195}', + Script::Common), ('\u{3196}', '\u{319f}', Script::Common), ('\u{31a0}', '\u{31bf}', + Script::Bopomofo), ('\u{31c0}', '\u{31e3}', Script::Common), ('\u{31f0}', '\u{31ff}', + Script::Katakana), ('\u{3200}', '\u{321e}', Script::Hangul), ('\u{3220}', '\u{3229}', + Script::Common), ('\u{322a}', '\u{3247}', Script::Common), ('\u{3248}', '\u{324f}', + Script::Common), ('\u{3250}', '\u{3250}', Script::Common), ('\u{3251}', '\u{325f}', + Script::Common), ('\u{3260}', '\u{327e}', Script::Hangul), ('\u{327f}', '\u{327f}', + Script::Common), ('\u{3280}', '\u{3289}', Script::Common), ('\u{328a}', '\u{32b0}', + Script::Common), ('\u{32b1}', '\u{32bf}', Script::Common), ('\u{32c0}', '\u{32cf}', + Script::Common), ('\u{32d0}', '\u{32fe}', Script::Katakana), ('\u{32ff}', '\u{32ff}', + Script::Common), ('\u{3300}', '\u{3357}', Script::Katakana), ('\u{3358}', '\u{33ff}', + Script::Common), ('\u{3400}', '\u{4dbf}', Script::Han), ('\u{4dc0}', '\u{4dff}', + Script::Common), ('\u{4e00}', '\u{9fff}', Script::Han), ('\u{a000}', '\u{a014}', + Script::Yi), ('\u{a015}', '\u{a015}', Script::Yi), ('\u{a016}', '\u{a48c}', Script::Yi), + ('\u{a490}', '\u{a4c6}', Script::Yi), ('\u{a4d0}', '\u{a4f7}', Script::Lisu), ('\u{a4f8}', + '\u{a4fd}', Script::Lisu), ('\u{a4fe}', '\u{a4ff}', Script::Lisu), ('\u{a500}', + '\u{a60b}', Script::Vai), ('\u{a60c}', '\u{a60c}', Script::Vai), ('\u{a60d}', '\u{a60f}', + Script::Vai), ('\u{a610}', '\u{a61f}', Script::Vai), ('\u{a620}', '\u{a629}', + Script::Vai), ('\u{a62a}', '\u{a62b}', Script::Vai), ('\u{a640}', '\u{a66d}', + Script::Cyrillic), ('\u{a66e}', '\u{a66e}', Script::Cyrillic), ('\u{a66f}', '\u{a66f}', + Script::Cyrillic), ('\u{a670}', '\u{a672}', Script::Cyrillic), ('\u{a673}', '\u{a673}', + Script::Cyrillic), ('\u{a674}', '\u{a67d}', Script::Cyrillic), ('\u{a67e}', '\u{a67e}', + Script::Cyrillic), ('\u{a67f}', '\u{a67f}', Script::Cyrillic), ('\u{a680}', '\u{a69b}', + Script::Cyrillic), ('\u{a69c}', '\u{a69d}', Script::Cyrillic), ('\u{a69e}', '\u{a69f}', + Script::Cyrillic), ('\u{a6a0}', '\u{a6e5}', Script::Bamum), ('\u{a6e6}', '\u{a6ef}', + Script::Bamum), ('\u{a6f0}', '\u{a6f1}', Script::Bamum), ('\u{a6f2}', '\u{a6f7}', + Script::Bamum), ('\u{a700}', '\u{a716}', Script::Common), ('\u{a717}', '\u{a71f}', + Script::Common), ('\u{a720}', '\u{a721}', Script::Common), ('\u{a722}', '\u{a76f}', + Script::Latin), ('\u{a770}', '\u{a770}', Script::Latin), ('\u{a771}', '\u{a787}', + Script::Latin), ('\u{a788}', '\u{a788}', Script::Common), ('\u{a789}', '\u{a78a}', + Script::Common), ('\u{a78b}', '\u{a78e}', Script::Latin), ('\u{a78f}', '\u{a78f}', + Script::Latin), ('\u{a790}', '\u{a7ca}', Script::Latin), ('\u{a7d0}', '\u{a7d1}', + Script::Latin), ('\u{a7d3}', '\u{a7d3}', Script::Latin), ('\u{a7d5}', '\u{a7d9}', + Script::Latin), ('\u{a7f2}', '\u{a7f4}', Script::Latin), ('\u{a7f5}', '\u{a7f6}', Script::Latin), ('\u{a7f7}', '\u{a7f7}', Script::Latin), ('\u{a7f8}', '\u{a7f9}', Script::Latin), ('\u{a7fa}', '\u{a7fa}', Script::Latin), ('\u{a7fb}', '\u{a7ff}', Script::Latin), ('\u{a800}', '\u{a801}', Script::Syloti_Nagri), ('\u{a802}', '\u{a802}', @@ -2568,11 +2660,12 @@ pub fn get_script_extension(c: char) -> Option { '\u{fb3c}', Script::Hebrew), ('\u{fb3e}', '\u{fb3e}', Script::Hebrew), ('\u{fb40}', '\u{fb41}', Script::Hebrew), ('\u{fb43}', '\u{fb44}', Script::Hebrew), ('\u{fb46}', '\u{fb4f}', Script::Hebrew), ('\u{fb50}', '\u{fbb1}', Script::Arabic), ('\u{fbb2}', - '\u{fbc1}', Script::Arabic), ('\u{fbd3}', '\u{fd3d}', Script::Arabic), ('\u{fd3e}', - '\u{fd3e}', Script::Common), ('\u{fd3f}', '\u{fd3f}', Script::Common), ('\u{fd50}', - '\u{fd8f}', Script::Arabic), ('\u{fd92}', '\u{fdc7}', Script::Arabic), ('\u{fdf0}', + '\u{fbc2}', Script::Arabic), ('\u{fbd3}', '\u{fd3d}', Script::Arabic), ('\u{fd3e}', + '\u{fd3e}', Script::Common), ('\u{fd3f}', '\u{fd3f}', Script::Common), ('\u{fd40}', + '\u{fd4f}', Script::Arabic), ('\u{fd50}', '\u{fd8f}', Script::Arabic), ('\u{fd92}', + '\u{fdc7}', Script::Arabic), ('\u{fdcf}', '\u{fdcf}', Script::Arabic), ('\u{fdf0}', '\u{fdfb}', Script::Arabic), ('\u{fdfc}', '\u{fdfc}', Script::Arabic), ('\u{fdfd}', - '\u{fdfd}', Script::Arabic), ('\u{fe00}', '\u{fe0f}', Script::Inherited), ('\u{fe10}', + '\u{fdff}', Script::Arabic), ('\u{fe00}', '\u{fe0f}', Script::Inherited), ('\u{fe10}', '\u{fe16}', Script::Common), ('\u{fe17}', '\u{fe17}', Script::Common), ('\u{fe18}', '\u{fe18}', Script::Common), ('\u{fe19}', '\u{fe19}', Script::Common), ('\u{fe20}', '\u{fe2d}', Script::Inherited), ('\u{fe2e}', '\u{fe2f}', Script::Cyrillic), ('\u{fe30}', @@ -2648,41 +2741,48 @@ pub fn get_script_extension(c: char) -> Option { Script::Osmanya), ('\u{104a0}', '\u{104a9}', Script::Osmanya), ('\u{104b0}', '\u{104d3}', Script::Osage), ('\u{104d8}', '\u{104fb}', Script::Osage), ('\u{10500}', '\u{10527}', Script::Elbasan), ('\u{10530}', '\u{10563}', Script::Caucasian_Albanian), ('\u{1056f}', - '\u{1056f}', Script::Caucasian_Albanian), ('\u{10600}', '\u{10736}', Script::Linear_A), - ('\u{10740}', '\u{10755}', Script::Linear_A), ('\u{10760}', '\u{10767}', - Script::Linear_A), ('\u{10800}', '\u{10805}', Script::Cypriot), ('\u{10808}', '\u{10808}', - Script::Cypriot), ('\u{1080a}', '\u{10835}', Script::Cypriot), ('\u{10837}', '\u{10838}', - Script::Cypriot), ('\u{1083c}', '\u{1083c}', Script::Cypriot), ('\u{1083f}', '\u{1083f}', - Script::Cypriot), ('\u{10840}', '\u{10855}', Script::Imperial_Aramaic), ('\u{10857}', - '\u{10857}', Script::Imperial_Aramaic), ('\u{10858}', '\u{1085f}', - Script::Imperial_Aramaic), ('\u{10860}', '\u{10876}', Script::Palmyrene), ('\u{10877}', - '\u{10878}', Script::Palmyrene), ('\u{10879}', '\u{1087f}', Script::Palmyrene), - ('\u{10880}', '\u{1089e}', Script::Nabataean), ('\u{108a7}', '\u{108af}', - Script::Nabataean), ('\u{108e0}', '\u{108f2}', Script::Hatran), ('\u{108f4}', '\u{108f5}', - Script::Hatran), ('\u{108fb}', '\u{108ff}', Script::Hatran), ('\u{10900}', '\u{10915}', - Script::Phoenician), ('\u{10916}', '\u{1091b}', Script::Phoenician), ('\u{1091f}', - '\u{1091f}', Script::Phoenician), ('\u{10920}', '\u{10939}', Script::Lydian), - ('\u{1093f}', '\u{1093f}', Script::Lydian), ('\u{10980}', '\u{1099f}', - Script::Meroitic_Hieroglyphs), ('\u{109a0}', '\u{109b7}', Script::Meroitic_Cursive), - ('\u{109bc}', '\u{109bd}', Script::Meroitic_Cursive), ('\u{109be}', '\u{109bf}', - Script::Meroitic_Cursive), ('\u{109c0}', '\u{109cf}', Script::Meroitic_Cursive), - ('\u{109d2}', '\u{109ff}', Script::Meroitic_Cursive), ('\u{10a00}', '\u{10a00}', - Script::Kharoshthi), ('\u{10a01}', '\u{10a03}', Script::Kharoshthi), ('\u{10a05}', - '\u{10a06}', Script::Kharoshthi), ('\u{10a0c}', '\u{10a0f}', Script::Kharoshthi), - ('\u{10a10}', '\u{10a13}', Script::Kharoshthi), ('\u{10a15}', '\u{10a17}', - Script::Kharoshthi), ('\u{10a19}', '\u{10a35}', Script::Kharoshthi), ('\u{10a38}', - '\u{10a3a}', Script::Kharoshthi), ('\u{10a3f}', '\u{10a3f}', Script::Kharoshthi), - ('\u{10a40}', '\u{10a48}', Script::Kharoshthi), ('\u{10a50}', '\u{10a58}', - Script::Kharoshthi), ('\u{10a60}', '\u{10a7c}', Script::Old_South_Arabian), ('\u{10a7d}', - '\u{10a7e}', Script::Old_South_Arabian), ('\u{10a7f}', '\u{10a7f}', - Script::Old_South_Arabian), ('\u{10a80}', '\u{10a9c}', Script::Old_North_Arabian), - ('\u{10a9d}', '\u{10a9f}', Script::Old_North_Arabian), ('\u{10ac0}', '\u{10ac7}', - Script::Manichaean), ('\u{10ac8}', '\u{10ac8}', Script::Manichaean), ('\u{10ac9}', - '\u{10ae4}', Script::Manichaean), ('\u{10ae5}', '\u{10ae6}', Script::Manichaean), - ('\u{10aeb}', '\u{10aef}', Script::Manichaean), ('\u{10af0}', '\u{10af6}', - Script::Manichaean), ('\u{10b00}', '\u{10b35}', Script::Avestan), ('\u{10b39}', - '\u{10b3f}', Script::Avestan), ('\u{10b40}', '\u{10b55}', Script::Inscriptional_Parthian), - ('\u{10b58}', '\u{10b5f}', Script::Inscriptional_Parthian), ('\u{10b60}', '\u{10b72}', + '\u{1056f}', Script::Caucasian_Albanian), ('\u{10570}', '\u{1057a}', Script::Vithkuqi), + ('\u{1057c}', '\u{1058a}', Script::Vithkuqi), ('\u{1058c}', '\u{10592}', + Script::Vithkuqi), ('\u{10594}', '\u{10595}', Script::Vithkuqi), ('\u{10597}', + '\u{105a1}', Script::Vithkuqi), ('\u{105a3}', '\u{105b1}', Script::Vithkuqi), + ('\u{105b3}', '\u{105b9}', Script::Vithkuqi), ('\u{105bb}', '\u{105bc}', + Script::Vithkuqi), ('\u{10600}', '\u{10736}', Script::Linear_A), ('\u{10740}', + '\u{10755}', Script::Linear_A), ('\u{10760}', '\u{10767}', Script::Linear_A), + ('\u{10780}', '\u{10785}', Script::Latin), ('\u{10787}', '\u{107b0}', Script::Latin), + ('\u{107b2}', '\u{107ba}', Script::Latin), ('\u{10800}', '\u{10805}', Script::Cypriot), + ('\u{10808}', '\u{10808}', Script::Cypriot), ('\u{1080a}', '\u{10835}', Script::Cypriot), + ('\u{10837}', '\u{10838}', Script::Cypriot), ('\u{1083c}', '\u{1083c}', Script::Cypriot), + ('\u{1083f}', '\u{1083f}', Script::Cypriot), ('\u{10840}', '\u{10855}', + Script::Imperial_Aramaic), ('\u{10857}', '\u{10857}', Script::Imperial_Aramaic), + ('\u{10858}', '\u{1085f}', Script::Imperial_Aramaic), ('\u{10860}', '\u{10876}', + Script::Palmyrene), ('\u{10877}', '\u{10878}', Script::Palmyrene), ('\u{10879}', + '\u{1087f}', Script::Palmyrene), ('\u{10880}', '\u{1089e}', Script::Nabataean), + ('\u{108a7}', '\u{108af}', Script::Nabataean), ('\u{108e0}', '\u{108f2}', Script::Hatran), + ('\u{108f4}', '\u{108f5}', Script::Hatran), ('\u{108fb}', '\u{108ff}', Script::Hatran), + ('\u{10900}', '\u{10915}', Script::Phoenician), ('\u{10916}', '\u{1091b}', + Script::Phoenician), ('\u{1091f}', '\u{1091f}', Script::Phoenician), ('\u{10920}', + '\u{10939}', Script::Lydian), ('\u{1093f}', '\u{1093f}', Script::Lydian), ('\u{10980}', + '\u{1099f}', Script::Meroitic_Hieroglyphs), ('\u{109a0}', '\u{109b7}', + Script::Meroitic_Cursive), ('\u{109bc}', '\u{109bd}', Script::Meroitic_Cursive), + ('\u{109be}', '\u{109bf}', Script::Meroitic_Cursive), ('\u{109c0}', '\u{109cf}', + Script::Meroitic_Cursive), ('\u{109d2}', '\u{109ff}', Script::Meroitic_Cursive), + ('\u{10a00}', '\u{10a00}', Script::Kharoshthi), ('\u{10a01}', '\u{10a03}', + Script::Kharoshthi), ('\u{10a05}', '\u{10a06}', Script::Kharoshthi), ('\u{10a0c}', + '\u{10a0f}', Script::Kharoshthi), ('\u{10a10}', '\u{10a13}', Script::Kharoshthi), + ('\u{10a15}', '\u{10a17}', Script::Kharoshthi), ('\u{10a19}', '\u{10a35}', + Script::Kharoshthi), ('\u{10a38}', '\u{10a3a}', Script::Kharoshthi), ('\u{10a3f}', + '\u{10a3f}', Script::Kharoshthi), ('\u{10a40}', '\u{10a48}', Script::Kharoshthi), + ('\u{10a50}', '\u{10a58}', Script::Kharoshthi), ('\u{10a60}', '\u{10a7c}', + Script::Old_South_Arabian), ('\u{10a7d}', '\u{10a7e}', Script::Old_South_Arabian), + ('\u{10a7f}', '\u{10a7f}', Script::Old_South_Arabian), ('\u{10a80}', '\u{10a9c}', + Script::Old_North_Arabian), ('\u{10a9d}', '\u{10a9f}', Script::Old_North_Arabian), + ('\u{10ac0}', '\u{10ac7}', Script::Manichaean), ('\u{10ac8}', '\u{10ac8}', + Script::Manichaean), ('\u{10ac9}', '\u{10ae4}', Script::Manichaean), ('\u{10ae5}', + '\u{10ae6}', Script::Manichaean), ('\u{10aeb}', '\u{10aef}', Script::Manichaean), + ('\u{10af0}', '\u{10af6}', Script::Manichaean), ('\u{10b00}', '\u{10b35}', + Script::Avestan), ('\u{10b39}', '\u{10b3f}', Script::Avestan), ('\u{10b40}', '\u{10b55}', + Script::Inscriptional_Parthian), ('\u{10b58}', '\u{10b5f}', + Script::Inscriptional_Parthian), ('\u{10b60}', '\u{10b72}', Script::Inscriptional_Pahlavi), ('\u{10b78}', '\u{10b7f}', Script::Inscriptional_Pahlavi), ('\u{10b80}', '\u{10b91}', Script::Psalter_Pahlavi), ('\u{10b99}', '\u{10b9c}', Script::Psalter_Pahlavi), ('\u{10ba9}', '\u{10baf}', Script::Psalter_Pahlavi), @@ -2692,166 +2792,186 @@ pub fn get_script_extension(c: char) -> Option { ('\u{10d24}', '\u{10d27}', Script::Hanifi_Rohingya), ('\u{10d30}', '\u{10d39}', Script::Hanifi_Rohingya), ('\u{10e60}', '\u{10e7e}', Script::Arabic), ('\u{10e80}', '\u{10ea9}', Script::Yezidi), ('\u{10eab}', '\u{10eac}', Script::Yezidi), ('\u{10ead}', - '\u{10ead}', Script::Yezidi), ('\u{10eb0}', '\u{10eb1}', Script::Yezidi), ('\u{10f00}', - '\u{10f1c}', Script::Old_Sogdian), ('\u{10f1d}', '\u{10f26}', Script::Old_Sogdian), - ('\u{10f27}', '\u{10f27}', Script::Old_Sogdian), ('\u{10f30}', '\u{10f45}', - Script::Sogdian), ('\u{10f46}', '\u{10f50}', Script::Sogdian), ('\u{10f51}', '\u{10f54}', - Script::Sogdian), ('\u{10f55}', '\u{10f59}', Script::Sogdian), ('\u{10fb0}', '\u{10fc4}', - Script::Chorasmian), ('\u{10fc5}', '\u{10fcb}', Script::Chorasmian), ('\u{10fe0}', - '\u{10ff6}', Script::Elymaic), ('\u{11000}', '\u{11000}', Script::Brahmi), ('\u{11001}', - '\u{11001}', Script::Brahmi), ('\u{11002}', '\u{11002}', Script::Brahmi), ('\u{11003}', - '\u{11037}', Script::Brahmi), ('\u{11038}', '\u{11046}', Script::Brahmi), ('\u{11047}', - '\u{1104d}', Script::Brahmi), ('\u{11052}', '\u{11065}', Script::Brahmi), ('\u{11066}', - '\u{1106f}', Script::Brahmi), ('\u{1107f}', '\u{1107f}', Script::Brahmi), ('\u{11080}', - '\u{11081}', Script::Kaithi), ('\u{11082}', '\u{11082}', Script::Kaithi), ('\u{11083}', - '\u{110af}', Script::Kaithi), ('\u{110b0}', '\u{110b2}', Script::Kaithi), ('\u{110b3}', - '\u{110b6}', Script::Kaithi), ('\u{110b7}', '\u{110b8}', Script::Kaithi), ('\u{110b9}', - '\u{110ba}', Script::Kaithi), ('\u{110bb}', '\u{110bc}', Script::Kaithi), ('\u{110bd}', - '\u{110bd}', Script::Kaithi), ('\u{110be}', '\u{110c1}', Script::Kaithi), ('\u{110cd}', - '\u{110cd}', Script::Kaithi), ('\u{110d0}', '\u{110e8}', Script::Sora_Sompeng), - ('\u{110f0}', '\u{110f9}', Script::Sora_Sompeng), ('\u{11100}', '\u{11102}', - Script::Chakma), ('\u{11103}', '\u{11126}', Script::Chakma), ('\u{11127}', '\u{1112b}', - Script::Chakma), ('\u{1112c}', '\u{1112c}', Script::Chakma), ('\u{1112d}', '\u{11134}', - Script::Chakma), ('\u{11136}', '\u{1113f}', Script::Chakma), ('\u{11140}', '\u{11143}', - Script::Chakma), ('\u{11144}', '\u{11144}', Script::Chakma), ('\u{11145}', '\u{11146}', - Script::Chakma), ('\u{11147}', '\u{11147}', Script::Chakma), ('\u{11150}', '\u{11172}', - Script::Mahajani), ('\u{11173}', '\u{11173}', Script::Mahajani), ('\u{11174}', - '\u{11175}', Script::Mahajani), ('\u{11176}', '\u{11176}', Script::Mahajani), - ('\u{11180}', '\u{11181}', Script::Sharada), ('\u{11182}', '\u{11182}', Script::Sharada), - ('\u{11183}', '\u{111b2}', Script::Sharada), ('\u{111b3}', '\u{111b5}', Script::Sharada), - ('\u{111b6}', '\u{111be}', Script::Sharada), ('\u{111bf}', '\u{111c0}', Script::Sharada), - ('\u{111c1}', '\u{111c4}', Script::Sharada), ('\u{111c5}', '\u{111c8}', Script::Sharada), - ('\u{111c9}', '\u{111cc}', Script::Sharada), ('\u{111cd}', '\u{111cd}', Script::Sharada), - ('\u{111ce}', '\u{111ce}', Script::Sharada), ('\u{111cf}', '\u{111cf}', Script::Sharada), - ('\u{111d0}', '\u{111d9}', Script::Sharada), ('\u{111da}', '\u{111da}', Script::Sharada), - ('\u{111db}', '\u{111db}', Script::Sharada), ('\u{111dc}', '\u{111dc}', Script::Sharada), - ('\u{111dd}', '\u{111df}', Script::Sharada), ('\u{111e1}', '\u{111f4}', Script::Sinhala), - ('\u{11200}', '\u{11211}', Script::Khojki), ('\u{11213}', '\u{1122b}', Script::Khojki), - ('\u{1122c}', '\u{1122e}', Script::Khojki), ('\u{1122f}', '\u{11231}', Script::Khojki), - ('\u{11232}', '\u{11233}', Script::Khojki), ('\u{11234}', '\u{11234}', Script::Khojki), - ('\u{11235}', '\u{11235}', Script::Khojki), ('\u{11236}', '\u{11237}', Script::Khojki), - ('\u{11238}', '\u{1123d}', Script::Khojki), ('\u{1123e}', '\u{1123e}', Script::Khojki), - ('\u{11280}', '\u{11286}', Script::Multani), ('\u{11288}', '\u{11288}', Script::Multani), - ('\u{1128a}', '\u{1128d}', Script::Multani), ('\u{1128f}', '\u{1129d}', Script::Multani), - ('\u{1129f}', '\u{112a8}', Script::Multani), ('\u{112a9}', '\u{112a9}', Script::Multani), - ('\u{112b0}', '\u{112de}', Script::Khudawadi), ('\u{112df}', '\u{112df}', - Script::Khudawadi), ('\u{112e0}', '\u{112e2}', Script::Khudawadi), ('\u{112e3}', - '\u{112ea}', Script::Khudawadi), ('\u{112f0}', '\u{112f9}', Script::Khudawadi), - ('\u{11300}', '\u{11301}', Script::Grantha), ('\u{11302}', '\u{11303}', Script::Grantha), - ('\u{11305}', '\u{1130c}', Script::Grantha), ('\u{1130f}', '\u{11310}', Script::Grantha), - ('\u{11313}', '\u{11328}', Script::Grantha), ('\u{1132a}', '\u{11330}', Script::Grantha), - ('\u{11332}', '\u{11333}', Script::Grantha), ('\u{11335}', '\u{11339}', Script::Grantha), - ('\u{1133b}', '\u{1133b}', Script::Inherited), ('\u{1133c}', '\u{1133c}', - Script::Grantha), ('\u{1133d}', '\u{1133d}', Script::Grantha), ('\u{1133e}', '\u{1133f}', - Script::Grantha), ('\u{11340}', '\u{11340}', Script::Grantha), ('\u{11341}', '\u{11344}', - Script::Grantha), ('\u{11347}', '\u{11348}', Script::Grantha), ('\u{1134b}', '\u{1134d}', - Script::Grantha), ('\u{11350}', '\u{11350}', Script::Grantha), ('\u{11357}', '\u{11357}', - Script::Grantha), ('\u{1135d}', '\u{11361}', Script::Grantha), ('\u{11362}', '\u{11363}', - Script::Grantha), ('\u{11366}', '\u{1136c}', Script::Grantha), ('\u{11370}', '\u{11374}', - Script::Grantha), ('\u{11400}', '\u{11434}', Script::Newa), ('\u{11435}', '\u{11437}', - Script::Newa), ('\u{11438}', '\u{1143f}', Script::Newa), ('\u{11440}', '\u{11441}', - Script::Newa), ('\u{11442}', '\u{11444}', Script::Newa), ('\u{11445}', '\u{11445}', - Script::Newa), ('\u{11446}', '\u{11446}', Script::Newa), ('\u{11447}', '\u{1144a}', - Script::Newa), ('\u{1144b}', '\u{1144f}', Script::Newa), ('\u{11450}', '\u{11459}', - Script::Newa), ('\u{1145a}', '\u{1145b}', Script::Newa), ('\u{1145d}', '\u{1145d}', - Script::Newa), ('\u{1145e}', '\u{1145e}', Script::Newa), ('\u{1145f}', '\u{11461}', - Script::Newa), ('\u{11480}', '\u{114af}', Script::Tirhuta), ('\u{114b0}', '\u{114b2}', - Script::Tirhuta), ('\u{114b3}', '\u{114b8}', Script::Tirhuta), ('\u{114b9}', '\u{114b9}', - Script::Tirhuta), ('\u{114ba}', '\u{114ba}', Script::Tirhuta), ('\u{114bb}', '\u{114be}', - Script::Tirhuta), ('\u{114bf}', '\u{114c0}', Script::Tirhuta), ('\u{114c1}', '\u{114c1}', - Script::Tirhuta), ('\u{114c2}', '\u{114c3}', Script::Tirhuta), ('\u{114c4}', '\u{114c5}', - Script::Tirhuta), ('\u{114c6}', '\u{114c6}', Script::Tirhuta), ('\u{114c7}', '\u{114c7}', - Script::Tirhuta), ('\u{114d0}', '\u{114d9}', Script::Tirhuta), ('\u{11580}', '\u{115ae}', - Script::Siddham), ('\u{115af}', '\u{115b1}', Script::Siddham), ('\u{115b2}', '\u{115b5}', - Script::Siddham), ('\u{115b8}', '\u{115bb}', Script::Siddham), ('\u{115bc}', '\u{115bd}', - Script::Siddham), ('\u{115be}', '\u{115be}', Script::Siddham), ('\u{115bf}', '\u{115c0}', - Script::Siddham), ('\u{115c1}', '\u{115d7}', Script::Siddham), ('\u{115d8}', '\u{115db}', - Script::Siddham), ('\u{115dc}', '\u{115dd}', Script::Siddham), ('\u{11600}', '\u{1162f}', - Script::Modi), ('\u{11630}', '\u{11632}', Script::Modi), ('\u{11633}', '\u{1163a}', - Script::Modi), ('\u{1163b}', '\u{1163c}', Script::Modi), ('\u{1163d}', '\u{1163d}', - Script::Modi), ('\u{1163e}', '\u{1163e}', Script::Modi), ('\u{1163f}', '\u{11640}', - Script::Modi), ('\u{11641}', '\u{11643}', Script::Modi), ('\u{11644}', '\u{11644}', - Script::Modi), ('\u{11650}', '\u{11659}', Script::Modi), ('\u{11660}', '\u{1166c}', - Script::Mongolian), ('\u{11680}', '\u{116aa}', Script::Takri), ('\u{116ab}', '\u{116ab}', - Script::Takri), ('\u{116ac}', '\u{116ac}', Script::Takri), ('\u{116ad}', '\u{116ad}', - Script::Takri), ('\u{116ae}', '\u{116af}', Script::Takri), ('\u{116b0}', '\u{116b5}', - Script::Takri), ('\u{116b6}', '\u{116b6}', Script::Takri), ('\u{116b7}', '\u{116b7}', - Script::Takri), ('\u{116b8}', '\u{116b8}', Script::Takri), ('\u{116c0}', '\u{116c9}', - Script::Takri), ('\u{11700}', '\u{1171a}', Script::Ahom), ('\u{1171d}', '\u{1171f}', - Script::Ahom), ('\u{11720}', '\u{11721}', Script::Ahom), ('\u{11722}', '\u{11725}', - Script::Ahom), ('\u{11726}', '\u{11726}', Script::Ahom), ('\u{11727}', '\u{1172b}', - Script::Ahom), ('\u{11730}', '\u{11739}', Script::Ahom), ('\u{1173a}', '\u{1173b}', - Script::Ahom), ('\u{1173c}', '\u{1173e}', Script::Ahom), ('\u{1173f}', '\u{1173f}', - Script::Ahom), ('\u{11800}', '\u{1182b}', Script::Dogra), ('\u{1182c}', '\u{1182e}', - Script::Dogra), ('\u{1182f}', '\u{11837}', Script::Dogra), ('\u{11838}', '\u{11838}', - Script::Dogra), ('\u{11839}', '\u{1183a}', Script::Dogra), ('\u{1183b}', '\u{1183b}', - Script::Dogra), ('\u{118a0}', '\u{118df}', Script::Warang_Citi), ('\u{118e0}', - '\u{118e9}', Script::Warang_Citi), ('\u{118ea}', '\u{118f2}', Script::Warang_Citi), - ('\u{118ff}', '\u{118ff}', Script::Warang_Citi), ('\u{11900}', '\u{11906}', - Script::Dives_Akuru), ('\u{11909}', '\u{11909}', Script::Dives_Akuru), ('\u{1190c}', - '\u{11913}', Script::Dives_Akuru), ('\u{11915}', '\u{11916}', Script::Dives_Akuru), - ('\u{11918}', '\u{1192f}', Script::Dives_Akuru), ('\u{11930}', '\u{11935}', - Script::Dives_Akuru), ('\u{11937}', '\u{11938}', Script::Dives_Akuru), ('\u{1193b}', - '\u{1193c}', Script::Dives_Akuru), ('\u{1193d}', '\u{1193d}', Script::Dives_Akuru), - ('\u{1193e}', '\u{1193e}', Script::Dives_Akuru), ('\u{1193f}', '\u{1193f}', - Script::Dives_Akuru), ('\u{11940}', '\u{11940}', Script::Dives_Akuru), ('\u{11941}', - '\u{11941}', Script::Dives_Akuru), ('\u{11942}', '\u{11942}', Script::Dives_Akuru), - ('\u{11943}', '\u{11943}', Script::Dives_Akuru), ('\u{11944}', '\u{11946}', - Script::Dives_Akuru), ('\u{11950}', '\u{11959}', Script::Dives_Akuru), ('\u{119a0}', - '\u{119a7}', Script::Nandinagari), ('\u{119aa}', '\u{119d0}', Script::Nandinagari), - ('\u{119d1}', '\u{119d3}', Script::Nandinagari), ('\u{119d4}', '\u{119d7}', - Script::Nandinagari), ('\u{119da}', '\u{119db}', Script::Nandinagari), ('\u{119dc}', - '\u{119df}', Script::Nandinagari), ('\u{119e0}', '\u{119e0}', Script::Nandinagari), - ('\u{119e1}', '\u{119e1}', Script::Nandinagari), ('\u{119e2}', '\u{119e2}', - Script::Nandinagari), ('\u{119e3}', '\u{119e3}', Script::Nandinagari), ('\u{119e4}', - '\u{119e4}', Script::Nandinagari), ('\u{11a00}', '\u{11a00}', Script::Zanabazar_Square), - ('\u{11a01}', '\u{11a0a}', Script::Zanabazar_Square), ('\u{11a0b}', '\u{11a32}', - Script::Zanabazar_Square), ('\u{11a33}', '\u{11a38}', Script::Zanabazar_Square), - ('\u{11a39}', '\u{11a39}', Script::Zanabazar_Square), ('\u{11a3a}', '\u{11a3a}', - Script::Zanabazar_Square), ('\u{11a3b}', '\u{11a3e}', Script::Zanabazar_Square), - ('\u{11a3f}', '\u{11a46}', Script::Zanabazar_Square), ('\u{11a47}', '\u{11a47}', - Script::Zanabazar_Square), ('\u{11a50}', '\u{11a50}', Script::Soyombo), ('\u{11a51}', - '\u{11a56}', Script::Soyombo), ('\u{11a57}', '\u{11a58}', Script::Soyombo), ('\u{11a59}', - '\u{11a5b}', Script::Soyombo), ('\u{11a5c}', '\u{11a89}', Script::Soyombo), ('\u{11a8a}', - '\u{11a96}', Script::Soyombo), ('\u{11a97}', '\u{11a97}', Script::Soyombo), ('\u{11a98}', - '\u{11a99}', Script::Soyombo), ('\u{11a9a}', '\u{11a9c}', Script::Soyombo), ('\u{11a9d}', - '\u{11a9d}', Script::Soyombo), ('\u{11a9e}', '\u{11aa2}', Script::Soyombo), ('\u{11ac0}', - '\u{11af8}', Script::Pau_Cin_Hau), ('\u{11c00}', '\u{11c08}', Script::Bhaiksuki), - ('\u{11c0a}', '\u{11c2e}', Script::Bhaiksuki), ('\u{11c2f}', '\u{11c2f}', - Script::Bhaiksuki), ('\u{11c30}', '\u{11c36}', Script::Bhaiksuki), ('\u{11c38}', - '\u{11c3d}', Script::Bhaiksuki), ('\u{11c3e}', '\u{11c3e}', Script::Bhaiksuki), - ('\u{11c3f}', '\u{11c3f}', Script::Bhaiksuki), ('\u{11c40}', '\u{11c40}', - Script::Bhaiksuki), ('\u{11c41}', '\u{11c45}', Script::Bhaiksuki), ('\u{11c50}', - '\u{11c59}', Script::Bhaiksuki), ('\u{11c5a}', '\u{11c6c}', Script::Bhaiksuki), - ('\u{11c70}', '\u{11c71}', Script::Marchen), ('\u{11c72}', '\u{11c8f}', Script::Marchen), - ('\u{11c92}', '\u{11ca7}', Script::Marchen), ('\u{11ca9}', '\u{11ca9}', Script::Marchen), - ('\u{11caa}', '\u{11cb0}', Script::Marchen), ('\u{11cb1}', '\u{11cb1}', Script::Marchen), - ('\u{11cb2}', '\u{11cb3}', Script::Marchen), ('\u{11cb4}', '\u{11cb4}', Script::Marchen), - ('\u{11cb5}', '\u{11cb6}', Script::Marchen), ('\u{11d00}', '\u{11d06}', - Script::Masaram_Gondi), ('\u{11d08}', '\u{11d09}', Script::Masaram_Gondi), ('\u{11d0b}', - '\u{11d30}', Script::Masaram_Gondi), ('\u{11d31}', '\u{11d36}', Script::Masaram_Gondi), - ('\u{11d3a}', '\u{11d3a}', Script::Masaram_Gondi), ('\u{11d3c}', '\u{11d3d}', - Script::Masaram_Gondi), ('\u{11d3f}', '\u{11d45}', Script::Masaram_Gondi), ('\u{11d46}', - '\u{11d46}', Script::Masaram_Gondi), ('\u{11d47}', '\u{11d47}', Script::Masaram_Gondi), - ('\u{11d50}', '\u{11d59}', Script::Masaram_Gondi), ('\u{11d60}', '\u{11d65}', - Script::Gunjala_Gondi), ('\u{11d67}', '\u{11d68}', Script::Gunjala_Gondi), ('\u{11d6a}', - '\u{11d89}', Script::Gunjala_Gondi), ('\u{11d8a}', '\u{11d8e}', Script::Gunjala_Gondi), - ('\u{11d90}', '\u{11d91}', Script::Gunjala_Gondi), ('\u{11d93}', '\u{11d94}', - Script::Gunjala_Gondi), ('\u{11d95}', '\u{11d95}', Script::Gunjala_Gondi), ('\u{11d96}', - '\u{11d96}', Script::Gunjala_Gondi), ('\u{11d97}', '\u{11d97}', Script::Gunjala_Gondi), - ('\u{11d98}', '\u{11d98}', Script::Gunjala_Gondi), ('\u{11da0}', '\u{11da9}', - Script::Gunjala_Gondi), ('\u{11ee0}', '\u{11ef2}', Script::Makasar), ('\u{11ef3}', - '\u{11ef4}', Script::Makasar), ('\u{11ef5}', '\u{11ef6}', Script::Makasar), ('\u{11ef7}', - '\u{11ef8}', Script::Makasar), ('\u{11fb0}', '\u{11fb0}', Script::Lisu), ('\u{11fc0}', - '\u{11fd4}', Script::Tamil), ('\u{11fd5}', '\u{11fdc}', Script::Tamil), ('\u{11fdd}', - '\u{11fe0}', Script::Tamil), ('\u{11fe1}', '\u{11ff1}', Script::Tamil), ('\u{11fff}', - '\u{11fff}', Script::Tamil), ('\u{12000}', '\u{12399}', Script::Cuneiform), ('\u{12400}', - '\u{1246e}', Script::Cuneiform), ('\u{12470}', '\u{12474}', Script::Cuneiform), - ('\u{12480}', '\u{12543}', Script::Cuneiform), ('\u{13000}', '\u{1342e}', - Script::Egyptian_Hieroglyphs), ('\u{13430}', '\u{13438}', Script::Egyptian_Hieroglyphs), + '\u{10ead}', Script::Yezidi), ('\u{10eb0}', '\u{10eb1}', Script::Yezidi), ('\u{10efd}', + '\u{10eff}', Script::Arabic), ('\u{10f00}', '\u{10f1c}', Script::Old_Sogdian), + ('\u{10f1d}', '\u{10f26}', Script::Old_Sogdian), ('\u{10f27}', '\u{10f27}', + Script::Old_Sogdian), ('\u{10f30}', '\u{10f45}', Script::Sogdian), ('\u{10f46}', + '\u{10f50}', Script::Sogdian), ('\u{10f51}', '\u{10f54}', Script::Sogdian), ('\u{10f55}', + '\u{10f59}', Script::Sogdian), ('\u{10f70}', '\u{10f81}', Script::Old_Uyghur), + ('\u{10f82}', '\u{10f85}', Script::Old_Uyghur), ('\u{10f86}', '\u{10f89}', + Script::Old_Uyghur), ('\u{10fb0}', '\u{10fc4}', Script::Chorasmian), ('\u{10fc5}', + '\u{10fcb}', Script::Chorasmian), ('\u{10fe0}', '\u{10ff6}', Script::Elymaic), + ('\u{11000}', '\u{11000}', Script::Brahmi), ('\u{11001}', '\u{11001}', Script::Brahmi), + ('\u{11002}', '\u{11002}', Script::Brahmi), ('\u{11003}', '\u{11037}', Script::Brahmi), + ('\u{11038}', '\u{11046}', Script::Brahmi), ('\u{11047}', '\u{1104d}', Script::Brahmi), + ('\u{11052}', '\u{11065}', Script::Brahmi), ('\u{11066}', '\u{1106f}', Script::Brahmi), + ('\u{11070}', '\u{11070}', Script::Brahmi), ('\u{11071}', '\u{11072}', Script::Brahmi), + ('\u{11073}', '\u{11074}', Script::Brahmi), ('\u{11075}', '\u{11075}', Script::Brahmi), + ('\u{1107f}', '\u{1107f}', Script::Brahmi), ('\u{11080}', '\u{11081}', Script::Kaithi), + ('\u{11082}', '\u{11082}', Script::Kaithi), ('\u{11083}', '\u{110af}', Script::Kaithi), + ('\u{110b0}', '\u{110b2}', Script::Kaithi), ('\u{110b3}', '\u{110b6}', Script::Kaithi), + ('\u{110b7}', '\u{110b8}', Script::Kaithi), ('\u{110b9}', '\u{110ba}', Script::Kaithi), + ('\u{110bb}', '\u{110bc}', Script::Kaithi), ('\u{110bd}', '\u{110bd}', Script::Kaithi), + ('\u{110be}', '\u{110c1}', Script::Kaithi), ('\u{110c2}', '\u{110c2}', Script::Kaithi), + ('\u{110cd}', '\u{110cd}', Script::Kaithi), ('\u{110d0}', '\u{110e8}', + Script::Sora_Sompeng), ('\u{110f0}', '\u{110f9}', Script::Sora_Sompeng), ('\u{11100}', + '\u{11102}', Script::Chakma), ('\u{11103}', '\u{11126}', Script::Chakma), ('\u{11127}', + '\u{1112b}', Script::Chakma), ('\u{1112c}', '\u{1112c}', Script::Chakma), ('\u{1112d}', + '\u{11134}', Script::Chakma), ('\u{11136}', '\u{1113f}', Script::Chakma), ('\u{11140}', + '\u{11143}', Script::Chakma), ('\u{11144}', '\u{11144}', Script::Chakma), ('\u{11145}', + '\u{11146}', Script::Chakma), ('\u{11147}', '\u{11147}', Script::Chakma), ('\u{11150}', + '\u{11172}', Script::Mahajani), ('\u{11173}', '\u{11173}', Script::Mahajani), + ('\u{11174}', '\u{11175}', Script::Mahajani), ('\u{11176}', '\u{11176}', + Script::Mahajani), ('\u{11180}', '\u{11181}', Script::Sharada), ('\u{11182}', '\u{11182}', + Script::Sharada), ('\u{11183}', '\u{111b2}', Script::Sharada), ('\u{111b3}', '\u{111b5}', + Script::Sharada), ('\u{111b6}', '\u{111be}', Script::Sharada), ('\u{111bf}', '\u{111c0}', + Script::Sharada), ('\u{111c1}', '\u{111c4}', Script::Sharada), ('\u{111c5}', '\u{111c8}', + Script::Sharada), ('\u{111c9}', '\u{111cc}', Script::Sharada), ('\u{111cd}', '\u{111cd}', + Script::Sharada), ('\u{111ce}', '\u{111ce}', Script::Sharada), ('\u{111cf}', '\u{111cf}', + Script::Sharada), ('\u{111d0}', '\u{111d9}', Script::Sharada), ('\u{111da}', '\u{111da}', + Script::Sharada), ('\u{111db}', '\u{111db}', Script::Sharada), ('\u{111dc}', '\u{111dc}', + Script::Sharada), ('\u{111dd}', '\u{111df}', Script::Sharada), ('\u{111e1}', '\u{111f4}', + Script::Sinhala), ('\u{11200}', '\u{11211}', Script::Khojki), ('\u{11213}', '\u{1122b}', + Script::Khojki), ('\u{1122c}', '\u{1122e}', Script::Khojki), ('\u{1122f}', '\u{11231}', + Script::Khojki), ('\u{11232}', '\u{11233}', Script::Khojki), ('\u{11234}', '\u{11234}', + Script::Khojki), ('\u{11235}', '\u{11235}', Script::Khojki), ('\u{11236}', '\u{11237}', + Script::Khojki), ('\u{11238}', '\u{1123d}', Script::Khojki), ('\u{1123e}', '\u{1123e}', + Script::Khojki), ('\u{1123f}', '\u{11240}', Script::Khojki), ('\u{11241}', '\u{11241}', + Script::Khojki), ('\u{11280}', '\u{11286}', Script::Multani), ('\u{11288}', '\u{11288}', + Script::Multani), ('\u{1128a}', '\u{1128d}', Script::Multani), ('\u{1128f}', '\u{1129d}', + Script::Multani), ('\u{1129f}', '\u{112a8}', Script::Multani), ('\u{112a9}', '\u{112a9}', + Script::Multani), ('\u{112b0}', '\u{112de}', Script::Khudawadi), ('\u{112df}', + '\u{112df}', Script::Khudawadi), ('\u{112e0}', '\u{112e2}', Script::Khudawadi), + ('\u{112e3}', '\u{112ea}', Script::Khudawadi), ('\u{112f0}', '\u{112f9}', + Script::Khudawadi), ('\u{11300}', '\u{11301}', Script::Grantha), ('\u{11302}', + '\u{11303}', Script::Grantha), ('\u{11305}', '\u{1130c}', Script::Grantha), ('\u{1130f}', + '\u{11310}', Script::Grantha), ('\u{11313}', '\u{11328}', Script::Grantha), ('\u{1132a}', + '\u{11330}', Script::Grantha), ('\u{11332}', '\u{11333}', Script::Grantha), ('\u{11335}', + '\u{11339}', Script::Grantha), ('\u{1133b}', '\u{1133b}', Script::Inherited), + ('\u{1133c}', '\u{1133c}', Script::Grantha), ('\u{1133d}', '\u{1133d}', Script::Grantha), + ('\u{1133e}', '\u{1133f}', Script::Grantha), ('\u{11340}', '\u{11340}', Script::Grantha), + ('\u{11341}', '\u{11344}', Script::Grantha), ('\u{11347}', '\u{11348}', Script::Grantha), + ('\u{1134b}', '\u{1134d}', Script::Grantha), ('\u{11350}', '\u{11350}', Script::Grantha), + ('\u{11357}', '\u{11357}', Script::Grantha), ('\u{1135d}', '\u{11361}', Script::Grantha), + ('\u{11362}', '\u{11363}', Script::Grantha), ('\u{11366}', '\u{1136c}', Script::Grantha), + ('\u{11370}', '\u{11374}', Script::Grantha), ('\u{11400}', '\u{11434}', Script::Newa), + ('\u{11435}', '\u{11437}', Script::Newa), ('\u{11438}', '\u{1143f}', Script::Newa), + ('\u{11440}', '\u{11441}', Script::Newa), ('\u{11442}', '\u{11444}', Script::Newa), + ('\u{11445}', '\u{11445}', Script::Newa), ('\u{11446}', '\u{11446}', Script::Newa), + ('\u{11447}', '\u{1144a}', Script::Newa), ('\u{1144b}', '\u{1144f}', Script::Newa), + ('\u{11450}', '\u{11459}', Script::Newa), ('\u{1145a}', '\u{1145b}', Script::Newa), + ('\u{1145d}', '\u{1145d}', Script::Newa), ('\u{1145e}', '\u{1145e}', Script::Newa), + ('\u{1145f}', '\u{11461}', Script::Newa), ('\u{11480}', '\u{114af}', Script::Tirhuta), + ('\u{114b0}', '\u{114b2}', Script::Tirhuta), ('\u{114b3}', '\u{114b8}', Script::Tirhuta), + ('\u{114b9}', '\u{114b9}', Script::Tirhuta), ('\u{114ba}', '\u{114ba}', Script::Tirhuta), + ('\u{114bb}', '\u{114be}', Script::Tirhuta), ('\u{114bf}', '\u{114c0}', Script::Tirhuta), + ('\u{114c1}', '\u{114c1}', Script::Tirhuta), ('\u{114c2}', '\u{114c3}', Script::Tirhuta), + ('\u{114c4}', '\u{114c5}', Script::Tirhuta), ('\u{114c6}', '\u{114c6}', Script::Tirhuta), + ('\u{114c7}', '\u{114c7}', Script::Tirhuta), ('\u{114d0}', '\u{114d9}', Script::Tirhuta), + ('\u{11580}', '\u{115ae}', Script::Siddham), ('\u{115af}', '\u{115b1}', Script::Siddham), + ('\u{115b2}', '\u{115b5}', Script::Siddham), ('\u{115b8}', '\u{115bb}', Script::Siddham), + ('\u{115bc}', '\u{115bd}', Script::Siddham), ('\u{115be}', '\u{115be}', Script::Siddham), + ('\u{115bf}', '\u{115c0}', Script::Siddham), ('\u{115c1}', '\u{115d7}', Script::Siddham), + ('\u{115d8}', '\u{115db}', Script::Siddham), ('\u{115dc}', '\u{115dd}', Script::Siddham), + ('\u{11600}', '\u{1162f}', Script::Modi), ('\u{11630}', '\u{11632}', Script::Modi), + ('\u{11633}', '\u{1163a}', Script::Modi), ('\u{1163b}', '\u{1163c}', Script::Modi), + ('\u{1163d}', '\u{1163d}', Script::Modi), ('\u{1163e}', '\u{1163e}', Script::Modi), + ('\u{1163f}', '\u{11640}', Script::Modi), ('\u{11641}', '\u{11643}', Script::Modi), + ('\u{11644}', '\u{11644}', Script::Modi), ('\u{11650}', '\u{11659}', Script::Modi), + ('\u{11660}', '\u{1166c}', Script::Mongolian), ('\u{11680}', '\u{116aa}', Script::Takri), + ('\u{116ab}', '\u{116ab}', Script::Takri), ('\u{116ac}', '\u{116ac}', Script::Takri), + ('\u{116ad}', '\u{116ad}', Script::Takri), ('\u{116ae}', '\u{116af}', Script::Takri), + ('\u{116b0}', '\u{116b5}', Script::Takri), ('\u{116b6}', '\u{116b6}', Script::Takri), + ('\u{116b7}', '\u{116b7}', Script::Takri), ('\u{116b8}', '\u{116b8}', Script::Takri), + ('\u{116b9}', '\u{116b9}', Script::Takri), ('\u{116c0}', '\u{116c9}', Script::Takri), + ('\u{11700}', '\u{1171a}', Script::Ahom), ('\u{1171d}', '\u{1171f}', Script::Ahom), + ('\u{11720}', '\u{11721}', Script::Ahom), ('\u{11722}', '\u{11725}', Script::Ahom), + ('\u{11726}', '\u{11726}', Script::Ahom), ('\u{11727}', '\u{1172b}', Script::Ahom), + ('\u{11730}', '\u{11739}', Script::Ahom), ('\u{1173a}', '\u{1173b}', Script::Ahom), + ('\u{1173c}', '\u{1173e}', Script::Ahom), ('\u{1173f}', '\u{1173f}', Script::Ahom), + ('\u{11740}', '\u{11746}', Script::Ahom), ('\u{11800}', '\u{1182b}', Script::Dogra), + ('\u{1182c}', '\u{1182e}', Script::Dogra), ('\u{1182f}', '\u{11837}', Script::Dogra), + ('\u{11838}', '\u{11838}', Script::Dogra), ('\u{11839}', '\u{1183a}', Script::Dogra), + ('\u{1183b}', '\u{1183b}', Script::Dogra), ('\u{118a0}', '\u{118df}', + Script::Warang_Citi), ('\u{118e0}', '\u{118e9}', Script::Warang_Citi), ('\u{118ea}', + '\u{118f2}', Script::Warang_Citi), ('\u{118ff}', '\u{118ff}', Script::Warang_Citi), + ('\u{11900}', '\u{11906}', Script::Dives_Akuru), ('\u{11909}', '\u{11909}', + Script::Dives_Akuru), ('\u{1190c}', '\u{11913}', Script::Dives_Akuru), ('\u{11915}', + '\u{11916}', Script::Dives_Akuru), ('\u{11918}', '\u{1192f}', Script::Dives_Akuru), + ('\u{11930}', '\u{11935}', Script::Dives_Akuru), ('\u{11937}', '\u{11938}', + Script::Dives_Akuru), ('\u{1193b}', '\u{1193c}', Script::Dives_Akuru), ('\u{1193d}', + '\u{1193d}', Script::Dives_Akuru), ('\u{1193e}', '\u{1193e}', Script::Dives_Akuru), + ('\u{1193f}', '\u{1193f}', Script::Dives_Akuru), ('\u{11940}', '\u{11940}', + Script::Dives_Akuru), ('\u{11941}', '\u{11941}', Script::Dives_Akuru), ('\u{11942}', + '\u{11942}', Script::Dives_Akuru), ('\u{11943}', '\u{11943}', Script::Dives_Akuru), + ('\u{11944}', '\u{11946}', Script::Dives_Akuru), ('\u{11950}', '\u{11959}', + Script::Dives_Akuru), ('\u{119a0}', '\u{119a7}', Script::Nandinagari), ('\u{119aa}', + '\u{119d0}', Script::Nandinagari), ('\u{119d1}', '\u{119d3}', Script::Nandinagari), + ('\u{119d4}', '\u{119d7}', Script::Nandinagari), ('\u{119da}', '\u{119db}', + Script::Nandinagari), ('\u{119dc}', '\u{119df}', Script::Nandinagari), ('\u{119e0}', + '\u{119e0}', Script::Nandinagari), ('\u{119e1}', '\u{119e1}', Script::Nandinagari), + ('\u{119e2}', '\u{119e2}', Script::Nandinagari), ('\u{119e3}', '\u{119e3}', + Script::Nandinagari), ('\u{119e4}', '\u{119e4}', Script::Nandinagari), ('\u{11a00}', + '\u{11a00}', Script::Zanabazar_Square), ('\u{11a01}', '\u{11a0a}', + Script::Zanabazar_Square), ('\u{11a0b}', '\u{11a32}', Script::Zanabazar_Square), + ('\u{11a33}', '\u{11a38}', Script::Zanabazar_Square), ('\u{11a39}', '\u{11a39}', + Script::Zanabazar_Square), ('\u{11a3a}', '\u{11a3a}', Script::Zanabazar_Square), + ('\u{11a3b}', '\u{11a3e}', Script::Zanabazar_Square), ('\u{11a3f}', '\u{11a46}', + Script::Zanabazar_Square), ('\u{11a47}', '\u{11a47}', Script::Zanabazar_Square), + ('\u{11a50}', '\u{11a50}', Script::Soyombo), ('\u{11a51}', '\u{11a56}', Script::Soyombo), + ('\u{11a57}', '\u{11a58}', Script::Soyombo), ('\u{11a59}', '\u{11a5b}', Script::Soyombo), + ('\u{11a5c}', '\u{11a89}', Script::Soyombo), ('\u{11a8a}', '\u{11a96}', Script::Soyombo), + ('\u{11a97}', '\u{11a97}', Script::Soyombo), ('\u{11a98}', '\u{11a99}', Script::Soyombo), + ('\u{11a9a}', '\u{11a9c}', Script::Soyombo), ('\u{11a9d}', '\u{11a9d}', Script::Soyombo), + ('\u{11a9e}', '\u{11aa2}', Script::Soyombo), ('\u{11ab0}', '\u{11abf}', + Script::Canadian_Aboriginal), ('\u{11ac0}', '\u{11af8}', Script::Pau_Cin_Hau), + ('\u{11b00}', '\u{11b09}', Script::Devanagari), ('\u{11c00}', '\u{11c08}', + Script::Bhaiksuki), ('\u{11c0a}', '\u{11c2e}', Script::Bhaiksuki), ('\u{11c2f}', + '\u{11c2f}', Script::Bhaiksuki), ('\u{11c30}', '\u{11c36}', Script::Bhaiksuki), + ('\u{11c38}', '\u{11c3d}', Script::Bhaiksuki), ('\u{11c3e}', '\u{11c3e}', + Script::Bhaiksuki), ('\u{11c3f}', '\u{11c3f}', Script::Bhaiksuki), ('\u{11c40}', + '\u{11c40}', Script::Bhaiksuki), ('\u{11c41}', '\u{11c45}', Script::Bhaiksuki), + ('\u{11c50}', '\u{11c59}', Script::Bhaiksuki), ('\u{11c5a}', '\u{11c6c}', + Script::Bhaiksuki), ('\u{11c70}', '\u{11c71}', Script::Marchen), ('\u{11c72}', + '\u{11c8f}', Script::Marchen), ('\u{11c92}', '\u{11ca7}', Script::Marchen), ('\u{11ca9}', + '\u{11ca9}', Script::Marchen), ('\u{11caa}', '\u{11cb0}', Script::Marchen), ('\u{11cb1}', + '\u{11cb1}', Script::Marchen), ('\u{11cb2}', '\u{11cb3}', Script::Marchen), ('\u{11cb4}', + '\u{11cb4}', Script::Marchen), ('\u{11cb5}', '\u{11cb6}', Script::Marchen), ('\u{11d00}', + '\u{11d06}', Script::Masaram_Gondi), ('\u{11d08}', '\u{11d09}', Script::Masaram_Gondi), + ('\u{11d0b}', '\u{11d30}', Script::Masaram_Gondi), ('\u{11d31}', '\u{11d36}', + Script::Masaram_Gondi), ('\u{11d3a}', '\u{11d3a}', Script::Masaram_Gondi), ('\u{11d3c}', + '\u{11d3d}', Script::Masaram_Gondi), ('\u{11d3f}', '\u{11d45}', Script::Masaram_Gondi), + ('\u{11d46}', '\u{11d46}', Script::Masaram_Gondi), ('\u{11d47}', '\u{11d47}', + Script::Masaram_Gondi), ('\u{11d50}', '\u{11d59}', Script::Masaram_Gondi), ('\u{11d60}', + '\u{11d65}', Script::Gunjala_Gondi), ('\u{11d67}', '\u{11d68}', Script::Gunjala_Gondi), + ('\u{11d6a}', '\u{11d89}', Script::Gunjala_Gondi), ('\u{11d8a}', '\u{11d8e}', + Script::Gunjala_Gondi), ('\u{11d90}', '\u{11d91}', Script::Gunjala_Gondi), ('\u{11d93}', + '\u{11d94}', Script::Gunjala_Gondi), ('\u{11d95}', '\u{11d95}', Script::Gunjala_Gondi), + ('\u{11d96}', '\u{11d96}', Script::Gunjala_Gondi), ('\u{11d97}', '\u{11d97}', + Script::Gunjala_Gondi), ('\u{11d98}', '\u{11d98}', Script::Gunjala_Gondi), ('\u{11da0}', + '\u{11da9}', Script::Gunjala_Gondi), ('\u{11ee0}', '\u{11ef2}', Script::Makasar), + ('\u{11ef3}', '\u{11ef4}', Script::Makasar), ('\u{11ef5}', '\u{11ef6}', Script::Makasar), + ('\u{11ef7}', '\u{11ef8}', Script::Makasar), ('\u{11f00}', '\u{11f01}', Script::Kawi), + ('\u{11f02}', '\u{11f02}', Script::Kawi), ('\u{11f03}', '\u{11f03}', Script::Kawi), + ('\u{11f04}', '\u{11f10}', Script::Kawi), ('\u{11f12}', '\u{11f33}', Script::Kawi), + ('\u{11f34}', '\u{11f35}', Script::Kawi), ('\u{11f36}', '\u{11f3a}', Script::Kawi), + ('\u{11f3e}', '\u{11f3f}', Script::Kawi), ('\u{11f40}', '\u{11f40}', Script::Kawi), + ('\u{11f41}', '\u{11f41}', Script::Kawi), ('\u{11f42}', '\u{11f42}', Script::Kawi), + ('\u{11f43}', '\u{11f4f}', Script::Kawi), ('\u{11f50}', '\u{11f59}', Script::Kawi), + ('\u{11fb0}', '\u{11fb0}', Script::Lisu), ('\u{11fc0}', '\u{11fd4}', Script::Tamil), + ('\u{11fd5}', '\u{11fdc}', Script::Tamil), ('\u{11fdd}', '\u{11fe0}', Script::Tamil), + ('\u{11fe1}', '\u{11ff1}', Script::Tamil), ('\u{11fff}', '\u{11fff}', Script::Tamil), + ('\u{12000}', '\u{12399}', Script::Cuneiform), ('\u{12400}', '\u{1246e}', + Script::Cuneiform), ('\u{12470}', '\u{12474}', Script::Cuneiform), ('\u{12480}', + '\u{12543}', Script::Cuneiform), ('\u{12f90}', '\u{12ff0}', Script::Cypro_Minoan), + ('\u{12ff1}', '\u{12ff2}', Script::Cypro_Minoan), ('\u{13000}', '\u{1342f}', + Script::Egyptian_Hieroglyphs), ('\u{13430}', '\u{1343f}', Script::Egyptian_Hieroglyphs), + ('\u{13440}', '\u{13440}', Script::Egyptian_Hieroglyphs), ('\u{13441}', '\u{13446}', + Script::Egyptian_Hieroglyphs), ('\u{13447}', '\u{13455}', Script::Egyptian_Hieroglyphs), ('\u{14400}', '\u{14646}', Script::Anatolian_Hieroglyphs), ('\u{16800}', '\u{16a38}', Script::Bamum), ('\u{16a40}', '\u{16a5e}', Script::Mro), ('\u{16a60}', '\u{16a69}', - Script::Mro), ('\u{16a6e}', '\u{16a6f}', Script::Mro), ('\u{16ad0}', '\u{16aed}', + Script::Mro), ('\u{16a6e}', '\u{16a6f}', Script::Mro), ('\u{16a70}', '\u{16abe}', + Script::Tangsa), ('\u{16ac0}', '\u{16ac9}', Script::Tangsa), ('\u{16ad0}', '\u{16aed}', Script::Bassa_Vah), ('\u{16af0}', '\u{16af4}', Script::Bassa_Vah), ('\u{16af5}', '\u{16af5}', Script::Bassa_Vah), ('\u{16b00}', '\u{16b2f}', Script::Pahawh_Hmong), ('\u{16b30}', '\u{16b36}', Script::Pahawh_Hmong), ('\u{16b37}', '\u{16b3b}', @@ -2866,118 +2986,132 @@ pub fn get_script_extension(c: char) -> Option { '\u{16f50}', Script::Miao), ('\u{16f51}', '\u{16f87}', Script::Miao), ('\u{16f8f}', '\u{16f92}', Script::Miao), ('\u{16f93}', '\u{16f9f}', Script::Miao), ('\u{16fe0}', '\u{16fe0}', Script::Tangut), ('\u{16fe1}', '\u{16fe1}', Script::Nushu), ('\u{16fe2}', - '\u{16fe2}', Script::Common), ('\u{16fe3}', '\u{16fe3}', Script::Common), ('\u{16fe4}', + '\u{16fe2}', Script::Han), ('\u{16fe3}', '\u{16fe3}', Script::Han), ('\u{16fe4}', '\u{16fe4}', Script::Khitan_Small_Script), ('\u{16ff0}', '\u{16ff1}', Script::Han), ('\u{17000}', '\u{187f7}', Script::Tangut), ('\u{18800}', '\u{18aff}', Script::Tangut), ('\u{18b00}', '\u{18cd5}', Script::Khitan_Small_Script), ('\u{18d00}', '\u{18d08}', - Script::Tangut), ('\u{1b000}', '\u{1b000}', Script::Katakana), ('\u{1b001}', '\u{1b11e}', - Script::Hiragana), ('\u{1b150}', '\u{1b152}', Script::Hiragana), ('\u{1b164}', - '\u{1b167}', Script::Katakana), ('\u{1b170}', '\u{1b2fb}', Script::Nushu), ('\u{1bc00}', - '\u{1bc6a}', Script::Duployan), ('\u{1bc70}', '\u{1bc7c}', Script::Duployan), - ('\u{1bc80}', '\u{1bc88}', Script::Duployan), ('\u{1bc90}', '\u{1bc99}', - Script::Duployan), ('\u{1bc9c}', '\u{1bc9c}', Script::Duployan), ('\u{1bc9d}', - '\u{1bc9e}', Script::Duployan), ('\u{1bc9f}', '\u{1bc9f}', Script::Duployan), - ('\u{1bca0}', '\u{1bca3}', Script::Common), ('\u{1d000}', '\u{1d0f5}', Script::Common), - ('\u{1d100}', '\u{1d126}', Script::Common), ('\u{1d129}', '\u{1d164}', Script::Common), - ('\u{1d165}', '\u{1d166}', Script::Common), ('\u{1d167}', '\u{1d169}', Script::Inherited), - ('\u{1d16a}', '\u{1d16c}', Script::Common), ('\u{1d16d}', '\u{1d172}', Script::Common), - ('\u{1d173}', '\u{1d17a}', Script::Common), ('\u{1d17b}', '\u{1d182}', Script::Inherited), - ('\u{1d183}', '\u{1d184}', Script::Common), ('\u{1d185}', '\u{1d18b}', Script::Inherited), - ('\u{1d18c}', '\u{1d1a9}', Script::Common), ('\u{1d1aa}', '\u{1d1ad}', Script::Inherited), - ('\u{1d1ae}', '\u{1d1e8}', Script::Common), ('\u{1d200}', '\u{1d241}', Script::Greek), - ('\u{1d242}', '\u{1d244}', Script::Greek), ('\u{1d245}', '\u{1d245}', Script::Greek), - ('\u{1d2e0}', '\u{1d2f3}', Script::Common), ('\u{1d300}', '\u{1d356}', Script::Common), - ('\u{1d360}', '\u{1d378}', Script::Common), ('\u{1d400}', '\u{1d454}', Script::Common), - ('\u{1d456}', '\u{1d49c}', Script::Common), ('\u{1d49e}', '\u{1d49f}', Script::Common), - ('\u{1d4a2}', '\u{1d4a2}', Script::Common), ('\u{1d4a5}', '\u{1d4a6}', Script::Common), - ('\u{1d4a9}', '\u{1d4ac}', Script::Common), ('\u{1d4ae}', '\u{1d4b9}', Script::Common), - ('\u{1d4bb}', '\u{1d4bb}', Script::Common), ('\u{1d4bd}', '\u{1d4c3}', Script::Common), - ('\u{1d4c5}', '\u{1d505}', Script::Common), ('\u{1d507}', '\u{1d50a}', Script::Common), - ('\u{1d50d}', '\u{1d514}', Script::Common), ('\u{1d516}', '\u{1d51c}', Script::Common), - ('\u{1d51e}', '\u{1d539}', Script::Common), ('\u{1d53b}', '\u{1d53e}', Script::Common), - ('\u{1d540}', '\u{1d544}', Script::Common), ('\u{1d546}', '\u{1d546}', Script::Common), - ('\u{1d54a}', '\u{1d550}', Script::Common), ('\u{1d552}', '\u{1d6a5}', Script::Common), - ('\u{1d6a8}', '\u{1d6c0}', Script::Common), ('\u{1d6c1}', '\u{1d6c1}', Script::Common), - ('\u{1d6c2}', '\u{1d6da}', Script::Common), ('\u{1d6db}', '\u{1d6db}', Script::Common), - ('\u{1d6dc}', '\u{1d6fa}', Script::Common), ('\u{1d6fb}', '\u{1d6fb}', Script::Common), - ('\u{1d6fc}', '\u{1d714}', Script::Common), ('\u{1d715}', '\u{1d715}', Script::Common), - ('\u{1d716}', '\u{1d734}', Script::Common), ('\u{1d735}', '\u{1d735}', Script::Common), - ('\u{1d736}', '\u{1d74e}', Script::Common), ('\u{1d74f}', '\u{1d74f}', Script::Common), - ('\u{1d750}', '\u{1d76e}', Script::Common), ('\u{1d76f}', '\u{1d76f}', Script::Common), - ('\u{1d770}', '\u{1d788}', Script::Common), ('\u{1d789}', '\u{1d789}', Script::Common), - ('\u{1d78a}', '\u{1d7a8}', Script::Common), ('\u{1d7a9}', '\u{1d7a9}', Script::Common), - ('\u{1d7aa}', '\u{1d7c2}', Script::Common), ('\u{1d7c3}', '\u{1d7c3}', Script::Common), - ('\u{1d7c4}', '\u{1d7cb}', Script::Common), ('\u{1d7ce}', '\u{1d7ff}', Script::Common), - ('\u{1d800}', '\u{1d9ff}', Script::SignWriting), ('\u{1da00}', '\u{1da36}', - Script::SignWriting), ('\u{1da37}', '\u{1da3a}', Script::SignWriting), ('\u{1da3b}', - '\u{1da6c}', Script::SignWriting), ('\u{1da6d}', '\u{1da74}', Script::SignWriting), - ('\u{1da75}', '\u{1da75}', Script::SignWriting), ('\u{1da76}', '\u{1da83}', - Script::SignWriting), ('\u{1da84}', '\u{1da84}', Script::SignWriting), ('\u{1da85}', - '\u{1da86}', Script::SignWriting), ('\u{1da87}', '\u{1da8b}', Script::SignWriting), - ('\u{1da9b}', '\u{1da9f}', Script::SignWriting), ('\u{1daa1}', '\u{1daaf}', - Script::SignWriting), ('\u{1e000}', '\u{1e006}', Script::Glagolitic), ('\u{1e008}', - '\u{1e018}', Script::Glagolitic), ('\u{1e01b}', '\u{1e021}', Script::Glagolitic), - ('\u{1e023}', '\u{1e024}', Script::Glagolitic), ('\u{1e026}', '\u{1e02a}', - Script::Glagolitic), ('\u{1e100}', '\u{1e12c}', Script::Nyiakeng_Puachue_Hmong), - ('\u{1e130}', '\u{1e136}', Script::Nyiakeng_Puachue_Hmong), ('\u{1e137}', '\u{1e13d}', + Script::Tangut), ('\u{1aff0}', '\u{1aff3}', Script::Katakana), ('\u{1aff5}', '\u{1affb}', + Script::Katakana), ('\u{1affd}', '\u{1affe}', Script::Katakana), ('\u{1b000}', + '\u{1b000}', Script::Katakana), ('\u{1b001}', '\u{1b11f}', Script::Hiragana), + ('\u{1b120}', '\u{1b122}', Script::Katakana), ('\u{1b132}', '\u{1b132}', + Script::Hiragana), ('\u{1b150}', '\u{1b152}', Script::Hiragana), ('\u{1b155}', + '\u{1b155}', Script::Katakana), ('\u{1b164}', '\u{1b167}', Script::Katakana), + ('\u{1b170}', '\u{1b2fb}', Script::Nushu), ('\u{1bc00}', '\u{1bc6a}', Script::Duployan), + ('\u{1bc70}', '\u{1bc7c}', Script::Duployan), ('\u{1bc80}', '\u{1bc88}', + Script::Duployan), ('\u{1bc90}', '\u{1bc99}', Script::Duployan), ('\u{1bc9c}', + '\u{1bc9c}', Script::Duployan), ('\u{1bc9d}', '\u{1bc9e}', Script::Duployan), + ('\u{1bc9f}', '\u{1bc9f}', Script::Duployan), ('\u{1bca0}', '\u{1bca3}', Script::Common), + ('\u{1cf00}', '\u{1cf2d}', Script::Inherited), ('\u{1cf30}', '\u{1cf46}', + Script::Inherited), ('\u{1cf50}', '\u{1cfc3}', Script::Common), ('\u{1d000}', '\u{1d0f5}', + Script::Common), ('\u{1d100}', '\u{1d126}', Script::Common), ('\u{1d129}', '\u{1d164}', + Script::Common), ('\u{1d165}', '\u{1d166}', Script::Common), ('\u{1d167}', '\u{1d169}', + Script::Inherited), ('\u{1d16a}', '\u{1d16c}', Script::Common), ('\u{1d16d}', '\u{1d172}', + Script::Common), ('\u{1d173}', '\u{1d17a}', Script::Common), ('\u{1d17b}', '\u{1d182}', + Script::Inherited), ('\u{1d183}', '\u{1d184}', Script::Common), ('\u{1d185}', '\u{1d18b}', + Script::Inherited), ('\u{1d18c}', '\u{1d1a9}', Script::Common), ('\u{1d1aa}', '\u{1d1ad}', + Script::Inherited), ('\u{1d1ae}', '\u{1d1ea}', Script::Common), ('\u{1d200}', '\u{1d241}', + Script::Greek), ('\u{1d242}', '\u{1d244}', Script::Greek), ('\u{1d245}', '\u{1d245}', + Script::Greek), ('\u{1d2c0}', '\u{1d2d3}', Script::Common), ('\u{1d2e0}', '\u{1d2f3}', + Script::Common), ('\u{1d300}', '\u{1d356}', Script::Common), ('\u{1d360}', '\u{1d378}', + Script::Common), ('\u{1d400}', '\u{1d454}', Script::Common), ('\u{1d456}', '\u{1d49c}', + Script::Common), ('\u{1d49e}', '\u{1d49f}', Script::Common), ('\u{1d4a2}', '\u{1d4a2}', + Script::Common), ('\u{1d4a5}', '\u{1d4a6}', Script::Common), ('\u{1d4a9}', '\u{1d4ac}', + Script::Common), ('\u{1d4ae}', '\u{1d4b9}', Script::Common), ('\u{1d4bb}', '\u{1d4bb}', + Script::Common), ('\u{1d4bd}', '\u{1d4c3}', Script::Common), ('\u{1d4c5}', '\u{1d505}', + Script::Common), ('\u{1d507}', '\u{1d50a}', Script::Common), ('\u{1d50d}', '\u{1d514}', + Script::Common), ('\u{1d516}', '\u{1d51c}', Script::Common), ('\u{1d51e}', '\u{1d539}', + Script::Common), ('\u{1d53b}', '\u{1d53e}', Script::Common), ('\u{1d540}', '\u{1d544}', + Script::Common), ('\u{1d546}', '\u{1d546}', Script::Common), ('\u{1d54a}', '\u{1d550}', + Script::Common), ('\u{1d552}', '\u{1d6a5}', Script::Common), ('\u{1d6a8}', '\u{1d6c0}', + Script::Common), ('\u{1d6c1}', '\u{1d6c1}', Script::Common), ('\u{1d6c2}', '\u{1d6da}', + Script::Common), ('\u{1d6db}', '\u{1d6db}', Script::Common), ('\u{1d6dc}', '\u{1d6fa}', + Script::Common), ('\u{1d6fb}', '\u{1d6fb}', Script::Common), ('\u{1d6fc}', '\u{1d714}', + Script::Common), ('\u{1d715}', '\u{1d715}', Script::Common), ('\u{1d716}', '\u{1d734}', + Script::Common), ('\u{1d735}', '\u{1d735}', Script::Common), ('\u{1d736}', '\u{1d74e}', + Script::Common), ('\u{1d74f}', '\u{1d74f}', Script::Common), ('\u{1d750}', '\u{1d76e}', + Script::Common), ('\u{1d76f}', '\u{1d76f}', Script::Common), ('\u{1d770}', '\u{1d788}', + Script::Common), ('\u{1d789}', '\u{1d789}', Script::Common), ('\u{1d78a}', '\u{1d7a8}', + Script::Common), ('\u{1d7a9}', '\u{1d7a9}', Script::Common), ('\u{1d7aa}', '\u{1d7c2}', + Script::Common), ('\u{1d7c3}', '\u{1d7c3}', Script::Common), ('\u{1d7c4}', '\u{1d7cb}', + Script::Common), ('\u{1d7ce}', '\u{1d7ff}', Script::Common), ('\u{1d800}', '\u{1d9ff}', + Script::SignWriting), ('\u{1da00}', '\u{1da36}', Script::SignWriting), ('\u{1da37}', + '\u{1da3a}', Script::SignWriting), ('\u{1da3b}', '\u{1da6c}', Script::SignWriting), + ('\u{1da6d}', '\u{1da74}', Script::SignWriting), ('\u{1da75}', '\u{1da75}', + Script::SignWriting), ('\u{1da76}', '\u{1da83}', Script::SignWriting), ('\u{1da84}', + '\u{1da84}', Script::SignWriting), ('\u{1da85}', '\u{1da86}', Script::SignWriting), + ('\u{1da87}', '\u{1da8b}', Script::SignWriting), ('\u{1da9b}', '\u{1da9f}', + Script::SignWriting), ('\u{1daa1}', '\u{1daaf}', Script::SignWriting), ('\u{1df00}', + '\u{1df09}', Script::Latin), ('\u{1df0a}', '\u{1df0a}', Script::Latin), ('\u{1df0b}', + '\u{1df1e}', Script::Latin), ('\u{1df25}', '\u{1df2a}', Script::Latin), ('\u{1e000}', + '\u{1e006}', Script::Glagolitic), ('\u{1e008}', '\u{1e018}', Script::Glagolitic), + ('\u{1e01b}', '\u{1e021}', Script::Glagolitic), ('\u{1e023}', '\u{1e024}', + Script::Glagolitic), ('\u{1e026}', '\u{1e02a}', Script::Glagolitic), ('\u{1e030}', + '\u{1e06d}', Script::Cyrillic), ('\u{1e08f}', '\u{1e08f}', Script::Cyrillic), + ('\u{1e100}', '\u{1e12c}', Script::Nyiakeng_Puachue_Hmong), ('\u{1e130}', '\u{1e136}', + Script::Nyiakeng_Puachue_Hmong), ('\u{1e137}', '\u{1e13d}', Script::Nyiakeng_Puachue_Hmong), ('\u{1e140}', '\u{1e149}', Script::Nyiakeng_Puachue_Hmong), ('\u{1e14e}', '\u{1e14e}', Script::Nyiakeng_Puachue_Hmong), ('\u{1e14f}', '\u{1e14f}', - Script::Nyiakeng_Puachue_Hmong), ('\u{1e2c0}', '\u{1e2eb}', Script::Wancho), ('\u{1e2ec}', + Script::Nyiakeng_Puachue_Hmong), ('\u{1e290}', '\u{1e2ad}', Script::Toto), ('\u{1e2ae}', + '\u{1e2ae}', Script::Toto), ('\u{1e2c0}', '\u{1e2eb}', Script::Wancho), ('\u{1e2ec}', '\u{1e2ef}', Script::Wancho), ('\u{1e2f0}', '\u{1e2f9}', Script::Wancho), ('\u{1e2ff}', - '\u{1e2ff}', Script::Wancho), ('\u{1e800}', '\u{1e8c4}', Script::Mende_Kikakui), - ('\u{1e8c7}', '\u{1e8cf}', Script::Mende_Kikakui), ('\u{1e8d0}', '\u{1e8d6}', - Script::Mende_Kikakui), ('\u{1e900}', '\u{1e943}', Script::Adlam), ('\u{1e944}', - '\u{1e94a}', Script::Adlam), ('\u{1e94b}', '\u{1e94b}', Script::Adlam), ('\u{1e950}', - '\u{1e959}', Script::Adlam), ('\u{1e95e}', '\u{1e95f}', Script::Adlam), ('\u{1ec71}', - '\u{1ecab}', Script::Common), ('\u{1ecac}', '\u{1ecac}', Script::Common), ('\u{1ecad}', - '\u{1ecaf}', Script::Common), ('\u{1ecb0}', '\u{1ecb0}', Script::Common), ('\u{1ecb1}', - '\u{1ecb4}', Script::Common), ('\u{1ed01}', '\u{1ed2d}', Script::Common), ('\u{1ed2e}', - '\u{1ed2e}', Script::Common), ('\u{1ed2f}', '\u{1ed3d}', Script::Common), ('\u{1ee00}', - '\u{1ee03}', Script::Arabic), ('\u{1ee05}', '\u{1ee1f}', Script::Arabic), ('\u{1ee21}', - '\u{1ee22}', Script::Arabic), ('\u{1ee24}', '\u{1ee24}', Script::Arabic), ('\u{1ee27}', - '\u{1ee27}', Script::Arabic), ('\u{1ee29}', '\u{1ee32}', Script::Arabic), ('\u{1ee34}', - '\u{1ee37}', Script::Arabic), ('\u{1ee39}', '\u{1ee39}', Script::Arabic), ('\u{1ee3b}', - '\u{1ee3b}', Script::Arabic), ('\u{1ee42}', '\u{1ee42}', Script::Arabic), ('\u{1ee47}', - '\u{1ee47}', Script::Arabic), ('\u{1ee49}', '\u{1ee49}', Script::Arabic), ('\u{1ee4b}', - '\u{1ee4b}', Script::Arabic), ('\u{1ee4d}', '\u{1ee4f}', Script::Arabic), ('\u{1ee51}', - '\u{1ee52}', Script::Arabic), ('\u{1ee54}', '\u{1ee54}', Script::Arabic), ('\u{1ee57}', - '\u{1ee57}', Script::Arabic), ('\u{1ee59}', '\u{1ee59}', Script::Arabic), ('\u{1ee5b}', - '\u{1ee5b}', Script::Arabic), ('\u{1ee5d}', '\u{1ee5d}', Script::Arabic), ('\u{1ee5f}', - '\u{1ee5f}', Script::Arabic), ('\u{1ee61}', '\u{1ee62}', Script::Arabic), ('\u{1ee64}', - '\u{1ee64}', Script::Arabic), ('\u{1ee67}', '\u{1ee6a}', Script::Arabic), ('\u{1ee6c}', - '\u{1ee72}', Script::Arabic), ('\u{1ee74}', '\u{1ee77}', Script::Arabic), ('\u{1ee79}', - '\u{1ee7c}', Script::Arabic), ('\u{1ee7e}', '\u{1ee7e}', Script::Arabic), ('\u{1ee80}', - '\u{1ee89}', Script::Arabic), ('\u{1ee8b}', '\u{1ee9b}', Script::Arabic), ('\u{1eea1}', - '\u{1eea3}', Script::Arabic), ('\u{1eea5}', '\u{1eea9}', Script::Arabic), ('\u{1eeab}', - '\u{1eebb}', Script::Arabic), ('\u{1eef0}', '\u{1eef1}', Script::Arabic), ('\u{1f000}', - '\u{1f02b}', Script::Common), ('\u{1f030}', '\u{1f093}', Script::Common), ('\u{1f0a0}', - '\u{1f0ae}', Script::Common), ('\u{1f0b1}', '\u{1f0bf}', Script::Common), ('\u{1f0c1}', - '\u{1f0cf}', Script::Common), ('\u{1f0d1}', '\u{1f0f5}', Script::Common), ('\u{1f100}', - '\u{1f10c}', Script::Common), ('\u{1f10d}', '\u{1f1ad}', Script::Common), ('\u{1f1e6}', - '\u{1f1ff}', Script::Common), ('\u{1f200}', '\u{1f200}', Script::Hiragana), ('\u{1f201}', - '\u{1f202}', Script::Common), ('\u{1f210}', '\u{1f23b}', Script::Common), ('\u{1f240}', - '\u{1f248}', Script::Common), ('\u{1f250}', '\u{1f251}', Script::Common), ('\u{1f260}', - '\u{1f265}', Script::Common), ('\u{1f300}', '\u{1f3fa}', Script::Common), ('\u{1f3fb}', - '\u{1f3ff}', Script::Common), ('\u{1f400}', '\u{1f6d7}', Script::Common), ('\u{1f6e0}', - '\u{1f6ec}', Script::Common), ('\u{1f6f0}', '\u{1f6fc}', Script::Common), ('\u{1f700}', - '\u{1f773}', Script::Common), ('\u{1f780}', '\u{1f7d8}', Script::Common), ('\u{1f7e0}', - '\u{1f7eb}', Script::Common), ('\u{1f800}', '\u{1f80b}', Script::Common), ('\u{1f810}', - '\u{1f847}', Script::Common), ('\u{1f850}', '\u{1f859}', Script::Common), ('\u{1f860}', - '\u{1f887}', Script::Common), ('\u{1f890}', '\u{1f8ad}', Script::Common), ('\u{1f8b0}', - '\u{1f8b1}', Script::Common), ('\u{1f900}', '\u{1f978}', Script::Common), ('\u{1f97a}', - '\u{1f9cb}', Script::Common), ('\u{1f9cd}', '\u{1fa53}', Script::Common), ('\u{1fa60}', - '\u{1fa6d}', Script::Common), ('\u{1fa70}', '\u{1fa74}', Script::Common), ('\u{1fa78}', - '\u{1fa7a}', Script::Common), ('\u{1fa80}', '\u{1fa86}', Script::Common), ('\u{1fa90}', - '\u{1faa8}', Script::Common), ('\u{1fab0}', '\u{1fab6}', Script::Common), ('\u{1fac0}', - '\u{1fac2}', Script::Common), ('\u{1fad0}', '\u{1fad6}', Script::Common), ('\u{1fb00}', - '\u{1fb92}', Script::Common), ('\u{1fb94}', '\u{1fbca}', Script::Common), ('\u{1fbf0}', - '\u{1fbf9}', Script::Common), ('\u{20000}', '\u{2a6dd}', Script::Han), ('\u{2a700}', - '\u{2b734}', Script::Han), ('\u{2b740}', '\u{2b81d}', Script::Han), ('\u{2b820}', - '\u{2cea1}', Script::Han), ('\u{2ceb0}', '\u{2ebe0}', Script::Han), ('\u{2f800}', - '\u{2fa1d}', Script::Han), ('\u{30000}', '\u{3134a}', Script::Han), ('\u{e0001}', - '\u{e0001}', Script::Common), ('\u{e0020}', '\u{e007f}', Script::Common), ('\u{e0100}', - '\u{e01ef}', Script::Inherited) + '\u{1e2ff}', Script::Wancho), ('\u{1e4d0}', '\u{1e4ea}', Script::Nag_Mundari), + ('\u{1e4eb}', '\u{1e4eb}', Script::Nag_Mundari), ('\u{1e4ec}', '\u{1e4ef}', + Script::Nag_Mundari), ('\u{1e4f0}', '\u{1e4f9}', Script::Nag_Mundari), ('\u{1e7e0}', + '\u{1e7e6}', Script::Ethiopic), ('\u{1e7e8}', '\u{1e7eb}', Script::Ethiopic), + ('\u{1e7ed}', '\u{1e7ee}', Script::Ethiopic), ('\u{1e7f0}', '\u{1e7fe}', + Script::Ethiopic), ('\u{1e800}', '\u{1e8c4}', Script::Mende_Kikakui), ('\u{1e8c7}', + '\u{1e8cf}', Script::Mende_Kikakui), ('\u{1e8d0}', '\u{1e8d6}', Script::Mende_Kikakui), + ('\u{1e900}', '\u{1e943}', Script::Adlam), ('\u{1e944}', '\u{1e94a}', Script::Adlam), + ('\u{1e94b}', '\u{1e94b}', Script::Adlam), ('\u{1e950}', '\u{1e959}', Script::Adlam), + ('\u{1e95e}', '\u{1e95f}', Script::Adlam), ('\u{1ec71}', '\u{1ecab}', Script::Common), + ('\u{1ecac}', '\u{1ecac}', Script::Common), ('\u{1ecad}', '\u{1ecaf}', Script::Common), + ('\u{1ecb0}', '\u{1ecb0}', Script::Common), ('\u{1ecb1}', '\u{1ecb4}', Script::Common), + ('\u{1ed01}', '\u{1ed2d}', Script::Common), ('\u{1ed2e}', '\u{1ed2e}', Script::Common), + ('\u{1ed2f}', '\u{1ed3d}', Script::Common), ('\u{1ee00}', '\u{1ee03}', Script::Arabic), + ('\u{1ee05}', '\u{1ee1f}', Script::Arabic), ('\u{1ee21}', '\u{1ee22}', Script::Arabic), + ('\u{1ee24}', '\u{1ee24}', Script::Arabic), ('\u{1ee27}', '\u{1ee27}', Script::Arabic), + ('\u{1ee29}', '\u{1ee32}', Script::Arabic), ('\u{1ee34}', '\u{1ee37}', Script::Arabic), + ('\u{1ee39}', '\u{1ee39}', Script::Arabic), ('\u{1ee3b}', '\u{1ee3b}', Script::Arabic), + ('\u{1ee42}', '\u{1ee42}', Script::Arabic), ('\u{1ee47}', '\u{1ee47}', Script::Arabic), + ('\u{1ee49}', '\u{1ee49}', Script::Arabic), ('\u{1ee4b}', '\u{1ee4b}', Script::Arabic), + ('\u{1ee4d}', '\u{1ee4f}', Script::Arabic), ('\u{1ee51}', '\u{1ee52}', Script::Arabic), + ('\u{1ee54}', '\u{1ee54}', Script::Arabic), ('\u{1ee57}', '\u{1ee57}', Script::Arabic), + ('\u{1ee59}', '\u{1ee59}', Script::Arabic), ('\u{1ee5b}', '\u{1ee5b}', Script::Arabic), + ('\u{1ee5d}', '\u{1ee5d}', Script::Arabic), ('\u{1ee5f}', '\u{1ee5f}', Script::Arabic), + ('\u{1ee61}', '\u{1ee62}', Script::Arabic), ('\u{1ee64}', '\u{1ee64}', Script::Arabic), + ('\u{1ee67}', '\u{1ee6a}', Script::Arabic), ('\u{1ee6c}', '\u{1ee72}', Script::Arabic), + ('\u{1ee74}', '\u{1ee77}', Script::Arabic), ('\u{1ee79}', '\u{1ee7c}', Script::Arabic), + ('\u{1ee7e}', '\u{1ee7e}', Script::Arabic), ('\u{1ee80}', '\u{1ee89}', Script::Arabic), + ('\u{1ee8b}', '\u{1ee9b}', Script::Arabic), ('\u{1eea1}', '\u{1eea3}', Script::Arabic), + ('\u{1eea5}', '\u{1eea9}', Script::Arabic), ('\u{1eeab}', '\u{1eebb}', Script::Arabic), + ('\u{1eef0}', '\u{1eef1}', Script::Arabic), ('\u{1f000}', '\u{1f02b}', Script::Common), + ('\u{1f030}', '\u{1f093}', Script::Common), ('\u{1f0a0}', '\u{1f0ae}', Script::Common), + ('\u{1f0b1}', '\u{1f0bf}', Script::Common), ('\u{1f0c1}', '\u{1f0cf}', Script::Common), + ('\u{1f0d1}', '\u{1f0f5}', Script::Common), ('\u{1f100}', '\u{1f10c}', Script::Common), + ('\u{1f10d}', '\u{1f1ad}', Script::Common), ('\u{1f1e6}', '\u{1f1ff}', Script::Common), + ('\u{1f200}', '\u{1f200}', Script::Hiragana), ('\u{1f201}', '\u{1f202}', Script::Common), + ('\u{1f210}', '\u{1f23b}', Script::Common), ('\u{1f240}', '\u{1f248}', Script::Common), + ('\u{1f250}', '\u{1f251}', Script::Common), ('\u{1f260}', '\u{1f265}', Script::Common), + ('\u{1f300}', '\u{1f3fa}', Script::Common), ('\u{1f3fb}', '\u{1f3ff}', Script::Common), + ('\u{1f400}', '\u{1f6d7}', Script::Common), ('\u{1f6dc}', '\u{1f6ec}', Script::Common), + ('\u{1f6f0}', '\u{1f6fc}', Script::Common), ('\u{1f700}', '\u{1f776}', Script::Common), + ('\u{1f77b}', '\u{1f7d9}', Script::Common), ('\u{1f7e0}', '\u{1f7eb}', Script::Common), + ('\u{1f7f0}', '\u{1f7f0}', Script::Common), ('\u{1f800}', '\u{1f80b}', Script::Common), + ('\u{1f810}', '\u{1f847}', Script::Common), ('\u{1f850}', '\u{1f859}', Script::Common), + ('\u{1f860}', '\u{1f887}', Script::Common), ('\u{1f890}', '\u{1f8ad}', Script::Common), + ('\u{1f8b0}', '\u{1f8b1}', Script::Common), ('\u{1f900}', '\u{1fa53}', Script::Common), + ('\u{1fa60}', '\u{1fa6d}', Script::Common), ('\u{1fa70}', '\u{1fa7c}', Script::Common), + ('\u{1fa80}', '\u{1fa88}', Script::Common), ('\u{1fa90}', '\u{1fabd}', Script::Common), + ('\u{1fabf}', '\u{1fac5}', Script::Common), ('\u{1face}', '\u{1fadb}', Script::Common), + ('\u{1fae0}', '\u{1fae8}', Script::Common), ('\u{1faf0}', '\u{1faf8}', Script::Common), + ('\u{1fb00}', '\u{1fb92}', Script::Common), ('\u{1fb94}', '\u{1fbca}', Script::Common), + ('\u{1fbf0}', '\u{1fbf9}', Script::Common), ('\u{20000}', '\u{2a6df}', Script::Han), + ('\u{2a700}', '\u{2b739}', Script::Han), ('\u{2b740}', '\u{2b81d}', Script::Han), + ('\u{2b820}', '\u{2cea1}', Script::Han), ('\u{2ceb0}', '\u{2ebe0}', Script::Han), + ('\u{2f800}', '\u{2fa1d}', Script::Han), ('\u{30000}', '\u{3134a}', Script::Han), + ('\u{31350}', '\u{323af}', Script::Han), ('\u{e0001}', '\u{e0001}', Script::Common), + ('\u{e0020}', '\u{e007f}', Script::Common), ('\u{e0100}', '\u{e01ef}', Script::Inherited) ]; const SCRIPT_EXTENSIONS: &'static [(char, char, ScriptExtension)] = &[ @@ -2986,11 +3120,11 @@ pub fn get_script_extension(c: char) -> Option { '\u{483}', script_extensions::CYRL_PERM), ('\u{484}', '\u{484}', script_extensions::CYRL_GLAG), ('\u{485}', '\u{486}', script_extensions::CYRL_LATN), ('\u{487}', '\u{487}', script_extensions::CYRL_GLAG), ('\u{60c}', '\u{60c}', - script_extensions::ARAB_ROHG_SYRC_THAA_YEZI), ('\u{61b}', '\u{61b}', - script_extensions::ARAB_ROHG_SYRC_THAA_YEZI), ('\u{61c}', '\u{61c}', + script_extensions::ARAB_NKOO_ROHG_SYRC_THAA_YEZI), ('\u{61b}', '\u{61b}', + script_extensions::ARAB_NKOO_ROHG_SYRC_THAA_YEZI), ('\u{61c}', '\u{61c}', script_extensions::ARAB_SYRC_THAA), ('\u{61f}', '\u{61f}', - script_extensions::ARAB_ROHG_SYRC_THAA_YEZI), ('\u{640}', '\u{640}', - script_extensions::ADLM_ARAB_MAND_MANI_PHLP_ROHG_SOGD_SYRC), ('\u{64b}', '\u{655}', + script_extensions::ADLM_ARAB_NKOO_ROHG_SYRC_THAA_YEZI), ('\u{640}', '\u{640}', + script_extensions::ADLM_ARAB_MAND_MANI_OUGR_PHLP_ROHG_SOGD_SYRC), ('\u{64b}', '\u{655}', script_extensions::ARAB_SYRC), ('\u{660}', '\u{669}', script_extensions::ARAB_THAA_YEZI), ('\u{670}', '\u{670}', script_extensions::ARAB_SYRC), ('\u{6d4}', '\u{6d4}', script_extensions::ARAB_ROHG), ('\u{951}', '\u{951}', @@ -3031,10 +3165,11 @@ pub fn get_script_extension(c: char) -> Option { script_extensions::BENG), ('\u{1cf8}', '\u{1cf9}', script_extensions::DEVA_GRAN), ('\u{1cfa}', '\u{1cfa}', script_extensions::NAND), ('\u{1dc0}', '\u{1dc1}', script_extensions::GREK), ('\u{1df8}', '\u{1df8}', script_extensions::CYRL_SYRC), - ('\u{202f}', '\u{202f}', script_extensions::LATN_MONG), ('\u{20f0}', '\u{20f0}', - script_extensions::DEVA_GRAN_LATN), ('\u{2e43}', '\u{2e43}', script_extensions::CYRL_GLAG), - ('\u{3001}', '\u{3002}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{3003}', - '\u{3003}', script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\u{3006}', '\u{3006}', + ('\u{1dfa}', '\u{1dfa}', script_extensions::SYRC), ('\u{202f}', '\u{202f}', + script_extensions::LATN_MONG), ('\u{20f0}', '\u{20f0}', script_extensions::DEVA_GRAN_LATN), + ('\u{2e43}', '\u{2e43}', script_extensions::CYRL_GLAG), ('\u{3001}', '\u{3002}', + script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{3003}', '\u{3003}', + script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\u{3006}', '\u{3006}', script_extensions::HANI), ('\u{3008}', '\u{3008}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{3009}', '\u{3009}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{300a}', '\u{300a}', @@ -3088,23 +3223,27 @@ pub fn get_script_extension(c: char) -> Option { script_extensions::DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SIND_TAKR_TIRH), ('\u{a8f1}', '\u{a8f1}', script_extensions::BENG_DEVA), ('\u{a8f3}', '\u{a8f3}', script_extensions::DEVA_TAML), ('\u{a92e}', '\u{a92e}', script_extensions::KALI_LATN_MYMR), - ('\u{a9cf}', '\u{a9cf}', script_extensions::BUGI_JAVA), ('\u{fdf2}', '\u{fdf2}', - script_extensions::ARAB_THAA), ('\u{fdfd}', '\u{fdfd}', script_extensions::ARAB_THAA), - ('\u{fe45}', '\u{fe46}', script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\u{ff61}', - '\u{ff61}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{ff62}', '\u{ff62}', + ('\u{a9cf}', '\u{a9cf}', script_extensions::BUGI_JAVA), ('\u{fd3e}', '\u{fd3e}', + script_extensions::ARAB_NKOO), ('\u{fd3f}', '\u{fd3f}', script_extensions::ARAB_NKOO), + ('\u{fdf2}', '\u{fdf2}', script_extensions::ARAB_THAA), ('\u{fdfd}', '\u{fdfd}', + script_extensions::ARAB_THAA), ('\u{fe45}', '\u{fe46}', + script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\u{ff61}', '\u{ff61}', + script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{ff62}', '\u{ff62}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{ff63}', '\u{ff63}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{ff64}', '\u{ff65}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\u{ff70}', '\u{ff70}', script_extensions::HIRA_KANA), ('\u{ff9e}', '\u{ff9f}', script_extensions::HIRA_KANA), - ('\u{10100}', '\u{10102}', script_extensions::CPRT_LINB), ('\u{10107}', '\u{10133}', + ('\u{10100}', '\u{10101}', script_extensions::CPMN_CPRT_LINB), ('\u{10102}', '\u{10102}', + script_extensions::CPRT_LINB), ('\u{10107}', '\u{10133}', script_extensions::CPRT_LINA_LINB), ('\u{10137}', '\u{1013f}', script_extensions::CPRT_LINB), ('\u{102e0}', '\u{102e0}', script_extensions::ARAB_COPT), - ('\u{102e1}', '\u{102fb}', script_extensions::ARAB_COPT), ('\u{11301}', '\u{11301}', - script_extensions::GRAN_TAML), ('\u{11303}', '\u{11303}', script_extensions::GRAN_TAML), - ('\u{1133b}', '\u{1133c}', script_extensions::GRAN_TAML), ('\u{11fd0}', '\u{11fd1}', - script_extensions::GRAN_TAML), ('\u{11fd3}', '\u{11fd3}', script_extensions::GRAN_TAML), - ('\u{1bca0}', '\u{1bca3}', script_extensions::DUPL), ('\u{1d360}', '\u{1d371}', - script_extensions::HANI), ('\u{1f250}', '\u{1f251}', script_extensions::HANI) + ('\u{102e1}', '\u{102fb}', script_extensions::ARAB_COPT), ('\u{10af2}', '\u{10af2}', + script_extensions::MANI_OUGR), ('\u{11301}', '\u{11301}', script_extensions::GRAN_TAML), + ('\u{11303}', '\u{11303}', script_extensions::GRAN_TAML), ('\u{1133b}', '\u{1133c}', + script_extensions::GRAN_TAML), ('\u{11fd0}', '\u{11fd1}', script_extensions::GRAN_TAML), + ('\u{11fd3}', '\u{11fd3}', script_extensions::GRAN_TAML), ('\u{1bca0}', '\u{1bca3}', + script_extensions::DUPL), ('\u{1d360}', '\u{1d371}', script_extensions::HANI), ('\u{1f250}', + '\u{1f251}', script_extensions::HANI) ]; diff --git a/vendor/unicode-security/.cargo-checksum.json b/vendor/unicode-security/.cargo-checksum.json index a0a3c205d..286456775 100644 --- a/vendor/unicode-security/.cargo-checksum.json +++ b/vendor/unicode-security/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"651b0fa8d5cbbdd756f4c54cf8f2c7ac0e2c443e3402684612babb2d0e745b5a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"cf597d1e3c462dcac6a525aab647e7b6557e03b1d6a7623ddb571cbfffc089ab","scripts/unicode.py":"44c9110535ff74c16f73276d6b15b42c8b9c5b980ca685f07d32edb068abd5ca","src/confusable_detection.rs":"c837f2ed06e9df60a7111e25471b46e5f61d86858215f548ddd43973fd2a64c4","src/general_security_profile.rs":"e7e979876f9414cec50a58301f635bb4216089f2cb2cab83487fcafb0e13c0ac","src/lib.rs":"4d0fe431eab6b50fd7293b59773f71e07f2fd4232b09d79e040bcf33a824d335","src/mixed_script.rs":"b95a3d5316c0aa6144c6ded12bb6c479df2d513e43157fb29e8dc9a3674d0d93","src/restriction_level.rs":"0e35d97c6b5ac3cf40440e80677caf6724fae7beb5d0f0bf438614a76ab920b0","src/tables.rs":"1d7886386d82b42000f9d55ba2286949da190795e75949f23640e1b25ba4a0fe","src/tests.rs":"a9d4bc171dec6dc6a440c871fa49eb14ece9ef0c248b6742f1233ea5a1d393a0"},"package":"5d87c28edc5b263377e448d6cdcb935c06b95413d8013ba6fae470558ccab18f"} \ No newline at end of file +{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"b719757f69f5e8a66d65f28780173e2a7d12d30ab2d4c636eeeef7cff6dc2256","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"9266090c1c7f321793aa0775763b499eb2f7aa819eb8c8d9a607503cb9487c8e","scripts/unicode.py":"25db65759b92a2f60ca2d4a6ec401a136895eca71732d903023a80c4b6cd5a7f","src/confusable_detection.rs":"c837f2ed06e9df60a7111e25471b46e5f61d86858215f548ddd43973fd2a64c4","src/general_security_profile.rs":"e7e979876f9414cec50a58301f635bb4216089f2cb2cab83487fcafb0e13c0ac","src/lib.rs":"4d0fe431eab6b50fd7293b59773f71e07f2fd4232b09d79e040bcf33a824d335","src/mixed_script.rs":"b95a3d5316c0aa6144c6ded12bb6c479df2d513e43157fb29e8dc9a3674d0d93","src/restriction_level.rs":"1f9831385cb20fda09d608390dc56a1866929104e7d694d4a5a486c60380a002","src/tables.rs":"5459b739f3a4b60bfa1ed4704a9d3a185a8808185842bd3cd8dff1ad2f9f7a70","src/tests.rs":"a9d4bc171dec6dc6a440c871fa49eb14ece9ef0c248b6742f1233ea5a1d393a0"},"package":"9ef5756b3097992b934b06608c69f48448a0fbe804bb1e72b982f6d7983e9e63"} \ No newline at end of file diff --git a/vendor/unicode-security/Cargo.toml b/vendor/unicode-security/Cargo.toml index cb2022812..090882aba 100644 --- a/vendor/unicode-security/Cargo.toml +++ b/vendor/unicode-security/Cargo.toml @@ -3,26 +3,39 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" name = "unicode-security" -version = "0.0.5" -authors = ["Charles Lew ", "Manish Goregaokar "] -exclude = ["target/*", "Cargo.lock"] -description = "Detect possible security problems with Unicode usage\naccording to Unicode Technical Standard #39 rules.\n" +version = "0.1.0" +authors = [ + "Charles Lew ", + "Manish Goregaokar ", +] +exclude = [ + "target/*", + "Cargo.lock", +] +description = """ +Detect possible security problems with Unicode usage +according to Unicode Technical Standard #39 rules. +""" homepage = "https://github.com/unicode-rs/unicode-security" documentation = "https://docs.rs/unicode-security" readme = "README.md" -keywords = ["text", "security", "unicode"] +keywords = [ + "text", + "security", + "unicode", +] license = "MIT/Apache-2.0" repository = "https://github.com/unicode-rs/unicode-security" + [dependencies.compiler_builtins] version = "0.1" optional = true @@ -48,4 +61,8 @@ default-features = false [features] bench = [] default = [] -rustc-dep-of-std = ["std", "core", "compiler_builtins"] +rustc-dep-of-std = [ + "std", + "core", + "compiler_builtins", +] diff --git a/vendor/unicode-security/README.md b/vendor/unicode-security/README.md index 22e8b6d35..bda8739d6 100644 --- a/vendor/unicode-security/README.md +++ b/vendor/unicode-security/README.md @@ -1,7 +1,7 @@ # unicode-security [![Build Status](https://github.com/unicode-rs/unicode-security/workflows/Tests/badge.svg)](https://github.com/unicode-rs/unicode-security/actions) -[![Current Version](https://meritbadge.herokuapp.com/unicode-security)](https://crates.io/crates/unicode-security) +[![Current Version](https://img.shields.io/crates/v/unicode-security.svg)](https://crates.io/crates/unicode-security) [![License: MIT/Apache-2.0](https://img.shields.io/crates/l/unicode-security.svg)](#license) -This crate exposes various utilities from [UAX #39 Unicode Security Mechanisms](https://www.unicode.org/reports/tr39/) \ No newline at end of file +This crate exposes various utilities from [UAX #39 Unicode Security Mechanisms](https://www.unicode.org/reports/tr39/) diff --git a/vendor/unicode-security/scripts/unicode.py b/vendor/unicode-security/scripts/unicode.py index 368b94c89..11ea31e53 100644 --- a/vendor/unicode-security/scripts/unicode.py +++ b/vendor/unicode-security/scripts/unicode.py @@ -39,14 +39,14 @@ preamble = '''// Copyright 2012-2015 The Rust Project Developers. See the COPYRI #![allow(missing_docs, non_upper_case_globals, non_snake_case)] ''' -UNICODE_VERSION = (13, 0, 0) +UNICODE_VERSION = (15, 0, 0) UNICODE_VERSION_NUMBER = "%s.%s.%s" %UNICODE_VERSION # Download a Unicode security table file def fetch(f): if not os.path.exists(os.path.basename(f)): - os.system("curl -O http://www.unicode.org/Public/security/%s/%s" + os.system("curl -O https://www.unicode.org/Public/security/%s/%s" % (UNICODE_VERSION_NUMBER, f)) if not os.path.exists(os.path.basename(f)): @@ -56,7 +56,7 @@ def fetch(f): # Download a UCD table file def fetch_unidata(f): if not os.path.exists(os.path.basename(f)): - os.system("curl -O http://www.unicode.org/Public/%s/ucd/%s" + os.system("curl -O https://www.unicode.org/Public/%s/ucd/%s" % (UNICODE_VERSION_NUMBER, f)) if not os.path.exists(os.path.basename(f)): diff --git a/vendor/unicode-security/src/restriction_level.rs b/vendor/unicode-security/src/restriction_level.rs index adaf07460..b2feedbad 100644 --- a/vendor/unicode-security/src/restriction_level.rs +++ b/vendor/unicode-security/src/restriction_level.rs @@ -48,7 +48,7 @@ impl RestrictionLevelDetection for &'_ str { if !GeneralSecurityProfile::identifier_allowed(ch) { return RestrictionLevel::Unrestricted; } - if ch.is_ascii() { + if !ch.is_ascii() { ascii_only = false; } let ch_set = ch.into(); diff --git a/vendor/unicode-security/src/tables.rs b/vendor/unicode-security/src/tables.rs index 5e4bc1e03..6b72dbb0a 100644 --- a/vendor/unicode-security/src/tables.rs +++ b/vendor/unicode-security/src/tables.rs @@ -14,7 +14,7 @@ /// The version of [Unicode](http://www.unicode.org/) /// that this version of unicode-security is based on. -pub const UNICODE_VERSION: (u64, u64, u64) = (13, 0, 0); +pub const UNICODE_VERSION: (u64, u64, u64) = (15, 0, 0); pub mod util { @@ -133,127 +133,135 @@ pub mod identifier { '\u{6ce}'), ('\u{6cf}', '\u{6cf}'), ('\u{6d0}', '\u{6d3}'), ('\u{6d5}', '\u{6d5}'), ('\u{6e5}', '\u{6e6}'), ('\u{6ee}', '\u{6ef}'), ('\u{6f0}', '\u{6f9}'), ('\u{6fa}', '\u{6fe}'), ('\u{6ff}', '\u{6ff}'), ('\u{750}', '\u{76d}'), ('\u{76e}', '\u{77f}'), - ('\u{780}', '\u{7b0}'), ('\u{7b1}', '\u{7b1}'), ('\u{8a0}', '\u{8a0}'), ('\u{8a1}', - '\u{8a1}'), ('\u{8a2}', '\u{8ac}'), ('\u{8b2}', '\u{8b2}'), ('\u{8b6}', '\u{8bd}'), - ('\u{8be}', '\u{8c7}'), ('\u{901}', '\u{903}'), ('\u{904}', '\u{904}'), ('\u{905}', - '\u{939}'), ('\u{93a}', '\u{93b}'), ('\u{93c}', '\u{94d}'), ('\u{94f}', '\u{94f}'), - ('\u{950}', '\u{950}'), ('\u{956}', '\u{957}'), ('\u{960}', '\u{963}'), ('\u{966}', - '\u{96f}'), ('\u{971}', '\u{972}'), ('\u{973}', '\u{977}'), ('\u{979}', '\u{97a}'), - ('\u{97b}', '\u{97c}'), ('\u{97d}', '\u{97d}'), ('\u{97e}', '\u{97f}'), ('\u{981}', - '\u{983}'), ('\u{985}', '\u{98c}'), ('\u{98f}', '\u{990}'), ('\u{993}', '\u{9a8}'), - ('\u{9aa}', '\u{9b0}'), ('\u{9b2}', '\u{9b2}'), ('\u{9b6}', '\u{9b9}'), ('\u{9bc}', - '\u{9bc}'), ('\u{9bd}', '\u{9bd}'), ('\u{9be}', '\u{9c4}'), ('\u{9c7}', '\u{9c8}'), - ('\u{9cb}', '\u{9cd}'), ('\u{9ce}', '\u{9ce}'), ('\u{9d7}', '\u{9d7}'), ('\u{9e0}', - '\u{9e3}'), ('\u{9e6}', '\u{9f1}'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', '\u{a01}'), - ('\u{a02}', '\u{a02}'), ('\u{a03}', '\u{a03}'), ('\u{a05}', '\u{a0a}'), ('\u{a0f}', - '\u{a10}'), ('\u{a13}', '\u{a28}'), ('\u{a2a}', '\u{a30}'), ('\u{a32}', '\u{a32}'), - ('\u{a35}', '\u{a35}'), ('\u{a38}', '\u{a39}'), ('\u{a3c}', '\u{a3c}'), ('\u{a3e}', - '\u{a42}'), ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a5c}', '\u{a5c}'), - ('\u{a66}', '\u{a74}'), ('\u{a81}', '\u{a83}'), ('\u{a85}', '\u{a8b}'), ('\u{a8c}', - '\u{a8c}'), ('\u{a8d}', '\u{a8d}'), ('\u{a8f}', '\u{a91}'), ('\u{a93}', '\u{aa8}'), - ('\u{aaa}', '\u{ab0}'), ('\u{ab2}', '\u{ab3}'), ('\u{ab5}', '\u{ab9}'), ('\u{abc}', - '\u{ac5}'), ('\u{ac7}', '\u{ac9}'), ('\u{acb}', '\u{acd}'), ('\u{ad0}', '\u{ad0}'), - ('\u{ae0}', '\u{ae0}'), ('\u{ae1}', '\u{ae3}'), ('\u{ae6}', '\u{aef}'), ('\u{afa}', - '\u{aff}'), ('\u{b01}', '\u{b03}'), ('\u{b05}', '\u{b0c}'), ('\u{b0f}', '\u{b10}'), - ('\u{b13}', '\u{b28}'), ('\u{b2a}', '\u{b30}'), ('\u{b32}', '\u{b33}'), ('\u{b35}', - '\u{b35}'), ('\u{b36}', '\u{b39}'), ('\u{b3c}', '\u{b43}'), ('\u{b47}', '\u{b48}'), - ('\u{b4b}', '\u{b4d}'), ('\u{b55}', '\u{b55}'), ('\u{b56}', '\u{b57}'), ('\u{b5f}', - '\u{b61}'), ('\u{b66}', '\u{b6f}'), ('\u{b71}', '\u{b71}'), ('\u{b82}', '\u{b83}'), - ('\u{b85}', '\u{b8a}'), ('\u{b8e}', '\u{b90}'), ('\u{b92}', '\u{b95}'), ('\u{b99}', - '\u{b9a}'), ('\u{b9c}', '\u{b9c}'), ('\u{b9e}', '\u{b9f}'), ('\u{ba3}', '\u{ba4}'), - ('\u{ba8}', '\u{baa}'), ('\u{bae}', '\u{bb5}'), ('\u{bb6}', '\u{bb6}'), ('\u{bb7}', - '\u{bb9}'), ('\u{bbe}', '\u{bc2}'), ('\u{bc6}', '\u{bc8}'), ('\u{bca}', '\u{bcd}'), - ('\u{bd0}', '\u{bd0}'), ('\u{bd7}', '\u{bd7}'), ('\u{be6}', '\u{be6}'), ('\u{be7}', - '\u{bef}'), ('\u{c01}', '\u{c03}'), ('\u{c04}', '\u{c04}'), ('\u{c05}', '\u{c0c}'), - ('\u{c0e}', '\u{c10}'), ('\u{c12}', '\u{c28}'), ('\u{c2a}', '\u{c33}'), ('\u{c35}', - '\u{c39}'), ('\u{c3d}', '\u{c3d}'), ('\u{c3e}', '\u{c44}'), ('\u{c46}', '\u{c48}'), - ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), ('\u{c60}', '\u{c61}'), ('\u{c66}', - '\u{c6f}'), ('\u{c80}', '\u{c80}'), ('\u{c82}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), - ('\u{c8e}', '\u{c90}'), ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', - '\u{cb9}'), ('\u{cbc}', '\u{cbd}'), ('\u{cbe}', '\u{cc4}'), ('\u{cc6}', '\u{cc8}'), - ('\u{cca}', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'), ('\u{ce0}', '\u{ce1}'), ('\u{ce2}', - '\u{ce3}'), ('\u{ce6}', '\u{cef}'), ('\u{cf1}', '\u{cf2}'), ('\u{d00}', '\u{d00}'), - ('\u{d02}', '\u{d03}'), ('\u{d05}', '\u{d0c}'), ('\u{d0e}', '\u{d10}'), ('\u{d12}', - '\u{d28}'), ('\u{d29}', '\u{d29}'), ('\u{d2a}', '\u{d39}'), ('\u{d3a}', '\u{d3a}'), - ('\u{d3d}', '\u{d3d}'), ('\u{d3e}', '\u{d43}'), ('\u{d46}', '\u{d48}'), ('\u{d4a}', - '\u{d4d}'), ('\u{d4e}', '\u{d4e}'), ('\u{d54}', '\u{d56}'), ('\u{d57}', '\u{d57}'), - ('\u{d60}', '\u{d61}'), ('\u{d66}', '\u{d6f}'), ('\u{d7a}', '\u{d7f}'), ('\u{d82}', - '\u{d83}'), ('\u{d85}', '\u{d8e}'), ('\u{d91}', '\u{d96}'), ('\u{d9a}', '\u{da5}'), - ('\u{da7}', '\u{db1}'), ('\u{db3}', '\u{dbb}'), ('\u{dbd}', '\u{dbd}'), ('\u{dc0}', - '\u{dc6}'), ('\u{dca}', '\u{dca}'), ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), - ('\u{dd8}', '\u{dde}'), ('\u{df2}', '\u{df2}'), ('\u{e01}', '\u{e32}'), ('\u{e34}', - '\u{e3a}'), ('\u{e40}', '\u{e4e}'), ('\u{e50}', '\u{e59}'), ('\u{e81}', '\u{e82}'), - ('\u{e84}', '\u{e84}'), ('\u{e86}', '\u{e86}'), ('\u{e87}', '\u{e88}'), ('\u{e89}', - '\u{e89}'), ('\u{e8a}', '\u{e8a}'), ('\u{e8c}', '\u{e8c}'), ('\u{e8d}', '\u{e8d}'), - ('\u{e8e}', '\u{e93}'), ('\u{e94}', '\u{e97}'), ('\u{e98}', '\u{e98}'), ('\u{e99}', - '\u{e9f}'), ('\u{ea0}', '\u{ea0}'), ('\u{ea1}', '\u{ea3}'), ('\u{ea5}', '\u{ea5}'), - ('\u{ea7}', '\u{ea7}'), ('\u{ea8}', '\u{ea9}'), ('\u{eaa}', '\u{eab}'), ('\u{eac}', - '\u{eac}'), ('\u{ead}', '\u{eb2}'), ('\u{eb4}', '\u{eb9}'), ('\u{eba}', '\u{eba}'), - ('\u{ebb}', '\u{ebd}'), ('\u{ec0}', '\u{ec4}'), ('\u{ec6}', '\u{ec6}'), ('\u{ec8}', - '\u{ecd}'), ('\u{ed0}', '\u{ed9}'), ('\u{ede}', '\u{edf}'), ('\u{f00}', '\u{f00}'), - ('\u{f0b}', '\u{f0b}'), ('\u{f20}', '\u{f29}'), ('\u{f35}', '\u{f35}'), ('\u{f37}', - '\u{f37}'), ('\u{f3e}', '\u{f42}'), ('\u{f44}', '\u{f47}'), ('\u{f49}', '\u{f4c}'), - ('\u{f4e}', '\u{f51}'), ('\u{f53}', '\u{f56}'), ('\u{f58}', '\u{f5b}'), ('\u{f5d}', - '\u{f68}'), ('\u{f6a}', '\u{f6a}'), ('\u{f6b}', '\u{f6c}'), ('\u{f71}', '\u{f72}'), - ('\u{f74}', '\u{f74}'), ('\u{f7a}', '\u{f80}'), ('\u{f82}', '\u{f84}'), ('\u{f86}', - '\u{f8b}'), ('\u{f8c}', '\u{f8f}'), ('\u{f90}', '\u{f92}'), ('\u{f94}', '\u{f95}'), - ('\u{f96}', '\u{f96}'), ('\u{f97}', '\u{f97}'), ('\u{f99}', '\u{f9c}'), ('\u{f9e}', - '\u{fa1}'), ('\u{fa3}', '\u{fa6}'), ('\u{fa8}', '\u{fab}'), ('\u{fad}', '\u{fad}'), - ('\u{fae}', '\u{fb0}'), ('\u{fb1}', '\u{fb7}'), ('\u{fb8}', '\u{fb8}'), ('\u{fba}', - '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('\u{1000}', '\u{1021}'), ('\u{1022}', '\u{1022}'), - ('\u{1023}', '\u{1027}'), ('\u{1028}', '\u{1028}'), ('\u{1029}', '\u{102a}'), ('\u{102b}', - '\u{102b}'), ('\u{102c}', '\u{1032}'), ('\u{1033}', '\u{1035}'), ('\u{1036}', '\u{1039}'), - ('\u{103a}', '\u{103f}'), ('\u{1040}', '\u{1049}'), ('\u{1050}', '\u{1059}'), ('\u{105a}', - '\u{1099}'), ('\u{109a}', '\u{109d}'), ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), - ('\u{10d0}', '\u{10f0}'), ('\u{10f7}', '\u{10f8}'), ('\u{10f9}', '\u{10fa}'), ('\u{10fd}', - '\u{10ff}'), ('\u{1200}', '\u{1206}'), ('\u{1207}', '\u{1207}'), ('\u{1208}', '\u{1246}'), - ('\u{1247}', '\u{1247}'), ('\u{1248}', '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', - '\u{1256}'), ('\u{1258}', '\u{1258}'), ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1286}'), - ('\u{1287}', '\u{1287}'), ('\u{1288}', '\u{1288}'), ('\u{128a}', '\u{128d}'), ('\u{1290}', - '\u{12ae}'), ('\u{12af}', '\u{12af}'), ('\u{12b0}', '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), - ('\u{12b8}', '\u{12be}'), ('\u{12c0}', '\u{12c0}'), ('\u{12c2}', '\u{12c5}'), ('\u{12c8}', - '\u{12ce}'), ('\u{12cf}', '\u{12cf}'), ('\u{12d0}', '\u{12d6}'), ('\u{12d8}', '\u{12ee}'), - ('\u{12ef}', '\u{12ef}'), ('\u{12f0}', '\u{130e}'), ('\u{130f}', '\u{130f}'), ('\u{1310}', - '\u{1310}'), ('\u{1312}', '\u{1315}'), ('\u{1318}', '\u{131e}'), ('\u{131f}', '\u{131f}'), - ('\u{1320}', '\u{1346}'), ('\u{1347}', '\u{1347}'), ('\u{1348}', '\u{135a}'), ('\u{135d}', - '\u{135e}'), ('\u{135f}', '\u{135f}'), ('\u{1380}', '\u{138f}'), ('\u{1780}', '\u{17a2}'), - ('\u{17a5}', '\u{17a7}'), ('\u{17a9}', '\u{17b3}'), ('\u{17b6}', '\u{17ca}'), ('\u{17d2}', - '\u{17d2}'), ('\u{17d7}', '\u{17d7}'), ('\u{17dc}', '\u{17dc}'), ('\u{17e0}', '\u{17e9}'), - ('\u{1c90}', '\u{1cba}'), ('\u{1cbd}', '\u{1cbf}'), ('\u{1e00}', '\u{1e99}'), ('\u{1e9e}', - '\u{1e9e}'), ('\u{1ea0}', '\u{1ef9}'), ('\u{1f00}', '\u{1f15}'), ('\u{1f18}', '\u{1f1d}'), - ('\u{1f20}', '\u{1f45}'), ('\u{1f48}', '\u{1f4d}'), ('\u{1f50}', '\u{1f57}'), ('\u{1f59}', - '\u{1f59}'), ('\u{1f5b}', '\u{1f5b}'), ('\u{1f5d}', '\u{1f5d}'), ('\u{1f5f}', '\u{1f70}'), - ('\u{1f72}', '\u{1f72}'), ('\u{1f74}', '\u{1f74}'), ('\u{1f76}', '\u{1f76}'), ('\u{1f78}', - '\u{1f78}'), ('\u{1f7a}', '\u{1f7a}'), ('\u{1f7c}', '\u{1f7c}'), ('\u{1f80}', '\u{1fb4}'), - ('\u{1fb6}', '\u{1fba}'), ('\u{1fbc}', '\u{1fbc}'), ('\u{1fc2}', '\u{1fc4}'), ('\u{1fc6}', - '\u{1fc8}'), ('\u{1fca}', '\u{1fca}'), ('\u{1fcc}', '\u{1fcc}'), ('\u{1fd0}', '\u{1fd2}'), - ('\u{1fd6}', '\u{1fda}'), ('\u{1fe0}', '\u{1fe2}'), ('\u{1fe4}', '\u{1fea}'), ('\u{1fec}', - '\u{1fec}'), ('\u{1ff2}', '\u{1ff4}'), ('\u{1ff6}', '\u{1ff8}'), ('\u{1ffa}', '\u{1ffa}'), - ('\u{1ffc}', '\u{1ffc}'), ('\u{200c}', '\u{200d}'), ('\u{2010}', '\u{2010}'), ('\u{2019}', - '\u{2019}'), ('\u{2027}', '\u{2027}'), ('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}'), - ('\u{2d80}', '\u{2d96}'), ('\u{2da0}', '\u{2da6}'), ('\u{2da8}', '\u{2dae}'), ('\u{2db0}', - '\u{2db6}'), ('\u{2db8}', '\u{2dbe}'), ('\u{2dc0}', '\u{2dc6}'), ('\u{2dc8}', '\u{2dce}'), - ('\u{2dd0}', '\u{2dd6}'), ('\u{2dd8}', '\u{2dde}'), ('\u{3005}', '\u{3007}'), ('\u{3041}', - '\u{3094}'), ('\u{3095}', '\u{3096}'), ('\u{3099}', '\u{309a}'), ('\u{309d}', '\u{309e}'), - ('\u{30a0}', '\u{30a0}'), ('\u{30a1}', '\u{30fe}'), ('\u{3105}', '\u{312c}'), ('\u{312d}', - '\u{312d}'), ('\u{312f}', '\u{312f}'), ('\u{31a0}', '\u{31b7}'), ('\u{31b8}', '\u{31ba}'), - ('\u{31bb}', '\u{31bf}'), ('\u{3400}', '\u{4db5}'), ('\u{4db6}', '\u{4dbf}'), ('\u{4e00}', - '\u{9fa5}'), ('\u{9fa6}', '\u{9fbb}'), ('\u{9fbc}', '\u{9fc3}'), ('\u{9fc4}', '\u{9fcb}'), - ('\u{9fcc}', '\u{9fcc}'), ('\u{9fcd}', '\u{9fd5}'), ('\u{9fd6}', '\u{9fea}'), ('\u{9feb}', - '\u{9fef}'), ('\u{9ff0}', '\u{9ffc}'), ('\u{a67f}', '\u{a67f}'), ('\u{a717}', '\u{a71a}'), - ('\u{a71b}', '\u{a71f}'), ('\u{a788}', '\u{a788}'), ('\u{a78d}', '\u{a78d}'), ('\u{a792}', - '\u{a793}'), ('\u{a7aa}', '\u{a7aa}'), ('\u{a7ae}', '\u{a7ae}'), ('\u{a7b8}', '\u{a7b9}'), - ('\u{a7c2}', '\u{a7c6}'), ('\u{a7c7}', '\u{a7ca}'), ('\u{a9e7}', '\u{a9fe}'), ('\u{aa60}', - '\u{aa76}'), ('\u{aa7a}', '\u{aa7b}'), ('\u{aa7c}', '\u{aa7f}'), ('\u{ab01}', '\u{ab06}'), - ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', - '\u{ab2e}'), ('\u{ab66}', '\u{ab67}'), ('\u{ac00}', '\u{d7a3}'), ('\u{fa0e}', '\u{fa0f}'), - ('\u{fa11}', '\u{fa11}'), ('\u{fa13}', '\u{fa14}'), ('\u{fa1f}', '\u{fa1f}'), ('\u{fa21}', - '\u{fa21}'), ('\u{fa23}', '\u{fa24}'), ('\u{fa27}', '\u{fa29}'), ('\u{11301}', '\u{11301}'), - ('\u{11303}', '\u{11303}'), ('\u{1133b}', '\u{1133b}'), ('\u{1133c}', '\u{1133c}'), - ('\u{16ff0}', '\u{16ff1}'), ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'), - ('\u{20000}', '\u{2a6d6}'), ('\u{2a6d7}', '\u{2a6dd}'), ('\u{2a700}', '\u{2b734}'), - ('\u{2b740}', '\u{2b81d}'), ('\u{2b820}', '\u{2cea1}'), ('\u{2ceb0}', '\u{2ebe0}'), - ('\u{30000}', '\u{3134a}') + ('\u{780}', '\u{7b0}'), ('\u{7b1}', '\u{7b1}'), ('\u{870}', '\u{887}'), ('\u{889}', + '\u{88e}'), ('\u{8a0}', '\u{8a0}'), ('\u{8a1}', '\u{8a1}'), ('\u{8a2}', '\u{8ac}'), + ('\u{8b2}', '\u{8b2}'), ('\u{8b5}', '\u{8b5}'), ('\u{8b6}', '\u{8bd}'), ('\u{8be}', + '\u{8c7}'), ('\u{8c8}', '\u{8c9}'), ('\u{901}', '\u{903}'), ('\u{904}', '\u{904}'), + ('\u{905}', '\u{939}'), ('\u{93a}', '\u{93b}'), ('\u{93c}', '\u{94d}'), ('\u{94f}', + '\u{94f}'), ('\u{950}', '\u{950}'), ('\u{956}', '\u{957}'), ('\u{960}', '\u{963}'), + ('\u{966}', '\u{96f}'), ('\u{971}', '\u{972}'), ('\u{973}', '\u{977}'), ('\u{979}', + '\u{97a}'), ('\u{97b}', '\u{97c}'), ('\u{97d}', '\u{97d}'), ('\u{97e}', '\u{97f}'), + ('\u{981}', '\u{983}'), ('\u{985}', '\u{98c}'), ('\u{98f}', '\u{990}'), ('\u{993}', + '\u{9a8}'), ('\u{9aa}', '\u{9b0}'), ('\u{9b2}', '\u{9b2}'), ('\u{9b6}', '\u{9b9}'), + ('\u{9bc}', '\u{9bc}'), ('\u{9bd}', '\u{9bd}'), ('\u{9be}', '\u{9c4}'), ('\u{9c7}', + '\u{9c8}'), ('\u{9cb}', '\u{9cd}'), ('\u{9ce}', '\u{9ce}'), ('\u{9d7}', '\u{9d7}'), + ('\u{9e0}', '\u{9e3}'), ('\u{9e6}', '\u{9f1}'), ('\u{9fe}', '\u{9fe}'), ('\u{a01}', + '\u{a01}'), ('\u{a02}', '\u{a02}'), ('\u{a03}', '\u{a03}'), ('\u{a05}', '\u{a0a}'), + ('\u{a0f}', '\u{a10}'), ('\u{a13}', '\u{a28}'), ('\u{a2a}', '\u{a30}'), ('\u{a32}', + '\u{a32}'), ('\u{a35}', '\u{a35}'), ('\u{a38}', '\u{a39}'), ('\u{a3c}', '\u{a3c}'), + ('\u{a3e}', '\u{a42}'), ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a5c}', + '\u{a5c}'), ('\u{a66}', '\u{a74}'), ('\u{a81}', '\u{a83}'), ('\u{a85}', '\u{a8b}'), + ('\u{a8c}', '\u{a8c}'), ('\u{a8d}', '\u{a8d}'), ('\u{a8f}', '\u{a91}'), ('\u{a93}', + '\u{aa8}'), ('\u{aaa}', '\u{ab0}'), ('\u{ab2}', '\u{ab3}'), ('\u{ab5}', '\u{ab9}'), + ('\u{abc}', '\u{ac5}'), ('\u{ac7}', '\u{ac9}'), ('\u{acb}', '\u{acd}'), ('\u{ad0}', + '\u{ad0}'), ('\u{ae0}', '\u{ae0}'), ('\u{ae1}', '\u{ae3}'), ('\u{ae6}', '\u{aef}'), + ('\u{afa}', '\u{aff}'), ('\u{b01}', '\u{b03}'), ('\u{b05}', '\u{b0c}'), ('\u{b0f}', + '\u{b10}'), ('\u{b13}', '\u{b28}'), ('\u{b2a}', '\u{b30}'), ('\u{b32}', '\u{b33}'), + ('\u{b35}', '\u{b35}'), ('\u{b36}', '\u{b39}'), ('\u{b3c}', '\u{b43}'), ('\u{b47}', + '\u{b48}'), ('\u{b4b}', '\u{b4d}'), ('\u{b55}', '\u{b55}'), ('\u{b56}', '\u{b57}'), + ('\u{b5f}', '\u{b61}'), ('\u{b66}', '\u{b6f}'), ('\u{b71}', '\u{b71}'), ('\u{b82}', + '\u{b83}'), ('\u{b85}', '\u{b8a}'), ('\u{b8e}', '\u{b90}'), ('\u{b92}', '\u{b95}'), + ('\u{b99}', '\u{b9a}'), ('\u{b9c}', '\u{b9c}'), ('\u{b9e}', '\u{b9f}'), ('\u{ba3}', + '\u{ba4}'), ('\u{ba8}', '\u{baa}'), ('\u{bae}', '\u{bb5}'), ('\u{bb6}', '\u{bb6}'), + ('\u{bb7}', '\u{bb9}'), ('\u{bbe}', '\u{bc2}'), ('\u{bc6}', '\u{bc8}'), ('\u{bca}', + '\u{bcd}'), ('\u{bd0}', '\u{bd0}'), ('\u{bd7}', '\u{bd7}'), ('\u{be6}', '\u{be6}'), + ('\u{be7}', '\u{bef}'), ('\u{c01}', '\u{c03}'), ('\u{c04}', '\u{c04}'), ('\u{c05}', + '\u{c0c}'), ('\u{c0e}', '\u{c10}'), ('\u{c12}', '\u{c28}'), ('\u{c2a}', '\u{c33}'), + ('\u{c35}', '\u{c39}'), ('\u{c3c}', '\u{c3c}'), ('\u{c3d}', '\u{c3d}'), ('\u{c3e}', + '\u{c44}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4d}'), ('\u{c55}', '\u{c56}'), + ('\u{c5d}', '\u{c5d}'), ('\u{c60}', '\u{c61}'), ('\u{c66}', '\u{c6f}'), ('\u{c80}', + '\u{c80}'), ('\u{c82}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), ('\u{c8e}', '\u{c90}'), + ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', '\u{cb9}'), ('\u{cbc}', + '\u{cbd}'), ('\u{cbe}', '\u{cc4}'), ('\u{cc6}', '\u{cc8}'), ('\u{cca}', '\u{ccd}'), + ('\u{cd5}', '\u{cd6}'), ('\u{cdd}', '\u{cdd}'), ('\u{ce0}', '\u{ce1}'), ('\u{ce2}', + '\u{ce3}'), ('\u{ce6}', '\u{cef}'), ('\u{cf1}', '\u{cf2}'), ('\u{cf3}', '\u{cf3}'), + ('\u{d00}', '\u{d00}'), ('\u{d02}', '\u{d03}'), ('\u{d05}', '\u{d0c}'), ('\u{d0e}', + '\u{d10}'), ('\u{d12}', '\u{d28}'), ('\u{d29}', '\u{d29}'), ('\u{d2a}', '\u{d39}'), + ('\u{d3a}', '\u{d3a}'), ('\u{d3d}', '\u{d3d}'), ('\u{d3e}', '\u{d43}'), ('\u{d46}', + '\u{d48}'), ('\u{d4a}', '\u{d4d}'), ('\u{d4e}', '\u{d4e}'), ('\u{d54}', '\u{d56}'), + ('\u{d57}', '\u{d57}'), ('\u{d60}', '\u{d61}'), ('\u{d66}', '\u{d6f}'), ('\u{d7a}', + '\u{d7f}'), ('\u{d82}', '\u{d83}'), ('\u{d85}', '\u{d8e}'), ('\u{d91}', '\u{d96}'), + ('\u{d9a}', '\u{da5}'), ('\u{da7}', '\u{db1}'), ('\u{db3}', '\u{dbb}'), ('\u{dbd}', + '\u{dbd}'), ('\u{dc0}', '\u{dc6}'), ('\u{dca}', '\u{dca}'), ('\u{dcf}', '\u{dd4}'), + ('\u{dd6}', '\u{dd6}'), ('\u{dd8}', '\u{dde}'), ('\u{df2}', '\u{df2}'), ('\u{e01}', + '\u{e32}'), ('\u{e34}', '\u{e3a}'), ('\u{e40}', '\u{e4e}'), ('\u{e50}', '\u{e59}'), + ('\u{e81}', '\u{e82}'), ('\u{e84}', '\u{e84}'), ('\u{e86}', '\u{e86}'), ('\u{e87}', + '\u{e88}'), ('\u{e89}', '\u{e89}'), ('\u{e8a}', '\u{e8a}'), ('\u{e8c}', '\u{e8c}'), + ('\u{e8d}', '\u{e8d}'), ('\u{e8e}', '\u{e93}'), ('\u{e94}', '\u{e97}'), ('\u{e98}', + '\u{e98}'), ('\u{e99}', '\u{e9f}'), ('\u{ea0}', '\u{ea0}'), ('\u{ea1}', '\u{ea3}'), + ('\u{ea5}', '\u{ea5}'), ('\u{ea7}', '\u{ea7}'), ('\u{ea8}', '\u{ea9}'), ('\u{eaa}', + '\u{eab}'), ('\u{eac}', '\u{eac}'), ('\u{ead}', '\u{eb2}'), ('\u{eb4}', '\u{eb9}'), + ('\u{eba}', '\u{eba}'), ('\u{ebb}', '\u{ebd}'), ('\u{ec0}', '\u{ec4}'), ('\u{ec6}', + '\u{ec6}'), ('\u{ec8}', '\u{ecd}'), ('\u{ece}', '\u{ece}'), ('\u{ed0}', '\u{ed9}'), + ('\u{ede}', '\u{edf}'), ('\u{f00}', '\u{f00}'), ('\u{f0b}', '\u{f0b}'), ('\u{f20}', + '\u{f29}'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'), ('\u{f3e}', '\u{f42}'), + ('\u{f44}', '\u{f47}'), ('\u{f49}', '\u{f4c}'), ('\u{f4e}', '\u{f51}'), ('\u{f53}', + '\u{f56}'), ('\u{f58}', '\u{f5b}'), ('\u{f5d}', '\u{f68}'), ('\u{f6a}', '\u{f6a}'), + ('\u{f6b}', '\u{f6c}'), ('\u{f71}', '\u{f72}'), ('\u{f74}', '\u{f74}'), ('\u{f7a}', + '\u{f80}'), ('\u{f82}', '\u{f84}'), ('\u{f86}', '\u{f8b}'), ('\u{f8c}', '\u{f8f}'), + ('\u{f90}', '\u{f92}'), ('\u{f94}', '\u{f95}'), ('\u{f96}', '\u{f96}'), ('\u{f97}', + '\u{f97}'), ('\u{f99}', '\u{f9c}'), ('\u{f9e}', '\u{fa1}'), ('\u{fa3}', '\u{fa6}'), + ('\u{fa8}', '\u{fab}'), ('\u{fad}', '\u{fad}'), ('\u{fae}', '\u{fb0}'), ('\u{fb1}', + '\u{fb7}'), ('\u{fb8}', '\u{fb8}'), ('\u{fba}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), + ('\u{1000}', '\u{1021}'), ('\u{1022}', '\u{1022}'), ('\u{1023}', '\u{1027}'), ('\u{1028}', + '\u{1028}'), ('\u{1029}', '\u{102a}'), ('\u{102b}', '\u{102b}'), ('\u{102c}', '\u{1032}'), + ('\u{1033}', '\u{1035}'), ('\u{1036}', '\u{1039}'), ('\u{103a}', '\u{103f}'), ('\u{1040}', + '\u{1049}'), ('\u{1050}', '\u{1059}'), ('\u{105a}', '\u{1099}'), ('\u{109a}', '\u{109d}'), + ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), ('\u{10d0}', '\u{10f0}'), ('\u{10f7}', + '\u{10f8}'), ('\u{10f9}', '\u{10fa}'), ('\u{10fd}', '\u{10ff}'), ('\u{1200}', '\u{1206}'), + ('\u{1207}', '\u{1207}'), ('\u{1208}', '\u{1246}'), ('\u{1247}', '\u{1247}'), ('\u{1248}', + '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', '\u{1256}'), ('\u{1258}', '\u{1258}'), + ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1286}'), ('\u{1287}', '\u{1287}'), ('\u{1288}', + '\u{1288}'), ('\u{128a}', '\u{128d}'), ('\u{1290}', '\u{12ae}'), ('\u{12af}', '\u{12af}'), + ('\u{12b0}', '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), ('\u{12b8}', '\u{12be}'), ('\u{12c0}', + '\u{12c0}'), ('\u{12c2}', '\u{12c5}'), ('\u{12c8}', '\u{12ce}'), ('\u{12cf}', '\u{12cf}'), + ('\u{12d0}', '\u{12d6}'), ('\u{12d8}', '\u{12ee}'), ('\u{12ef}', '\u{12ef}'), ('\u{12f0}', + '\u{130e}'), ('\u{130f}', '\u{130f}'), ('\u{1310}', '\u{1310}'), ('\u{1312}', '\u{1315}'), + ('\u{1318}', '\u{131e}'), ('\u{131f}', '\u{131f}'), ('\u{1320}', '\u{1346}'), ('\u{1347}', + '\u{1347}'), ('\u{1348}', '\u{135a}'), ('\u{135d}', '\u{135e}'), ('\u{135f}', '\u{135f}'), + ('\u{1380}', '\u{138f}'), ('\u{1780}', '\u{17a2}'), ('\u{17a5}', '\u{17a7}'), ('\u{17a9}', + '\u{17b3}'), ('\u{17b6}', '\u{17cd}'), ('\u{17d0}', '\u{17d0}'), ('\u{17d2}', '\u{17d2}'), + ('\u{17d7}', '\u{17d7}'), ('\u{17dc}', '\u{17dc}'), ('\u{17e0}', '\u{17e9}'), ('\u{1c90}', + '\u{1cba}'), ('\u{1cbd}', '\u{1cbf}'), ('\u{1e00}', '\u{1e99}'), ('\u{1e9e}', '\u{1e9e}'), + ('\u{1ea0}', '\u{1ef9}'), ('\u{1f00}', '\u{1f15}'), ('\u{1f18}', '\u{1f1d}'), ('\u{1f20}', + '\u{1f45}'), ('\u{1f48}', '\u{1f4d}'), ('\u{1f50}', '\u{1f57}'), ('\u{1f59}', '\u{1f59}'), + ('\u{1f5b}', '\u{1f5b}'), ('\u{1f5d}', '\u{1f5d}'), ('\u{1f5f}', '\u{1f70}'), ('\u{1f72}', + '\u{1f72}'), ('\u{1f74}', '\u{1f74}'), ('\u{1f76}', '\u{1f76}'), ('\u{1f78}', '\u{1f78}'), + ('\u{1f7a}', '\u{1f7a}'), ('\u{1f7c}', '\u{1f7c}'), ('\u{1f80}', '\u{1fb4}'), ('\u{1fb6}', + '\u{1fba}'), ('\u{1fbc}', '\u{1fbc}'), ('\u{1fc2}', '\u{1fc4}'), ('\u{1fc6}', '\u{1fc8}'), + ('\u{1fca}', '\u{1fca}'), ('\u{1fcc}', '\u{1fcc}'), ('\u{1fd0}', '\u{1fd2}'), ('\u{1fd6}', + '\u{1fda}'), ('\u{1fe0}', '\u{1fe2}'), ('\u{1fe4}', '\u{1fea}'), ('\u{1fec}', '\u{1fec}'), + ('\u{1ff2}', '\u{1ff4}'), ('\u{1ff6}', '\u{1ff8}'), ('\u{1ffa}', '\u{1ffa}'), ('\u{1ffc}', + '\u{1ffc}'), ('\u{2010}', '\u{2010}'), ('\u{2019}', '\u{2019}'), ('\u{2027}', '\u{2027}'), + ('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}'), ('\u{2d80}', '\u{2d96}'), ('\u{2da0}', + '\u{2da6}'), ('\u{2da8}', '\u{2dae}'), ('\u{2db0}', '\u{2db6}'), ('\u{2db8}', '\u{2dbe}'), + ('\u{2dc0}', '\u{2dc6}'), ('\u{2dc8}', '\u{2dce}'), ('\u{2dd0}', '\u{2dd6}'), ('\u{2dd8}', + '\u{2dde}'), ('\u{3005}', '\u{3007}'), ('\u{3041}', '\u{3094}'), ('\u{3095}', '\u{3096}'), + ('\u{3099}', '\u{309a}'), ('\u{309d}', '\u{309e}'), ('\u{30a0}', '\u{30a0}'), ('\u{30a1}', + '\u{30fe}'), ('\u{3105}', '\u{312c}'), ('\u{312d}', '\u{312d}'), ('\u{312f}', '\u{312f}'), + ('\u{31a0}', '\u{31b7}'), ('\u{31b8}', '\u{31ba}'), ('\u{31bb}', '\u{31bf}'), ('\u{3400}', + '\u{4db5}'), ('\u{4db6}', '\u{4dbf}'), ('\u{4e00}', '\u{9fa5}'), ('\u{9fa6}', '\u{9fbb}'), + ('\u{9fbc}', '\u{9fc3}'), ('\u{9fc4}', '\u{9fcb}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{9fcd}', + '\u{9fd5}'), ('\u{9fd6}', '\u{9fea}'), ('\u{9feb}', '\u{9fef}'), ('\u{9ff0}', '\u{9ffc}'), + ('\u{9ffd}', '\u{9fff}'), ('\u{a67f}', '\u{a67f}'), ('\u{a717}', '\u{a71a}'), ('\u{a71b}', + '\u{a71f}'), ('\u{a788}', '\u{a788}'), ('\u{a78d}', '\u{a78d}'), ('\u{a792}', '\u{a793}'), + ('\u{a7aa}', '\u{a7aa}'), ('\u{a7c0}', '\u{a7c1}'), ('\u{a7c2}', '\u{a7c6}'), ('\u{a7c7}', + '\u{a7ca}'), ('\u{a7d0}', '\u{a7d1}'), ('\u{a7d3}', '\u{a7d3}'), ('\u{a7d5}', '\u{a7d9}'), + ('\u{a9e7}', '\u{a9fe}'), ('\u{aa60}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7b}'), ('\u{aa7c}', + '\u{aa7f}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), + ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{ab66}', '\u{ab67}'), ('\u{ac00}', + '\u{d7a3}'), ('\u{fa0e}', '\u{fa0f}'), ('\u{fa11}', '\u{fa11}'), ('\u{fa13}', '\u{fa14}'), + ('\u{fa1f}', '\u{fa1f}'), ('\u{fa21}', '\u{fa21}'), ('\u{fa23}', '\u{fa24}'), ('\u{fa27}', + '\u{fa29}'), ('\u{11301}', '\u{11301}'), ('\u{11303}', '\u{11303}'), ('\u{1133b}', + '\u{1133b}'), ('\u{1133c}', '\u{1133c}'), ('\u{16ff0}', '\u{16ff1}'), ('\u{1b11f}', + '\u{1b122}'), ('\u{1b132}', '\u{1b132}'), ('\u{1b150}', '\u{1b152}'), ('\u{1b155}', + '\u{1b155}'), ('\u{1b164}', '\u{1b167}'), ('\u{1df00}', '\u{1df1e}'), ('\u{1df25}', + '\u{1df2a}'), ('\u{1e08f}', '\u{1e08f}'), ('\u{1e7e0}', '\u{1e7e6}'), ('\u{1e7e8}', + '\u{1e7eb}'), ('\u{1e7ed}', '\u{1e7ee}'), ('\u{1e7f0}', '\u{1e7fe}'), ('\u{20000}', + '\u{2a6d6}'), ('\u{2a6d7}', '\u{2a6dd}'), ('\u{2a6de}', '\u{2a6df}'), ('\u{2a700}', + '\u{2b734}'), ('\u{2b735}', '\u{2b738}'), ('\u{2b739}', '\u{2b739}'), ('\u{2b740}', + '\u{2b81d}'), ('\u{2b820}', '\u{2cea1}'), ('\u{2ceb0}', '\u{2ebe0}'), ('\u{30000}', + '\u{3134a}'), ('\u{31350}', '\u{323af}') ]; const IDENTIFIER_TYPE: &'static [(char, char, IdentifierType)] = &[ @@ -438,160 +446,167 @@ pub mod identifier { IdentifierType::Not_XID), ('\u{60d}', '\u{60f}', IdentifierType::Not_XID), ('\u{610}', '\u{615}', IdentifierType::Uncommon_Use), ('\u{616}', '\u{61a}', IdentifierType::Uncommon_Use), ('\u{61b}', '\u{61b}', IdentifierType::Not_XID), - ('\u{61c}', '\u{61c}', IdentifierType::Default_Ignorable), ('\u{61e}', '\u{61e}', - IdentifierType::Not_XID), ('\u{61f}', '\u{61f}', IdentifierType::Not_XID), ('\u{620}', - '\u{620}', IdentifierType::Recommended), ('\u{621}', '\u{63a}', - IdentifierType::Recommended), ('\u{63b}', '\u{63f}', IdentifierType::Recommended), - ('\u{640}', '\u{640}', IdentifierType::Obsolete), ('\u{641}', '\u{652}', - IdentifierType::Recommended), ('\u{653}', '\u{655}', IdentifierType::Recommended), - ('\u{656}', '\u{658}', IdentifierType::Uncommon_Use), ('\u{659}', '\u{65e}', - IdentifierType::Uncommon_Use), ('\u{65f}', '\u{65f}', IdentifierType::Uncommon_Use), - ('\u{660}', '\u{669}', IdentifierType::Recommended), ('\u{66a}', '\u{66d}', - IdentifierType::Not_XID), ('\u{66e}', '\u{66f}', IdentifierType::Obsolete), ('\u{670}', - '\u{672}', IdentifierType::Recommended), ('\u{673}', '\u{673}', - IdentifierType::Deprecated), ('\u{674}', '\u{674}', IdentifierType::Recommended), - ('\u{675}', '\u{678}', IdentifierType::Not_NFKC), ('\u{679}', '\u{68d}', - IdentifierType::Recommended), ('\u{68e}', '\u{68e}', IdentifierType::Obsolete), - ('\u{68f}', '\u{6a0}', IdentifierType::Recommended), ('\u{6a1}', '\u{6a1}', - IdentifierType::Obsolete), ('\u{6a2}', '\u{6b7}', IdentifierType::Recommended), - ('\u{6b8}', '\u{6b9}', IdentifierType::Recommended), ('\u{6ba}', '\u{6be}', - IdentifierType::Recommended), ('\u{6bf}', '\u{6bf}', IdentifierType::Recommended), - ('\u{6c0}', '\u{6ce}', IdentifierType::Recommended), ('\u{6cf}', '\u{6cf}', - IdentifierType::Recommended), ('\u{6d0}', '\u{6d3}', IdentifierType::Recommended), - ('\u{6d4}', '\u{6d4}', IdentifierType::Not_XID), ('\u{6d5}', '\u{6d5}', - IdentifierType::Recommended), ('\u{6d6}', '\u{6dc}', IdentifierType::Uncommon_Use), - ('\u{6dd}', '\u{6dd}', IdentifierType::Not_XID), ('\u{6de}', '\u{6de}', - IdentifierType::Not_XID), ('\u{6df}', '\u{6e4}', IdentifierType::Uncommon_Use), - ('\u{6e5}', '\u{6e6}', IdentifierType::Recommended), ('\u{6e7}', '\u{6e8}', - IdentifierType::Uncommon_Use), ('\u{6e9}', '\u{6e9}', IdentifierType::Not_XID), - ('\u{6ea}', '\u{6ed}', IdentifierType::Uncommon_Use), ('\u{6ee}', '\u{6ef}', - IdentifierType::Recommended), ('\u{6f0}', '\u{6f9}', IdentifierType::Recommended), - ('\u{6fa}', '\u{6fc}', IdentifierType::Recommended), ('\u{6fd}', '\u{6fe}', - IdentifierType::Inclusion), ('\u{6ff}', '\u{6ff}', IdentifierType::Recommended), - ('\u{700}', '\u{70d}', IdentifierType::Limited_Use), ('\u{70f}', '\u{70f}', - IdentifierType::Limited_Use), ('\u{710}', '\u{72c}', IdentifierType::Limited_Use), - ('\u{72d}', '\u{72f}', IdentifierType::Limited_Use), ('\u{730}', '\u{73f}', - IdentifierType::Limited_Use), ('\u{740}', '\u{74a}', IdentifierType::Limited_Use), - ('\u{74d}', '\u{74f}', IdentifierType::Limited_Use), ('\u{750}', '\u{76d}', - IdentifierType::Recommended), ('\u{76e}', '\u{77f}', IdentifierType::Recommended), - ('\u{780}', '\u{7b0}', IdentifierType::Recommended), ('\u{7b1}', '\u{7b1}', - IdentifierType::Recommended), ('\u{7c0}', '\u{7e7}', IdentifierType::Limited_Use), - ('\u{7e8}', '\u{7ea}', IdentifierType::Limited_Use), ('\u{7eb}', '\u{7f5}', - IdentifierType::Limited_Use), ('\u{7f6}', '\u{7f9}', IdentifierType::Limited_Use), - ('\u{7fa}', '\u{7fa}', IdentifierType::Limited_Use), ('\u{7fd}', '\u{7fd}', - IdentifierType::Limited_Use), ('\u{7fe}', '\u{7ff}', IdentifierType::Limited_Use), - ('\u{800}', '\u{82d}', IdentifierType::Exclusion), ('\u{830}', '\u{83e}', - IdentifierType::Exclusion), ('\u{840}', '\u{85b}', IdentifierType::Limited_Use), - ('\u{85e}', '\u{85e}', IdentifierType::Limited_Use), ('\u{860}', '\u{86a}', - IdentifierType::Limited_Use), ('\u{8a0}', '\u{8a0}', IdentifierType::Recommended), - ('\u{8a1}', '\u{8a1}', IdentifierType::Recommended), ('\u{8a2}', '\u{8ac}', - IdentifierType::Recommended), ('\u{8ad}', '\u{8b1}', IdentifierType::Obsolete), - ('\u{8b2}', '\u{8b2}', IdentifierType::Recommended), ('\u{8b3}', '\u{8b4}', - IdentifierType::Uncommon_Use), ('\u{8b6}', '\u{8bd}', IdentifierType::Recommended), - ('\u{8be}', '\u{8c7}', IdentifierType::Recommended), ('\u{8d3}', '\u{8d3}', - IdentifierType::Uncommon_Use), ('\u{8d4}', '\u{8e1}', IdentifierType::Uncommon_Use), - ('\u{8e2}', '\u{8e2}', IdentifierType::Not_XID), ('\u{8e3}', '\u{8e3}', - IdentifierType::Uncommon_Use), ('\u{8e4}', '\u{8fe}', IdentifierType::Uncommon_Use), - ('\u{8ff}', '\u{8ff}', IdentifierType::Uncommon_Use), ('\u{900}', '\u{900}', - IdentifierType::Uncommon_Use), ('\u{901}', '\u{903}', IdentifierType::Recommended), - ('\u{904}', '\u{904}', IdentifierType::Recommended), ('\u{905}', '\u{939}', - IdentifierType::Recommended), ('\u{93a}', '\u{93b}', IdentifierType::Recommended), - ('\u{93c}', '\u{94d}', IdentifierType::Recommended), ('\u{94e}', '\u{94e}', - IdentifierType::Obsolete), ('\u{94f}', '\u{94f}', IdentifierType::Recommended), - ('\u{950}', '\u{950}', IdentifierType::Recommended), ('\u{951}', '\u{952}', - IdentifierType::Obsolete), ('\u{953}', '\u{954}', IdentifierType::Technical), ('\u{955}', - '\u{955}', IdentifierType::Uncommon_Use), ('\u{956}', '\u{957}', - IdentifierType::Recommended), ('\u{958}', '\u{95f}', IdentifierType::Not_NFKC), - ('\u{960}', '\u{963}', IdentifierType::Recommended), ('\u{964}', '\u{965}', - IdentifierType::Not_XID), ('\u{966}', '\u{96f}', IdentifierType::Recommended), ('\u{970}', - '\u{970}', IdentifierType::Not_XID), ('\u{971}', '\u{972}', IdentifierType::Recommended), - ('\u{973}', '\u{977}', IdentifierType::Recommended), ('\u{978}', '\u{978}', - IdentifierType::Obsolete), ('\u{979}', '\u{97a}', IdentifierType::Recommended), - ('\u{97b}', '\u{97c}', IdentifierType::Recommended), ('\u{97d}', '\u{97d}', - IdentifierType::Recommended), ('\u{97e}', '\u{97f}', IdentifierType::Recommended), - ('\u{980}', '\u{980}', IdentifierType::Obsolete), ('\u{981}', '\u{983}', - IdentifierType::Recommended), ('\u{985}', '\u{98c}', IdentifierType::Recommended), - ('\u{98f}', '\u{990}', IdentifierType::Recommended), ('\u{993}', '\u{9a8}', - IdentifierType::Recommended), ('\u{9aa}', '\u{9b0}', IdentifierType::Recommended), - ('\u{9b2}', '\u{9b2}', IdentifierType::Recommended), ('\u{9b6}', '\u{9b9}', - IdentifierType::Recommended), ('\u{9bc}', '\u{9bc}', IdentifierType::Recommended), - ('\u{9bd}', '\u{9bd}', IdentifierType::Recommended), ('\u{9be}', '\u{9c4}', - IdentifierType::Recommended), ('\u{9c7}', '\u{9c8}', IdentifierType::Recommended), - ('\u{9cb}', '\u{9cd}', IdentifierType::Recommended), ('\u{9ce}', '\u{9ce}', - IdentifierType::Recommended), ('\u{9d7}', '\u{9d7}', IdentifierType::Recommended), - ('\u{9dc}', '\u{9dd}', IdentifierType::Not_NFKC), ('\u{9df}', '\u{9df}', - IdentifierType::Not_NFKC), ('\u{9e0}', '\u{9e3}', IdentifierType::Recommended), - ('\u{9e6}', '\u{9f1}', IdentifierType::Recommended), ('\u{9f2}', '\u{9fa}', - IdentifierType::Not_XID), ('\u{9fb}', '\u{9fb}', IdentifierType::Not_XID), ('\u{9fc}', - '\u{9fc}', IdentifierType::Obsolete), ('\u{9fd}', '\u{9fd}', IdentifierType::Not_XID), - ('\u{9fe}', '\u{9fe}', IdentifierType::Recommended), ('\u{a01}', '\u{a01}', - IdentifierType::Recommended), ('\u{a02}', '\u{a02}', IdentifierType::Recommended), - ('\u{a03}', '\u{a03}', IdentifierType::Recommended), ('\u{a05}', '\u{a0a}', - IdentifierType::Recommended), ('\u{a0f}', '\u{a10}', IdentifierType::Recommended), - ('\u{a13}', '\u{a28}', IdentifierType::Recommended), ('\u{a2a}', '\u{a30}', - IdentifierType::Recommended), ('\u{a32}', '\u{a32}', IdentifierType::Recommended), - ('\u{a33}', '\u{a33}', IdentifierType::Not_NFKC), ('\u{a35}', '\u{a35}', - IdentifierType::Recommended), ('\u{a36}', '\u{a36}', IdentifierType::Not_NFKC), - ('\u{a38}', '\u{a39}', IdentifierType::Recommended), ('\u{a3c}', '\u{a3c}', - IdentifierType::Recommended), ('\u{a3e}', '\u{a42}', IdentifierType::Recommended), - ('\u{a47}', '\u{a48}', IdentifierType::Recommended), ('\u{a4b}', '\u{a4d}', - IdentifierType::Recommended), ('\u{a51}', '\u{a51}', IdentifierType::Uncommon_Use), - ('\u{a59}', '\u{a5b}', IdentifierType::Not_NFKC), ('\u{a5c}', '\u{a5c}', - IdentifierType::Recommended), ('\u{a5e}', '\u{a5e}', IdentifierType::Not_NFKC), - ('\u{a66}', '\u{a74}', IdentifierType::Recommended), ('\u{a75}', '\u{a75}', - IdentifierType::Uncommon_Use), ('\u{a76}', '\u{a76}', IdentifierType::Not_XID), - ('\u{a81}', '\u{a83}', IdentifierType::Recommended), ('\u{a85}', '\u{a8b}', - IdentifierType::Recommended), ('\u{a8c}', '\u{a8c}', IdentifierType::Recommended), - ('\u{a8d}', '\u{a8d}', IdentifierType::Recommended), ('\u{a8f}', '\u{a91}', - IdentifierType::Recommended), ('\u{a93}', '\u{aa8}', IdentifierType::Recommended), - ('\u{aaa}', '\u{ab0}', IdentifierType::Recommended), ('\u{ab2}', '\u{ab3}', - IdentifierType::Recommended), ('\u{ab5}', '\u{ab9}', IdentifierType::Recommended), - ('\u{abc}', '\u{ac5}', IdentifierType::Recommended), ('\u{ac7}', '\u{ac9}', - IdentifierType::Recommended), ('\u{acb}', '\u{acd}', IdentifierType::Recommended), - ('\u{ad0}', '\u{ad0}', IdentifierType::Recommended), ('\u{ae0}', '\u{ae0}', - IdentifierType::Recommended), ('\u{ae1}', '\u{ae3}', IdentifierType::Recommended), - ('\u{ae6}', '\u{aef}', IdentifierType::Recommended), ('\u{af0}', '\u{af0}', - IdentifierType::Not_XID), ('\u{af1}', '\u{af1}', IdentifierType::Not_XID), ('\u{af9}', - '\u{af9}', IdentifierType::Uncommon_Use), ('\u{afa}', '\u{aff}', - IdentifierType::Recommended), ('\u{b01}', '\u{b03}', IdentifierType::Recommended), - ('\u{b05}', '\u{b0c}', IdentifierType::Recommended), ('\u{b0f}', '\u{b10}', - IdentifierType::Recommended), ('\u{b13}', '\u{b28}', IdentifierType::Recommended), - ('\u{b2a}', '\u{b30}', IdentifierType::Recommended), ('\u{b32}', '\u{b33}', - IdentifierType::Recommended), ('\u{b35}', '\u{b35}', IdentifierType::Recommended), - ('\u{b36}', '\u{b39}', IdentifierType::Recommended), ('\u{b3c}', '\u{b43}', - IdentifierType::Recommended), ('\u{b44}', '\u{b44}', IdentifierType::Uncommon_Use), - ('\u{b47}', '\u{b48}', IdentifierType::Recommended), ('\u{b4b}', '\u{b4d}', - IdentifierType::Recommended), ('\u{b55}', '\u{b55}', IdentifierType::Recommended), - ('\u{b56}', '\u{b57}', IdentifierType::Recommended), ('\u{b5c}', '\u{b5d}', - IdentifierType::Not_NFKC), ('\u{b5f}', '\u{b61}', IdentifierType::Recommended), - ('\u{b62}', '\u{b63}', IdentifierType::Uncommon_Use), ('\u{b66}', '\u{b6f}', - IdentifierType::Recommended), ('\u{b70}', '\u{b70}', IdentifierType::Not_XID), ('\u{b71}', - '\u{b71}', IdentifierType::Recommended), ('\u{b72}', '\u{b77}', IdentifierType::Not_XID), - ('\u{b82}', '\u{b83}', IdentifierType::Recommended), ('\u{b85}', '\u{b8a}', - IdentifierType::Recommended), ('\u{b8e}', '\u{b90}', IdentifierType::Recommended), - ('\u{b92}', '\u{b95}', IdentifierType::Recommended), ('\u{b99}', '\u{b9a}', - IdentifierType::Recommended), ('\u{b9c}', '\u{b9c}', IdentifierType::Recommended), - ('\u{b9e}', '\u{b9f}', IdentifierType::Recommended), ('\u{ba3}', '\u{ba4}', - IdentifierType::Recommended), ('\u{ba8}', '\u{baa}', IdentifierType::Recommended), - ('\u{bae}', '\u{bb5}', IdentifierType::Recommended), ('\u{bb6}', '\u{bb6}', - IdentifierType::Recommended), ('\u{bb7}', '\u{bb9}', IdentifierType::Recommended), - ('\u{bbe}', '\u{bc2}', IdentifierType::Recommended), ('\u{bc6}', '\u{bc8}', - IdentifierType::Recommended), ('\u{bca}', '\u{bcd}', IdentifierType::Recommended), - ('\u{bd0}', '\u{bd0}', IdentifierType::Recommended), ('\u{bd7}', '\u{bd7}', - IdentifierType::Recommended), ('\u{be6}', '\u{be6}', IdentifierType::Recommended), - ('\u{be7}', '\u{bef}', IdentifierType::Recommended), ('\u{bf0}', '\u{bf2}', - IdentifierType::Not_XID), ('\u{bf3}', '\u{bfa}', IdentifierType::Not_XID), ('\u{c00}', - '\u{c00}', IdentifierType::Obsolete), ('\u{c01}', '\u{c03}', IdentifierType::Recommended), - ('\u{c04}', '\u{c04}', IdentifierType::Recommended), ('\u{c05}', '\u{c0c}', - IdentifierType::Recommended), ('\u{c0e}', '\u{c10}', IdentifierType::Recommended), - ('\u{c12}', '\u{c28}', IdentifierType::Recommended), ('\u{c2a}', '\u{c33}', - IdentifierType::Recommended), ('\u{c34}', '\u{c34}', IdentifierType::Obsolete), - ('\u{c35}', '\u{c39}', IdentifierType::Recommended), ('\u{c3d}', '\u{c3d}', - IdentifierType::Recommended), ('\u{c3e}', '\u{c44}', IdentifierType::Recommended), - ('\u{c46}', '\u{c48}', IdentifierType::Recommended), ('\u{c4a}', '\u{c4d}', - IdentifierType::Recommended), ('\u{c55}', '\u{c56}', IdentifierType::Recommended), - ('\u{c58}', '\u{c59}', IdentifierType::Obsolete), ('\u{c5a}', '\u{c5a}', - IdentifierType::Uncommon_Use), ('\u{c60}', '\u{c61}', IdentifierType::Recommended), + ('\u{61c}', '\u{61c}', IdentifierType::Default_Ignorable), ('\u{61d}', '\u{61d}', + IdentifierType::Not_XID), ('\u{61e}', '\u{61e}', IdentifierType::Not_XID), ('\u{61f}', + '\u{61f}', IdentifierType::Not_XID), ('\u{620}', '\u{620}', IdentifierType::Recommended), + ('\u{621}', '\u{63a}', IdentifierType::Recommended), ('\u{63b}', '\u{63f}', + IdentifierType::Recommended), ('\u{640}', '\u{640}', IdentifierType::Obsolete), + ('\u{641}', '\u{652}', IdentifierType::Recommended), ('\u{653}', '\u{655}', + IdentifierType::Recommended), ('\u{656}', '\u{658}', IdentifierType::Uncommon_Use), + ('\u{659}', '\u{65e}', IdentifierType::Uncommon_Use), ('\u{65f}', '\u{65f}', + IdentifierType::Uncommon_Use), ('\u{660}', '\u{669}', IdentifierType::Recommended), + ('\u{66a}', '\u{66d}', IdentifierType::Not_XID), ('\u{66e}', '\u{66f}', + IdentifierType::Obsolete), ('\u{670}', '\u{672}', IdentifierType::Recommended), + ('\u{673}', '\u{673}', IdentifierType::Deprecated), ('\u{674}', '\u{674}', + IdentifierType::Recommended), ('\u{675}', '\u{678}', IdentifierType::Not_NFKC), + ('\u{679}', '\u{68d}', IdentifierType::Recommended), ('\u{68e}', '\u{68e}', + IdentifierType::Obsolete), ('\u{68f}', '\u{6a0}', IdentifierType::Recommended), + ('\u{6a1}', '\u{6a1}', IdentifierType::Obsolete), ('\u{6a2}', '\u{6b7}', + IdentifierType::Recommended), ('\u{6b8}', '\u{6b9}', IdentifierType::Recommended), + ('\u{6ba}', '\u{6be}', IdentifierType::Recommended), ('\u{6bf}', '\u{6bf}', + IdentifierType::Recommended), ('\u{6c0}', '\u{6ce}', IdentifierType::Recommended), + ('\u{6cf}', '\u{6cf}', IdentifierType::Recommended), ('\u{6d0}', '\u{6d3}', + IdentifierType::Recommended), ('\u{6d4}', '\u{6d4}', IdentifierType::Not_XID), ('\u{6d5}', + '\u{6d5}', IdentifierType::Recommended), ('\u{6d6}', '\u{6dc}', + IdentifierType::Uncommon_Use), ('\u{6dd}', '\u{6dd}', IdentifierType::Not_XID), + ('\u{6de}', '\u{6de}', IdentifierType::Not_XID), ('\u{6df}', '\u{6e4}', + IdentifierType::Uncommon_Use), ('\u{6e5}', '\u{6e6}', IdentifierType::Recommended), + ('\u{6e7}', '\u{6e8}', IdentifierType::Uncommon_Use), ('\u{6e9}', '\u{6e9}', + IdentifierType::Not_XID), ('\u{6ea}', '\u{6ed}', IdentifierType::Uncommon_Use), + ('\u{6ee}', '\u{6ef}', IdentifierType::Recommended), ('\u{6f0}', '\u{6f9}', + IdentifierType::Recommended), ('\u{6fa}', '\u{6fc}', IdentifierType::Recommended), + ('\u{6fd}', '\u{6fe}', IdentifierType::Inclusion), ('\u{6ff}', '\u{6ff}', + IdentifierType::Recommended), ('\u{700}', '\u{70d}', IdentifierType::Limited_Use), + ('\u{70f}', '\u{70f}', IdentifierType::Limited_Use), ('\u{710}', '\u{72c}', + IdentifierType::Limited_Use), ('\u{72d}', '\u{72f}', IdentifierType::Limited_Use), + ('\u{730}', '\u{73f}', IdentifierType::Limited_Use), ('\u{740}', '\u{74a}', + IdentifierType::Limited_Use), ('\u{74d}', '\u{74f}', IdentifierType::Limited_Use), + ('\u{750}', '\u{76d}', IdentifierType::Recommended), ('\u{76e}', '\u{77f}', + IdentifierType::Recommended), ('\u{780}', '\u{7b0}', IdentifierType::Recommended), + ('\u{7b1}', '\u{7b1}', IdentifierType::Recommended), ('\u{7c0}', '\u{7e7}', + IdentifierType::Limited_Use), ('\u{7e8}', '\u{7ea}', IdentifierType::Limited_Use), + ('\u{7eb}', '\u{7f5}', IdentifierType::Limited_Use), ('\u{7f6}', '\u{7f9}', + IdentifierType::Limited_Use), ('\u{7fa}', '\u{7fa}', IdentifierType::Limited_Use), + ('\u{7fd}', '\u{7fd}', IdentifierType::Limited_Use), ('\u{7fe}', '\u{7ff}', + IdentifierType::Limited_Use), ('\u{800}', '\u{82d}', IdentifierType::Exclusion), + ('\u{830}', '\u{83e}', IdentifierType::Exclusion), ('\u{840}', '\u{85b}', + IdentifierType::Limited_Use), ('\u{85e}', '\u{85e}', IdentifierType::Limited_Use), + ('\u{860}', '\u{86a}', IdentifierType::Limited_Use), ('\u{870}', '\u{887}', + IdentifierType::Recommended), ('\u{888}', '\u{888}', IdentifierType::Not_XID), ('\u{889}', + '\u{88e}', IdentifierType::Recommended), ('\u{890}', '\u{891}', IdentifierType::Not_XID), + ('\u{898}', '\u{89f}', IdentifierType::Uncommon_Use), ('\u{8a0}', '\u{8a0}', + IdentifierType::Recommended), ('\u{8a1}', '\u{8a1}', IdentifierType::Recommended), + ('\u{8a2}', '\u{8ac}', IdentifierType::Recommended), ('\u{8ad}', '\u{8b1}', + IdentifierType::Obsolete), ('\u{8b2}', '\u{8b2}', IdentifierType::Recommended), + ('\u{8b3}', '\u{8b4}', IdentifierType::Uncommon_Use), ('\u{8b5}', '\u{8b5}', + IdentifierType::Recommended), ('\u{8b6}', '\u{8bd}', IdentifierType::Recommended), + ('\u{8be}', '\u{8c7}', IdentifierType::Recommended), ('\u{8c8}', '\u{8c9}', + IdentifierType::Recommended), ('\u{8ca}', '\u{8d2}', IdentifierType::Uncommon_Use), + ('\u{8d3}', '\u{8d3}', IdentifierType::Uncommon_Use), ('\u{8d4}', '\u{8e1}', + IdentifierType::Uncommon_Use), ('\u{8e2}', '\u{8e2}', IdentifierType::Not_XID), + ('\u{8e3}', '\u{8e3}', IdentifierType::Uncommon_Use), ('\u{8e4}', '\u{8fe}', + IdentifierType::Uncommon_Use), ('\u{8ff}', '\u{8ff}', IdentifierType::Uncommon_Use), + ('\u{900}', '\u{900}', IdentifierType::Uncommon_Use), ('\u{901}', '\u{903}', + IdentifierType::Recommended), ('\u{904}', '\u{904}', IdentifierType::Recommended), + ('\u{905}', '\u{939}', IdentifierType::Recommended), ('\u{93a}', '\u{93b}', + IdentifierType::Recommended), ('\u{93c}', '\u{94d}', IdentifierType::Recommended), + ('\u{94e}', '\u{94e}', IdentifierType::Obsolete), ('\u{94f}', '\u{94f}', + IdentifierType::Recommended), ('\u{950}', '\u{950}', IdentifierType::Recommended), + ('\u{951}', '\u{952}', IdentifierType::Obsolete), ('\u{953}', '\u{954}', + IdentifierType::Technical), ('\u{955}', '\u{955}', IdentifierType::Uncommon_Use), + ('\u{956}', '\u{957}', IdentifierType::Recommended), ('\u{958}', '\u{95f}', + IdentifierType::Not_NFKC), ('\u{960}', '\u{963}', IdentifierType::Recommended), + ('\u{964}', '\u{965}', IdentifierType::Not_XID), ('\u{966}', '\u{96f}', + IdentifierType::Recommended), ('\u{970}', '\u{970}', IdentifierType::Not_XID), ('\u{971}', + '\u{972}', IdentifierType::Recommended), ('\u{973}', '\u{977}', + IdentifierType::Recommended), ('\u{978}', '\u{978}', IdentifierType::Obsolete), + ('\u{979}', '\u{97a}', IdentifierType::Recommended), ('\u{97b}', '\u{97c}', + IdentifierType::Recommended), ('\u{97d}', '\u{97d}', IdentifierType::Recommended), + ('\u{97e}', '\u{97f}', IdentifierType::Recommended), ('\u{980}', '\u{980}', + IdentifierType::Obsolete), ('\u{981}', '\u{983}', IdentifierType::Recommended), + ('\u{985}', '\u{98c}', IdentifierType::Recommended), ('\u{98f}', '\u{990}', + IdentifierType::Recommended), ('\u{993}', '\u{9a8}', IdentifierType::Recommended), + ('\u{9aa}', '\u{9b0}', IdentifierType::Recommended), ('\u{9b2}', '\u{9b2}', + IdentifierType::Recommended), ('\u{9b6}', '\u{9b9}', IdentifierType::Recommended), + ('\u{9bc}', '\u{9bc}', IdentifierType::Recommended), ('\u{9bd}', '\u{9bd}', + IdentifierType::Recommended), ('\u{9be}', '\u{9c4}', IdentifierType::Recommended), + ('\u{9c7}', '\u{9c8}', IdentifierType::Recommended), ('\u{9cb}', '\u{9cd}', + IdentifierType::Recommended), ('\u{9ce}', '\u{9ce}', IdentifierType::Recommended), + ('\u{9d7}', '\u{9d7}', IdentifierType::Recommended), ('\u{9dc}', '\u{9dd}', + IdentifierType::Not_NFKC), ('\u{9df}', '\u{9df}', IdentifierType::Not_NFKC), ('\u{9e0}', + '\u{9e3}', IdentifierType::Recommended), ('\u{9e6}', '\u{9f1}', + IdentifierType::Recommended), ('\u{9f2}', '\u{9fa}', IdentifierType::Not_XID), ('\u{9fb}', + '\u{9fb}', IdentifierType::Not_XID), ('\u{9fc}', '\u{9fc}', IdentifierType::Obsolete), + ('\u{9fd}', '\u{9fd}', IdentifierType::Not_XID), ('\u{9fe}', '\u{9fe}', + IdentifierType::Recommended), ('\u{a01}', '\u{a01}', IdentifierType::Recommended), + ('\u{a02}', '\u{a02}', IdentifierType::Recommended), ('\u{a03}', '\u{a03}', + IdentifierType::Recommended), ('\u{a05}', '\u{a0a}', IdentifierType::Recommended), + ('\u{a0f}', '\u{a10}', IdentifierType::Recommended), ('\u{a13}', '\u{a28}', + IdentifierType::Recommended), ('\u{a2a}', '\u{a30}', IdentifierType::Recommended), + ('\u{a32}', '\u{a32}', IdentifierType::Recommended), ('\u{a33}', '\u{a33}', + IdentifierType::Not_NFKC), ('\u{a35}', '\u{a35}', IdentifierType::Recommended), + ('\u{a36}', '\u{a36}', IdentifierType::Not_NFKC), ('\u{a38}', '\u{a39}', + IdentifierType::Recommended), ('\u{a3c}', '\u{a3c}', IdentifierType::Recommended), + ('\u{a3e}', '\u{a42}', IdentifierType::Recommended), ('\u{a47}', '\u{a48}', + IdentifierType::Recommended), ('\u{a4b}', '\u{a4d}', IdentifierType::Recommended), + ('\u{a51}', '\u{a51}', IdentifierType::Uncommon_Use), ('\u{a59}', '\u{a5b}', + IdentifierType::Not_NFKC), ('\u{a5c}', '\u{a5c}', IdentifierType::Recommended), + ('\u{a5e}', '\u{a5e}', IdentifierType::Not_NFKC), ('\u{a66}', '\u{a74}', + IdentifierType::Recommended), ('\u{a75}', '\u{a75}', IdentifierType::Uncommon_Use), + ('\u{a76}', '\u{a76}', IdentifierType::Not_XID), ('\u{a81}', '\u{a83}', + IdentifierType::Recommended), ('\u{a85}', '\u{a8b}', IdentifierType::Recommended), + ('\u{a8c}', '\u{a8c}', IdentifierType::Recommended), ('\u{a8d}', '\u{a8d}', + IdentifierType::Recommended), ('\u{a8f}', '\u{a91}', IdentifierType::Recommended), + ('\u{a93}', '\u{aa8}', IdentifierType::Recommended), ('\u{aaa}', '\u{ab0}', + IdentifierType::Recommended), ('\u{ab2}', '\u{ab3}', IdentifierType::Recommended), + ('\u{ab5}', '\u{ab9}', IdentifierType::Recommended), ('\u{abc}', '\u{ac5}', + IdentifierType::Recommended), ('\u{ac7}', '\u{ac9}', IdentifierType::Recommended), + ('\u{acb}', '\u{acd}', IdentifierType::Recommended), ('\u{ad0}', '\u{ad0}', + IdentifierType::Recommended), ('\u{ae0}', '\u{ae0}', IdentifierType::Recommended), + ('\u{ae1}', '\u{ae3}', IdentifierType::Recommended), ('\u{ae6}', '\u{aef}', + IdentifierType::Recommended), ('\u{af0}', '\u{af0}', IdentifierType::Not_XID), ('\u{af1}', + '\u{af1}', IdentifierType::Not_XID), ('\u{af9}', '\u{af9}', IdentifierType::Uncommon_Use), + ('\u{afa}', '\u{aff}', IdentifierType::Recommended), ('\u{b01}', '\u{b03}', + IdentifierType::Recommended), ('\u{b05}', '\u{b0c}', IdentifierType::Recommended), + ('\u{b0f}', '\u{b10}', IdentifierType::Recommended), ('\u{b13}', '\u{b28}', + IdentifierType::Recommended), ('\u{b2a}', '\u{b30}', IdentifierType::Recommended), + ('\u{b32}', '\u{b33}', IdentifierType::Recommended), ('\u{b35}', '\u{b35}', + IdentifierType::Recommended), ('\u{b36}', '\u{b39}', IdentifierType::Recommended), + ('\u{b3c}', '\u{b43}', IdentifierType::Recommended), ('\u{b44}', '\u{b44}', + IdentifierType::Uncommon_Use), ('\u{b47}', '\u{b48}', IdentifierType::Recommended), + ('\u{b4b}', '\u{b4d}', IdentifierType::Recommended), ('\u{b55}', '\u{b55}', + IdentifierType::Recommended), ('\u{b56}', '\u{b57}', IdentifierType::Recommended), + ('\u{b5c}', '\u{b5d}', IdentifierType::Not_NFKC), ('\u{b5f}', '\u{b61}', + IdentifierType::Recommended), ('\u{b62}', '\u{b63}', IdentifierType::Uncommon_Use), + ('\u{b66}', '\u{b6f}', IdentifierType::Recommended), ('\u{b70}', '\u{b70}', + IdentifierType::Not_XID), ('\u{b71}', '\u{b71}', IdentifierType::Recommended), ('\u{b72}', + '\u{b77}', IdentifierType::Not_XID), ('\u{b82}', '\u{b83}', IdentifierType::Recommended), + ('\u{b85}', '\u{b8a}', IdentifierType::Recommended), ('\u{b8e}', '\u{b90}', + IdentifierType::Recommended), ('\u{b92}', '\u{b95}', IdentifierType::Recommended), + ('\u{b99}', '\u{b9a}', IdentifierType::Recommended), ('\u{b9c}', '\u{b9c}', + IdentifierType::Recommended), ('\u{b9e}', '\u{b9f}', IdentifierType::Recommended), + ('\u{ba3}', '\u{ba4}', IdentifierType::Recommended), ('\u{ba8}', '\u{baa}', + IdentifierType::Recommended), ('\u{bae}', '\u{bb5}', IdentifierType::Recommended), + ('\u{bb6}', '\u{bb6}', IdentifierType::Recommended), ('\u{bb7}', '\u{bb9}', + IdentifierType::Recommended), ('\u{bbe}', '\u{bc2}', IdentifierType::Recommended), + ('\u{bc6}', '\u{bc8}', IdentifierType::Recommended), ('\u{bca}', '\u{bcd}', + IdentifierType::Recommended), ('\u{bd0}', '\u{bd0}', IdentifierType::Recommended), + ('\u{bd7}', '\u{bd7}', IdentifierType::Recommended), ('\u{be6}', '\u{be6}', + IdentifierType::Recommended), ('\u{be7}', '\u{bef}', IdentifierType::Recommended), + ('\u{bf0}', '\u{bf2}', IdentifierType::Not_XID), ('\u{bf3}', '\u{bfa}', + IdentifierType::Not_XID), ('\u{c00}', '\u{c00}', IdentifierType::Obsolete), ('\u{c01}', + '\u{c03}', IdentifierType::Recommended), ('\u{c04}', '\u{c04}', + IdentifierType::Recommended), ('\u{c05}', '\u{c0c}', IdentifierType::Recommended), + ('\u{c0e}', '\u{c10}', IdentifierType::Recommended), ('\u{c12}', '\u{c28}', + IdentifierType::Recommended), ('\u{c2a}', '\u{c33}', IdentifierType::Recommended), + ('\u{c34}', '\u{c34}', IdentifierType::Obsolete), ('\u{c35}', '\u{c39}', + IdentifierType::Recommended), ('\u{c3c}', '\u{c3c}', IdentifierType::Recommended), + ('\u{c3d}', '\u{c3d}', IdentifierType::Recommended), ('\u{c3e}', '\u{c44}', + IdentifierType::Recommended), ('\u{c46}', '\u{c48}', IdentifierType::Recommended), + ('\u{c4a}', '\u{c4d}', IdentifierType::Recommended), ('\u{c55}', '\u{c56}', + IdentifierType::Recommended), ('\u{c58}', '\u{c59}', IdentifierType::Obsolete), + ('\u{c5a}', '\u{c5a}', IdentifierType::Uncommon_Use), ('\u{c5d}', '\u{c5d}', + IdentifierType::Recommended), ('\u{c60}', '\u{c61}', IdentifierType::Recommended), ('\u{c62}', '\u{c63}', IdentifierType::Uncommon_Use), ('\u{c66}', '\u{c6f}', IdentifierType::Recommended), ('\u{c77}', '\u{c77}', IdentifierType::Not_XID), ('\u{c78}', '\u{c7f}', IdentifierType::Not_XID), ('\u{c80}', '\u{c80}', IdentifierType::Recommended), @@ -603,44 +618,45 @@ pub mod identifier { IdentifierType::Recommended), ('\u{cbc}', '\u{cbd}', IdentifierType::Recommended), ('\u{cbe}', '\u{cc4}', IdentifierType::Recommended), ('\u{cc6}', '\u{cc8}', IdentifierType::Recommended), ('\u{cca}', '\u{ccd}', IdentifierType::Recommended), - ('\u{cd5}', '\u{cd6}', IdentifierType::Recommended), ('\u{cde}', '\u{cde}', - IdentifierType::Obsolete), ('\u{ce0}', '\u{ce1}', IdentifierType::Recommended), - ('\u{ce2}', '\u{ce3}', IdentifierType::Recommended), ('\u{ce6}', '\u{cef}', - IdentifierType::Recommended), ('\u{cf1}', '\u{cf2}', IdentifierType::Recommended), - ('\u{d00}', '\u{d00}', IdentifierType::Recommended), ('\u{d01}', '\u{d01}', - IdentifierType::Obsolete), ('\u{d02}', '\u{d03}', IdentifierType::Recommended), - ('\u{d04}', '\u{d04}', IdentifierType::Technical), ('\u{d05}', '\u{d0c}', - IdentifierType::Recommended), ('\u{d0e}', '\u{d10}', IdentifierType::Recommended), - ('\u{d12}', '\u{d28}', IdentifierType::Recommended), ('\u{d29}', '\u{d29}', - IdentifierType::Recommended), ('\u{d2a}', '\u{d39}', IdentifierType::Recommended), - ('\u{d3a}', '\u{d3a}', IdentifierType::Recommended), ('\u{d3b}', '\u{d3c}', - IdentifierType::Obsolete), ('\u{d3d}', '\u{d3d}', IdentifierType::Recommended), - ('\u{d3e}', '\u{d43}', IdentifierType::Recommended), ('\u{d44}', '\u{d44}', - IdentifierType::Uncommon_Use), ('\u{d46}', '\u{d48}', IdentifierType::Recommended), - ('\u{d4a}', '\u{d4d}', IdentifierType::Recommended), ('\u{d4e}', '\u{d4e}', - IdentifierType::Recommended), ('\u{d4f}', '\u{d4f}', IdentifierType::Not_XID), ('\u{d54}', - '\u{d56}', IdentifierType::Recommended), ('\u{d57}', '\u{d57}', - IdentifierType::Recommended), ('\u{d58}', '\u{d5e}', IdentifierType::Not_XID), ('\u{d5f}', - '\u{d5f}', IdentifierType::Obsolete), ('\u{d60}', '\u{d61}', IdentifierType::Recommended), - ('\u{d62}', '\u{d63}', IdentifierType::Uncommon_Use), ('\u{d66}', '\u{d6f}', - IdentifierType::Recommended), ('\u{d70}', '\u{d75}', IdentifierType::Not_XID), ('\u{d76}', - '\u{d78}', IdentifierType::Not_XID), ('\u{d79}', '\u{d79}', IdentifierType::Not_XID), - ('\u{d7a}', '\u{d7f}', IdentifierType::Recommended), ('\u{d81}', '\u{d81}', - IdentifierType::Technical), ('\u{d82}', '\u{d83}', IdentifierType::Recommended), - ('\u{d85}', '\u{d8e}', IdentifierType::Recommended), ('\u{d8f}', '\u{d90}', - IdentifierType::Uncommon_Use), ('\u{d91}', '\u{d96}', IdentifierType::Recommended), - ('\u{d9a}', '\u{da5}', IdentifierType::Recommended), ('\u{da6}', '\u{da6}', - IdentifierType::Uncommon_Use), ('\u{da7}', '\u{db1}', IdentifierType::Recommended), - ('\u{db3}', '\u{dbb}', IdentifierType::Recommended), ('\u{dbd}', '\u{dbd}', - IdentifierType::Recommended), ('\u{dc0}', '\u{dc6}', IdentifierType::Recommended), - ('\u{dca}', '\u{dca}', IdentifierType::Recommended), ('\u{dcf}', '\u{dd4}', - IdentifierType::Recommended), ('\u{dd6}', '\u{dd6}', IdentifierType::Recommended), - ('\u{dd8}', '\u{dde}', IdentifierType::Recommended), ('\u{ddf}', '\u{ddf}', - IdentifierType::Uncommon_Use), ('\u{de6}', '\u{def}', IdentifierType::Obsolete), - ('\u{df2}', '\u{df2}', IdentifierType::Recommended), ('\u{df3}', '\u{df3}', - IdentifierType::Uncommon_Use), ('\u{df4}', '\u{df4}', IdentifierType::Not_XID), - ('\u{e01}', '\u{e32}', IdentifierType::Recommended), ('\u{e33}', '\u{e33}', - IdentifierType::Not_NFKC), ('\u{e34}', '\u{e3a}', IdentifierType::Recommended), + ('\u{cd5}', '\u{cd6}', IdentifierType::Recommended), ('\u{cdd}', '\u{cdd}', + IdentifierType::Recommended), ('\u{cde}', '\u{cde}', IdentifierType::Obsolete), + ('\u{ce0}', '\u{ce1}', IdentifierType::Recommended), ('\u{ce2}', '\u{ce3}', + IdentifierType::Recommended), ('\u{ce6}', '\u{cef}', IdentifierType::Recommended), + ('\u{cf1}', '\u{cf2}', IdentifierType::Recommended), ('\u{cf3}', '\u{cf3}', + IdentifierType::Recommended), ('\u{d00}', '\u{d00}', IdentifierType::Recommended), + ('\u{d01}', '\u{d01}', IdentifierType::Obsolete), ('\u{d02}', '\u{d03}', + IdentifierType::Recommended), ('\u{d04}', '\u{d04}', IdentifierType::Technical), + ('\u{d05}', '\u{d0c}', IdentifierType::Recommended), ('\u{d0e}', '\u{d10}', + IdentifierType::Recommended), ('\u{d12}', '\u{d28}', IdentifierType::Recommended), + ('\u{d29}', '\u{d29}', IdentifierType::Recommended), ('\u{d2a}', '\u{d39}', + IdentifierType::Recommended), ('\u{d3a}', '\u{d3a}', IdentifierType::Recommended), + ('\u{d3b}', '\u{d3c}', IdentifierType::Obsolete), ('\u{d3d}', '\u{d3d}', + IdentifierType::Recommended), ('\u{d3e}', '\u{d43}', IdentifierType::Recommended), + ('\u{d44}', '\u{d44}', IdentifierType::Uncommon_Use), ('\u{d46}', '\u{d48}', + IdentifierType::Recommended), ('\u{d4a}', '\u{d4d}', IdentifierType::Recommended), + ('\u{d4e}', '\u{d4e}', IdentifierType::Recommended), ('\u{d4f}', '\u{d4f}', + IdentifierType::Not_XID), ('\u{d54}', '\u{d56}', IdentifierType::Recommended), ('\u{d57}', + '\u{d57}', IdentifierType::Recommended), ('\u{d58}', '\u{d5e}', IdentifierType::Not_XID), + ('\u{d5f}', '\u{d5f}', IdentifierType::Obsolete), ('\u{d60}', '\u{d61}', + IdentifierType::Recommended), ('\u{d62}', '\u{d63}', IdentifierType::Uncommon_Use), + ('\u{d66}', '\u{d6f}', IdentifierType::Recommended), ('\u{d70}', '\u{d75}', + IdentifierType::Not_XID), ('\u{d76}', '\u{d78}', IdentifierType::Not_XID), ('\u{d79}', + '\u{d79}', IdentifierType::Not_XID), ('\u{d7a}', '\u{d7f}', IdentifierType::Recommended), + ('\u{d81}', '\u{d81}', IdentifierType::Technical), ('\u{d82}', '\u{d83}', + IdentifierType::Recommended), ('\u{d85}', '\u{d8e}', IdentifierType::Recommended), + ('\u{d8f}', '\u{d90}', IdentifierType::Uncommon_Use), ('\u{d91}', '\u{d96}', + IdentifierType::Recommended), ('\u{d9a}', '\u{da5}', IdentifierType::Recommended), + ('\u{da6}', '\u{da6}', IdentifierType::Uncommon_Use), ('\u{da7}', '\u{db1}', + IdentifierType::Recommended), ('\u{db3}', '\u{dbb}', IdentifierType::Recommended), + ('\u{dbd}', '\u{dbd}', IdentifierType::Recommended), ('\u{dc0}', '\u{dc6}', + IdentifierType::Recommended), ('\u{dca}', '\u{dca}', IdentifierType::Recommended), + ('\u{dcf}', '\u{dd4}', IdentifierType::Recommended), ('\u{dd6}', '\u{dd6}', + IdentifierType::Recommended), ('\u{dd8}', '\u{dde}', IdentifierType::Recommended), + ('\u{ddf}', '\u{ddf}', IdentifierType::Uncommon_Use), ('\u{de6}', '\u{def}', + IdentifierType::Obsolete), ('\u{df2}', '\u{df2}', IdentifierType::Recommended), + ('\u{df3}', '\u{df3}', IdentifierType::Uncommon_Use), ('\u{df4}', '\u{df4}', + IdentifierType::Not_XID), ('\u{e01}', '\u{e32}', IdentifierType::Recommended), ('\u{e33}', + '\u{e33}', IdentifierType::Not_NFKC), ('\u{e34}', '\u{e3a}', IdentifierType::Recommended), ('\u{e3f}', '\u{e3f}', IdentifierType::Not_XID), ('\u{e40}', '\u{e4e}', IdentifierType::Recommended), ('\u{e4f}', '\u{e4f}', IdentifierType::Not_XID), ('\u{e50}', '\u{e59}', IdentifierType::Recommended), ('\u{e5a}', '\u{e5b}', IdentifierType::Not_XID), @@ -662,133 +678,137 @@ pub mod identifier { IdentifierType::Recommended), ('\u{ebb}', '\u{ebd}', IdentifierType::Recommended), ('\u{ec0}', '\u{ec4}', IdentifierType::Recommended), ('\u{ec6}', '\u{ec6}', IdentifierType::Recommended), ('\u{ec8}', '\u{ecd}', IdentifierType::Recommended), - ('\u{ed0}', '\u{ed9}', IdentifierType::Recommended), ('\u{edc}', '\u{edd}', - IdentifierType::Not_NFKC), ('\u{ede}', '\u{edf}', IdentifierType::Recommended), - ('\u{f00}', '\u{f00}', IdentifierType::Recommended), ('\u{f01}', '\u{f0a}', - IdentifierType::Not_XID), ('\u{f0b}', '\u{f0b}', IdentifierType::Inclusion), ('\u{f0c}', - '\u{f0c}', IdentifierType::Not_NFKC), ('\u{f0d}', '\u{f17}', IdentifierType::Not_XID), - ('\u{f18}', '\u{f19}', IdentifierType::Technical), ('\u{f1a}', '\u{f1f}', - IdentifierType::Not_XID), ('\u{f20}', '\u{f29}', IdentifierType::Recommended), ('\u{f2a}', - '\u{f34}', IdentifierType::Not_XID), ('\u{f35}', '\u{f35}', IdentifierType::Recommended), - ('\u{f36}', '\u{f36}', IdentifierType::Not_XID), ('\u{f37}', '\u{f37}', - IdentifierType::Recommended), ('\u{f38}', '\u{f38}', IdentifierType::Not_XID), ('\u{f39}', - '\u{f39}', IdentifierType::Uncommon_Use), ('\u{f3a}', '\u{f3d}', IdentifierType::Not_XID), - ('\u{f3e}', '\u{f42}', IdentifierType::Recommended), ('\u{f43}', '\u{f43}', - IdentifierType::Not_NFKC), ('\u{f44}', '\u{f47}', IdentifierType::Recommended), - ('\u{f49}', '\u{f4c}', IdentifierType::Recommended), ('\u{f4d}', '\u{f4d}', - IdentifierType::Not_NFKC), ('\u{f4e}', '\u{f51}', IdentifierType::Recommended), - ('\u{f52}', '\u{f52}', IdentifierType::Not_NFKC), ('\u{f53}', '\u{f56}', - IdentifierType::Recommended), ('\u{f57}', '\u{f57}', IdentifierType::Not_NFKC), - ('\u{f58}', '\u{f5b}', IdentifierType::Recommended), ('\u{f5c}', '\u{f5c}', - IdentifierType::Not_NFKC), ('\u{f5d}', '\u{f68}', IdentifierType::Recommended), - ('\u{f69}', '\u{f69}', IdentifierType::Not_NFKC), ('\u{f6a}', '\u{f6a}', - IdentifierType::Recommended), ('\u{f6b}', '\u{f6c}', IdentifierType::Recommended), - ('\u{f71}', '\u{f72}', IdentifierType::Recommended), ('\u{f73}', '\u{f73}', - IdentifierType::Not_NFKC), ('\u{f74}', '\u{f74}', IdentifierType::Recommended), - ('\u{f75}', '\u{f76}', IdentifierType::Not_NFKC), ('\u{f77}', '\u{f77}', - IdentifierType::Deprecated), ('\u{f78}', '\u{f78}', IdentifierType::Not_NFKC), ('\u{f79}', - '\u{f79}', IdentifierType::Deprecated), ('\u{f7a}', '\u{f80}', - IdentifierType::Recommended), ('\u{f81}', '\u{f81}', IdentifierType::Not_NFKC), - ('\u{f82}', '\u{f84}', IdentifierType::Recommended), ('\u{f85}', '\u{f85}', - IdentifierType::Not_XID), ('\u{f86}', '\u{f8b}', IdentifierType::Recommended), ('\u{f8c}', - '\u{f8f}', IdentifierType::Recommended), ('\u{f90}', '\u{f92}', - IdentifierType::Recommended), ('\u{f93}', '\u{f93}', IdentifierType::Not_NFKC), - ('\u{f94}', '\u{f95}', IdentifierType::Recommended), ('\u{f96}', '\u{f96}', - IdentifierType::Recommended), ('\u{f97}', '\u{f97}', IdentifierType::Recommended), - ('\u{f99}', '\u{f9c}', IdentifierType::Recommended), ('\u{f9d}', '\u{f9d}', - IdentifierType::Not_NFKC), ('\u{f9e}', '\u{fa1}', IdentifierType::Recommended), - ('\u{fa2}', '\u{fa2}', IdentifierType::Not_NFKC), ('\u{fa3}', '\u{fa6}', - IdentifierType::Recommended), ('\u{fa7}', '\u{fa7}', IdentifierType::Not_NFKC), - ('\u{fa8}', '\u{fab}', IdentifierType::Recommended), ('\u{fac}', '\u{fac}', - IdentifierType::Not_NFKC), ('\u{fad}', '\u{fad}', IdentifierType::Recommended), - ('\u{fae}', '\u{fb0}', IdentifierType::Recommended), ('\u{fb1}', '\u{fb7}', - IdentifierType::Recommended), ('\u{fb8}', '\u{fb8}', IdentifierType::Recommended), - ('\u{fb9}', '\u{fb9}', IdentifierType::Not_NFKC), ('\u{fba}', '\u{fbc}', - IdentifierType::Recommended), ('\u{fbe}', '\u{fc5}', IdentifierType::Not_XID), ('\u{fc6}', - '\u{fc6}', IdentifierType::Recommended), ('\u{fc7}', '\u{fcc}', IdentifierType::Not_XID), - ('\u{fce}', '\u{fce}', IdentifierType::Not_XID), ('\u{fcf}', '\u{fcf}', - IdentifierType::Not_XID), ('\u{fd0}', '\u{fd1}', IdentifierType::Not_XID), ('\u{fd2}', - '\u{fd4}', IdentifierType::Not_XID), ('\u{fd5}', '\u{fd8}', IdentifierType::Not_XID), - ('\u{fd9}', '\u{fda}', IdentifierType::Not_XID), ('\u{1000}', '\u{1021}', - IdentifierType::Recommended), ('\u{1022}', '\u{1022}', IdentifierType::Recommended), - ('\u{1023}', '\u{1027}', IdentifierType::Recommended), ('\u{1028}', '\u{1028}', - IdentifierType::Recommended), ('\u{1029}', '\u{102a}', IdentifierType::Recommended), - ('\u{102b}', '\u{102b}', IdentifierType::Recommended), ('\u{102c}', '\u{1032}', - IdentifierType::Recommended), ('\u{1033}', '\u{1035}', IdentifierType::Recommended), - ('\u{1036}', '\u{1039}', IdentifierType::Recommended), ('\u{103a}', '\u{103f}', - IdentifierType::Recommended), ('\u{1040}', '\u{1049}', IdentifierType::Recommended), - ('\u{104a}', '\u{104f}', IdentifierType::Not_XID), ('\u{1050}', '\u{1059}', - IdentifierType::Recommended), ('\u{105a}', '\u{1099}', IdentifierType::Recommended), - ('\u{109a}', '\u{109d}', IdentifierType::Recommended), ('\u{109e}', '\u{109f}', - IdentifierType::Not_XID), ('\u{10a0}', '\u{10c5}', IdentifierType::Obsolete), ('\u{10c7}', - '\u{10c7}', IdentifierType::Recommended), ('\u{10cd}', '\u{10cd}', - IdentifierType::Recommended), ('\u{10d0}', '\u{10f0}', IdentifierType::Recommended), - ('\u{10f1}', '\u{10f6}', IdentifierType::Obsolete), ('\u{10f7}', '\u{10f8}', - IdentifierType::Recommended), ('\u{10f9}', '\u{10fa}', IdentifierType::Recommended), - ('\u{10fb}', '\u{10fb}', IdentifierType::Not_XID), ('\u{10fc}', '\u{10fc}', - IdentifierType::Not_NFKC), ('\u{10fd}', '\u{10ff}', IdentifierType::Recommended), - ('\u{1100}', '\u{1159}', IdentifierType::Obsolete), ('\u{115a}', '\u{115e}', - IdentifierType::Obsolete), ('\u{115f}', '\u{1160}', IdentifierType::Default_Ignorable), - ('\u{1161}', '\u{11a2}', IdentifierType::Obsolete), ('\u{11a3}', '\u{11a7}', - IdentifierType::Obsolete), ('\u{11a8}', '\u{11f9}', IdentifierType::Obsolete), - ('\u{11fa}', '\u{11ff}', IdentifierType::Obsolete), ('\u{1200}', '\u{1206}', - IdentifierType::Recommended), ('\u{1207}', '\u{1207}', IdentifierType::Recommended), - ('\u{1208}', '\u{1246}', IdentifierType::Recommended), ('\u{1247}', '\u{1247}', - IdentifierType::Recommended), ('\u{1248}', '\u{1248}', IdentifierType::Recommended), - ('\u{124a}', '\u{124d}', IdentifierType::Recommended), ('\u{1250}', '\u{1256}', - IdentifierType::Recommended), ('\u{1258}', '\u{1258}', IdentifierType::Recommended), - ('\u{125a}', '\u{125d}', IdentifierType::Recommended), ('\u{1260}', '\u{1286}', - IdentifierType::Recommended), ('\u{1287}', '\u{1287}', IdentifierType::Recommended), - ('\u{1288}', '\u{1288}', IdentifierType::Recommended), ('\u{128a}', '\u{128d}', - IdentifierType::Recommended), ('\u{1290}', '\u{12ae}', IdentifierType::Recommended), - ('\u{12af}', '\u{12af}', IdentifierType::Recommended), ('\u{12b0}', '\u{12b0}', - IdentifierType::Recommended), ('\u{12b2}', '\u{12b5}', IdentifierType::Recommended), - ('\u{12b8}', '\u{12be}', IdentifierType::Recommended), ('\u{12c0}', '\u{12c0}', - IdentifierType::Recommended), ('\u{12c2}', '\u{12c5}', IdentifierType::Recommended), - ('\u{12c8}', '\u{12ce}', IdentifierType::Recommended), ('\u{12cf}', '\u{12cf}', - IdentifierType::Recommended), ('\u{12d0}', '\u{12d6}', IdentifierType::Recommended), - ('\u{12d8}', '\u{12ee}', IdentifierType::Recommended), ('\u{12ef}', '\u{12ef}', - IdentifierType::Recommended), ('\u{12f0}', '\u{130e}', IdentifierType::Recommended), - ('\u{130f}', '\u{130f}', IdentifierType::Recommended), ('\u{1310}', '\u{1310}', - IdentifierType::Recommended), ('\u{1312}', '\u{1315}', IdentifierType::Recommended), - ('\u{1318}', '\u{131e}', IdentifierType::Recommended), ('\u{131f}', '\u{131f}', - IdentifierType::Recommended), ('\u{1320}', '\u{1346}', IdentifierType::Recommended), - ('\u{1347}', '\u{1347}', IdentifierType::Recommended), ('\u{1348}', '\u{135a}', - IdentifierType::Recommended), ('\u{135d}', '\u{135e}', IdentifierType::Recommended), - ('\u{135f}', '\u{135f}', IdentifierType::Recommended), ('\u{1360}', '\u{1360}', - IdentifierType::Not_XID), ('\u{1361}', '\u{1368}', IdentifierType::Not_XID), ('\u{1369}', - '\u{1371}', IdentifierType::Obsolete), ('\u{1372}', '\u{137c}', IdentifierType::Not_XID), - ('\u{1380}', '\u{138f}', IdentifierType::Recommended), ('\u{1390}', '\u{1399}', - IdentifierType::Not_XID), ('\u{13a0}', '\u{13f4}', IdentifierType::Limited_Use), - ('\u{13f5}', '\u{13f5}', IdentifierType::Limited_Use), ('\u{13f8}', '\u{13fd}', - IdentifierType::Limited_Use), ('\u{1400}', '\u{1400}', IdentifierType::Limited_Use), - ('\u{1401}', '\u{166c}', IdentifierType::Limited_Use), ('\u{166d}', '\u{166e}', - IdentifierType::Limited_Use), ('\u{166f}', '\u{1676}', IdentifierType::Limited_Use), - ('\u{1677}', '\u{167f}', IdentifierType::Limited_Use), ('\u{1680}', '\u{1680}', - IdentifierType::Exclusion), ('\u{1681}', '\u{169a}', IdentifierType::Exclusion), - ('\u{169b}', '\u{169c}', IdentifierType::Exclusion), ('\u{16a0}', '\u{16ea}', - IdentifierType::Exclusion), ('\u{16eb}', '\u{16ed}', IdentifierType::Not_XID), - ('\u{16ee}', '\u{16f0}', IdentifierType::Exclusion), ('\u{16f1}', '\u{16f8}', - IdentifierType::Exclusion), ('\u{1700}', '\u{170c}', IdentifierType::Exclusion), - ('\u{170e}', '\u{1714}', IdentifierType::Exclusion), ('\u{1720}', '\u{1734}', - IdentifierType::Exclusion), ('\u{1735}', '\u{1736}', IdentifierType::Exclusion), - ('\u{1740}', '\u{1753}', IdentifierType::Exclusion), ('\u{1760}', '\u{176c}', - IdentifierType::Exclusion), ('\u{176e}', '\u{1770}', IdentifierType::Exclusion), - ('\u{1772}', '\u{1773}', IdentifierType::Exclusion), ('\u{1780}', '\u{17a2}', - IdentifierType::Recommended), ('\u{17a3}', '\u{17a4}', IdentifierType::Deprecated), - ('\u{17a5}', '\u{17a7}', IdentifierType::Recommended), ('\u{17a8}', '\u{17a8}', - IdentifierType::Obsolete), ('\u{17a9}', '\u{17b3}', IdentifierType::Recommended), - ('\u{17b4}', '\u{17b5}', IdentifierType::Default_Ignorable), ('\u{17b6}', '\u{17ca}', - IdentifierType::Recommended), ('\u{17cb}', '\u{17d0}', IdentifierType::Technical), - ('\u{17d1}', '\u{17d1}', IdentifierType::Technical), ('\u{17d2}', '\u{17d2}', - IdentifierType::Recommended), ('\u{17d3}', '\u{17d3}', IdentifierType::Obsolete), - ('\u{17d4}', '\u{17d6}', IdentifierType::Not_XID), ('\u{17d7}', '\u{17d7}', - IdentifierType::Recommended), ('\u{17d8}', '\u{17d8}', IdentifierType::Obsolete), - ('\u{17d9}', '\u{17db}', IdentifierType::Not_XID), ('\u{17dc}', '\u{17dc}', - IdentifierType::Recommended), ('\u{17dd}', '\u{17dd}', IdentifierType::Technical), - ('\u{17e0}', '\u{17e9}', IdentifierType::Recommended), ('\u{17f0}', '\u{17f9}', - IdentifierType::Not_XID), ('\u{1800}', '\u{180a}', IdentifierType::Exclusion), - ('\u{180b}', '\u{180d}', IdentifierType::Default_Ignorable), ('\u{180e}', '\u{180e}', + ('\u{ece}', '\u{ece}', IdentifierType::Recommended), ('\u{ed0}', '\u{ed9}', + IdentifierType::Recommended), ('\u{edc}', '\u{edd}', IdentifierType::Not_NFKC), + ('\u{ede}', '\u{edf}', IdentifierType::Recommended), ('\u{f00}', '\u{f00}', + IdentifierType::Recommended), ('\u{f01}', '\u{f0a}', IdentifierType::Not_XID), ('\u{f0b}', + '\u{f0b}', IdentifierType::Inclusion), ('\u{f0c}', '\u{f0c}', IdentifierType::Not_NFKC), + ('\u{f0d}', '\u{f17}', IdentifierType::Not_XID), ('\u{f18}', '\u{f19}', + IdentifierType::Technical), ('\u{f1a}', '\u{f1f}', IdentifierType::Not_XID), ('\u{f20}', + '\u{f29}', IdentifierType::Recommended), ('\u{f2a}', '\u{f34}', IdentifierType::Not_XID), + ('\u{f35}', '\u{f35}', IdentifierType::Recommended), ('\u{f36}', '\u{f36}', + IdentifierType::Not_XID), ('\u{f37}', '\u{f37}', IdentifierType::Recommended), ('\u{f38}', + '\u{f38}', IdentifierType::Not_XID), ('\u{f39}', '\u{f39}', IdentifierType::Uncommon_Use), + ('\u{f3a}', '\u{f3d}', IdentifierType::Not_XID), ('\u{f3e}', '\u{f42}', + IdentifierType::Recommended), ('\u{f43}', '\u{f43}', IdentifierType::Not_NFKC), + ('\u{f44}', '\u{f47}', IdentifierType::Recommended), ('\u{f49}', '\u{f4c}', + IdentifierType::Recommended), ('\u{f4d}', '\u{f4d}', IdentifierType::Not_NFKC), + ('\u{f4e}', '\u{f51}', IdentifierType::Recommended), ('\u{f52}', '\u{f52}', + IdentifierType::Not_NFKC), ('\u{f53}', '\u{f56}', IdentifierType::Recommended), + ('\u{f57}', '\u{f57}', IdentifierType::Not_NFKC), ('\u{f58}', '\u{f5b}', + IdentifierType::Recommended), ('\u{f5c}', '\u{f5c}', IdentifierType::Not_NFKC), + ('\u{f5d}', '\u{f68}', IdentifierType::Recommended), ('\u{f69}', '\u{f69}', + IdentifierType::Not_NFKC), ('\u{f6a}', '\u{f6a}', IdentifierType::Recommended), + ('\u{f6b}', '\u{f6c}', IdentifierType::Recommended), ('\u{f71}', '\u{f72}', + IdentifierType::Recommended), ('\u{f73}', '\u{f73}', IdentifierType::Not_NFKC), + ('\u{f74}', '\u{f74}', IdentifierType::Recommended), ('\u{f75}', '\u{f76}', + IdentifierType::Not_NFKC), ('\u{f77}', '\u{f77}', IdentifierType::Deprecated), ('\u{f78}', + '\u{f78}', IdentifierType::Not_NFKC), ('\u{f79}', '\u{f79}', IdentifierType::Deprecated), + ('\u{f7a}', '\u{f80}', IdentifierType::Recommended), ('\u{f81}', '\u{f81}', + IdentifierType::Not_NFKC), ('\u{f82}', '\u{f84}', IdentifierType::Recommended), + ('\u{f85}', '\u{f85}', IdentifierType::Not_XID), ('\u{f86}', '\u{f8b}', + IdentifierType::Recommended), ('\u{f8c}', '\u{f8f}', IdentifierType::Recommended), + ('\u{f90}', '\u{f92}', IdentifierType::Recommended), ('\u{f93}', '\u{f93}', + IdentifierType::Not_NFKC), ('\u{f94}', '\u{f95}', IdentifierType::Recommended), + ('\u{f96}', '\u{f96}', IdentifierType::Recommended), ('\u{f97}', '\u{f97}', + IdentifierType::Recommended), ('\u{f99}', '\u{f9c}', IdentifierType::Recommended), + ('\u{f9d}', '\u{f9d}', IdentifierType::Not_NFKC), ('\u{f9e}', '\u{fa1}', + IdentifierType::Recommended), ('\u{fa2}', '\u{fa2}', IdentifierType::Not_NFKC), + ('\u{fa3}', '\u{fa6}', IdentifierType::Recommended), ('\u{fa7}', '\u{fa7}', + IdentifierType::Not_NFKC), ('\u{fa8}', '\u{fab}', IdentifierType::Recommended), + ('\u{fac}', '\u{fac}', IdentifierType::Not_NFKC), ('\u{fad}', '\u{fad}', + IdentifierType::Recommended), ('\u{fae}', '\u{fb0}', IdentifierType::Recommended), + ('\u{fb1}', '\u{fb7}', IdentifierType::Recommended), ('\u{fb8}', '\u{fb8}', + IdentifierType::Recommended), ('\u{fb9}', '\u{fb9}', IdentifierType::Not_NFKC), + ('\u{fba}', '\u{fbc}', IdentifierType::Recommended), ('\u{fbe}', '\u{fc5}', + IdentifierType::Not_XID), ('\u{fc6}', '\u{fc6}', IdentifierType::Recommended), ('\u{fc7}', + '\u{fcc}', IdentifierType::Not_XID), ('\u{fce}', '\u{fce}', IdentifierType::Not_XID), + ('\u{fcf}', '\u{fcf}', IdentifierType::Not_XID), ('\u{fd0}', '\u{fd1}', + IdentifierType::Not_XID), ('\u{fd2}', '\u{fd4}', IdentifierType::Not_XID), ('\u{fd5}', + '\u{fd8}', IdentifierType::Not_XID), ('\u{fd9}', '\u{fda}', IdentifierType::Not_XID), + ('\u{1000}', '\u{1021}', IdentifierType::Recommended), ('\u{1022}', '\u{1022}', + IdentifierType::Recommended), ('\u{1023}', '\u{1027}', IdentifierType::Recommended), + ('\u{1028}', '\u{1028}', IdentifierType::Recommended), ('\u{1029}', '\u{102a}', + IdentifierType::Recommended), ('\u{102b}', '\u{102b}', IdentifierType::Recommended), + ('\u{102c}', '\u{1032}', IdentifierType::Recommended), ('\u{1033}', '\u{1035}', + IdentifierType::Recommended), ('\u{1036}', '\u{1039}', IdentifierType::Recommended), + ('\u{103a}', '\u{103f}', IdentifierType::Recommended), ('\u{1040}', '\u{1049}', + IdentifierType::Recommended), ('\u{104a}', '\u{104f}', IdentifierType::Not_XID), + ('\u{1050}', '\u{1059}', IdentifierType::Recommended), ('\u{105a}', '\u{1099}', + IdentifierType::Recommended), ('\u{109a}', '\u{109d}', IdentifierType::Recommended), + ('\u{109e}', '\u{109f}', IdentifierType::Not_XID), ('\u{10a0}', '\u{10c5}', + IdentifierType::Obsolete), ('\u{10c7}', '\u{10c7}', IdentifierType::Recommended), + ('\u{10cd}', '\u{10cd}', IdentifierType::Recommended), ('\u{10d0}', '\u{10f0}', + IdentifierType::Recommended), ('\u{10f1}', '\u{10f6}', IdentifierType::Obsolete), + ('\u{10f7}', '\u{10f8}', IdentifierType::Recommended), ('\u{10f9}', '\u{10fa}', + IdentifierType::Recommended), ('\u{10fb}', '\u{10fb}', IdentifierType::Not_XID), + ('\u{10fc}', '\u{10fc}', IdentifierType::Not_NFKC), ('\u{10fd}', '\u{10ff}', + IdentifierType::Recommended), ('\u{1100}', '\u{1159}', IdentifierType::Obsolete), + ('\u{115a}', '\u{115e}', IdentifierType::Obsolete), ('\u{115f}', '\u{1160}', + IdentifierType::Default_Ignorable), ('\u{1161}', '\u{11a2}', IdentifierType::Obsolete), + ('\u{11a3}', '\u{11a7}', IdentifierType::Obsolete), ('\u{11a8}', '\u{11f9}', + IdentifierType::Obsolete), ('\u{11fa}', '\u{11ff}', IdentifierType::Obsolete), + ('\u{1200}', '\u{1206}', IdentifierType::Recommended), ('\u{1207}', '\u{1207}', + IdentifierType::Recommended), ('\u{1208}', '\u{1246}', IdentifierType::Recommended), + ('\u{1247}', '\u{1247}', IdentifierType::Recommended), ('\u{1248}', '\u{1248}', + IdentifierType::Recommended), ('\u{124a}', '\u{124d}', IdentifierType::Recommended), + ('\u{1250}', '\u{1256}', IdentifierType::Recommended), ('\u{1258}', '\u{1258}', + IdentifierType::Recommended), ('\u{125a}', '\u{125d}', IdentifierType::Recommended), + ('\u{1260}', '\u{1286}', IdentifierType::Recommended), ('\u{1287}', '\u{1287}', + IdentifierType::Recommended), ('\u{1288}', '\u{1288}', IdentifierType::Recommended), + ('\u{128a}', '\u{128d}', IdentifierType::Recommended), ('\u{1290}', '\u{12ae}', + IdentifierType::Recommended), ('\u{12af}', '\u{12af}', IdentifierType::Recommended), + ('\u{12b0}', '\u{12b0}', IdentifierType::Recommended), ('\u{12b2}', '\u{12b5}', + IdentifierType::Recommended), ('\u{12b8}', '\u{12be}', IdentifierType::Recommended), + ('\u{12c0}', '\u{12c0}', IdentifierType::Recommended), ('\u{12c2}', '\u{12c5}', + IdentifierType::Recommended), ('\u{12c8}', '\u{12ce}', IdentifierType::Recommended), + ('\u{12cf}', '\u{12cf}', IdentifierType::Recommended), ('\u{12d0}', '\u{12d6}', + IdentifierType::Recommended), ('\u{12d8}', '\u{12ee}', IdentifierType::Recommended), + ('\u{12ef}', '\u{12ef}', IdentifierType::Recommended), ('\u{12f0}', '\u{130e}', + IdentifierType::Recommended), ('\u{130f}', '\u{130f}', IdentifierType::Recommended), + ('\u{1310}', '\u{1310}', IdentifierType::Recommended), ('\u{1312}', '\u{1315}', + IdentifierType::Recommended), ('\u{1318}', '\u{131e}', IdentifierType::Recommended), + ('\u{131f}', '\u{131f}', IdentifierType::Recommended), ('\u{1320}', '\u{1346}', + IdentifierType::Recommended), ('\u{1347}', '\u{1347}', IdentifierType::Recommended), + ('\u{1348}', '\u{135a}', IdentifierType::Recommended), ('\u{135d}', '\u{135e}', + IdentifierType::Recommended), ('\u{135f}', '\u{135f}', IdentifierType::Recommended), + ('\u{1360}', '\u{1360}', IdentifierType::Not_XID), ('\u{1361}', '\u{1368}', + IdentifierType::Not_XID), ('\u{1369}', '\u{1371}', IdentifierType::Obsolete), ('\u{1372}', + '\u{137c}', IdentifierType::Not_XID), ('\u{1380}', '\u{138f}', + IdentifierType::Recommended), ('\u{1390}', '\u{1399}', IdentifierType::Not_XID), + ('\u{13a0}', '\u{13f4}', IdentifierType::Limited_Use), ('\u{13f5}', '\u{13f5}', + IdentifierType::Limited_Use), ('\u{13f8}', '\u{13fd}', IdentifierType::Limited_Use), + ('\u{1400}', '\u{1400}', IdentifierType::Limited_Use), ('\u{1401}', '\u{166c}', + IdentifierType::Limited_Use), ('\u{166d}', '\u{166e}', IdentifierType::Limited_Use), + ('\u{166f}', '\u{1676}', IdentifierType::Limited_Use), ('\u{1677}', '\u{167f}', + IdentifierType::Limited_Use), ('\u{1680}', '\u{1680}', IdentifierType::Exclusion), + ('\u{1681}', '\u{169a}', IdentifierType::Exclusion), ('\u{169b}', '\u{169c}', + IdentifierType::Exclusion), ('\u{16a0}', '\u{16ea}', IdentifierType::Exclusion), + ('\u{16eb}', '\u{16ed}', IdentifierType::Not_XID), ('\u{16ee}', '\u{16f0}', + IdentifierType::Exclusion), ('\u{16f1}', '\u{16f8}', IdentifierType::Exclusion), + ('\u{1700}', '\u{170c}', IdentifierType::Exclusion), ('\u{170d}', '\u{170d}', + IdentifierType::Exclusion), ('\u{170e}', '\u{1714}', IdentifierType::Exclusion), + ('\u{1715}', '\u{1715}', IdentifierType::Exclusion), ('\u{171f}', '\u{171f}', + IdentifierType::Exclusion), ('\u{1720}', '\u{1734}', IdentifierType::Exclusion), + ('\u{1735}', '\u{1736}', IdentifierType::Exclusion), ('\u{1740}', '\u{1753}', + IdentifierType::Exclusion), ('\u{1760}', '\u{176c}', IdentifierType::Exclusion), + ('\u{176e}', '\u{1770}', IdentifierType::Exclusion), ('\u{1772}', '\u{1773}', + IdentifierType::Exclusion), ('\u{1780}', '\u{17a2}', IdentifierType::Recommended), + ('\u{17a3}', '\u{17a4}', IdentifierType::Deprecated), ('\u{17a5}', '\u{17a7}', + IdentifierType::Recommended), ('\u{17a8}', '\u{17a8}', IdentifierType::Obsolete), + ('\u{17a9}', '\u{17b3}', IdentifierType::Recommended), ('\u{17b4}', '\u{17b5}', + IdentifierType::Default_Ignorable), ('\u{17b6}', '\u{17cd}', IdentifierType::Recommended), + ('\u{17ce}', '\u{17cf}', IdentifierType::Technical), ('\u{17d0}', '\u{17d0}', + IdentifierType::Recommended), ('\u{17d1}', '\u{17d1}', IdentifierType::Technical), + ('\u{17d2}', '\u{17d2}', IdentifierType::Recommended), ('\u{17d3}', '\u{17d3}', + IdentifierType::Obsolete), ('\u{17d4}', '\u{17d6}', IdentifierType::Not_XID), ('\u{17d7}', + '\u{17d7}', IdentifierType::Recommended), ('\u{17d8}', '\u{17d8}', + IdentifierType::Obsolete), ('\u{17d9}', '\u{17db}', IdentifierType::Not_XID), ('\u{17dc}', + '\u{17dc}', IdentifierType::Recommended), ('\u{17dd}', '\u{17dd}', + IdentifierType::Technical), ('\u{17e0}', '\u{17e9}', IdentifierType::Recommended), + ('\u{17f0}', '\u{17f9}', IdentifierType::Not_XID), ('\u{1800}', '\u{180a}', + IdentifierType::Exclusion), ('\u{180b}', '\u{180d}', IdentifierType::Default_Ignorable), + ('\u{180e}', '\u{180e}', IdentifierType::Default_Ignorable), ('\u{180f}', '\u{180f}', IdentifierType::Default_Ignorable), ('\u{1810}', '\u{1819}', IdentifierType::Exclusion), ('\u{1820}', '\u{1877}', IdentifierType::Exclusion), ('\u{1878}', '\u{1878}', IdentifierType::Exclusion), ('\u{1880}', '\u{18a8}', IdentifierType::Exclusion), @@ -812,9 +832,11 @@ pub mod identifier { IdentifierType::Limited_Use), ('\u{1aa8}', '\u{1aad}', IdentifierType::Limited_Use), ('\u{1ab0}', '\u{1abd}', IdentifierType::Obsolete), ('\u{1abe}', '\u{1abe}', IdentifierType::Not_XID), ('\u{1abf}', '\u{1ac0}', IdentifierType::Technical), - ('\u{1b00}', '\u{1b4b}', IdentifierType::Limited_Use), ('\u{1b50}', '\u{1b59}', - IdentifierType::Limited_Use), ('\u{1b5a}', '\u{1b6a}', IdentifierType::Limited_Use), - ('\u{1b6b}', '\u{1b73}', IdentifierType::Limited_Use), ('\u{1b74}', '\u{1b7c}', + ('\u{1ac1}', '\u{1ace}', IdentifierType::Uncommon_Use), ('\u{1b00}', '\u{1b4b}', + IdentifierType::Limited_Use), ('\u{1b4c}', '\u{1b4c}', IdentifierType::Limited_Use), + ('\u{1b50}', '\u{1b59}', IdentifierType::Limited_Use), ('\u{1b5a}', '\u{1b6a}', + IdentifierType::Limited_Use), ('\u{1b6b}', '\u{1b73}', IdentifierType::Limited_Use), + ('\u{1b74}', '\u{1b7c}', IdentifierType::Limited_Use), ('\u{1b7d}', '\u{1b7e}', IdentifierType::Limited_Use), ('\u{1b80}', '\u{1baa}', IdentifierType::Limited_Use), ('\u{1bab}', '\u{1bad}', IdentifierType::Limited_Use), ('\u{1bae}', '\u{1bb9}', IdentifierType::Limited_Use), ('\u{1bba}', '\u{1bbf}', IdentifierType::Limited_Use), @@ -844,74 +866,73 @@ pub mod identifier { IdentifierType::Technical), ('\u{1dcf}', '\u{1dd0}', IdentifierType::Technical), ('\u{1dd1}', '\u{1de6}', IdentifierType::Technical), ('\u{1de7}', '\u{1df5}', IdentifierType::Technical), ('\u{1df6}', '\u{1df9}', IdentifierType::Technical), - ('\u{1dfb}', '\u{1dfb}', IdentifierType::Technical), ('\u{1dfc}', '\u{1dfc}', - IdentifierType::Technical), ('\u{1dfd}', '\u{1dfd}', IdentifierType::Technical), - ('\u{1dfe}', '\u{1dff}', IdentifierType::Technical), ('\u{1e00}', '\u{1e99}', - IdentifierType::Recommended), ('\u{1e9a}', '\u{1e9a}', IdentifierType::Not_NFKC), - ('\u{1e9b}', '\u{1e9b}', IdentifierType::Not_NFKC), ('\u{1e9c}', '\u{1e9d}', - IdentifierType::Technical), ('\u{1e9e}', '\u{1e9e}', IdentifierType::Recommended), - ('\u{1e9f}', '\u{1e9f}', IdentifierType::Technical), ('\u{1ea0}', '\u{1ef9}', - IdentifierType::Recommended), ('\u{1efa}', '\u{1eff}', IdentifierType::Technical), - ('\u{1f00}', '\u{1f15}', IdentifierType::Recommended), ('\u{1f18}', '\u{1f1d}', - IdentifierType::Recommended), ('\u{1f20}', '\u{1f45}', IdentifierType::Recommended), - ('\u{1f48}', '\u{1f4d}', IdentifierType::Recommended), ('\u{1f50}', '\u{1f57}', - IdentifierType::Recommended), ('\u{1f59}', '\u{1f59}', IdentifierType::Recommended), - ('\u{1f5b}', '\u{1f5b}', IdentifierType::Recommended), ('\u{1f5d}', '\u{1f5d}', - IdentifierType::Recommended), ('\u{1f5f}', '\u{1f70}', IdentifierType::Recommended), - ('\u{1f71}', '\u{1f71}', IdentifierType::Not_NFKC), ('\u{1f72}', '\u{1f72}', - IdentifierType::Recommended), ('\u{1f73}', '\u{1f73}', IdentifierType::Not_NFKC), - ('\u{1f74}', '\u{1f74}', IdentifierType::Recommended), ('\u{1f75}', '\u{1f75}', - IdentifierType::Not_NFKC), ('\u{1f76}', '\u{1f76}', IdentifierType::Recommended), - ('\u{1f77}', '\u{1f77}', IdentifierType::Not_NFKC), ('\u{1f78}', '\u{1f78}', - IdentifierType::Recommended), ('\u{1f79}', '\u{1f79}', IdentifierType::Not_NFKC), - ('\u{1f7a}', '\u{1f7a}', IdentifierType::Recommended), ('\u{1f7b}', '\u{1f7b}', - IdentifierType::Not_NFKC), ('\u{1f7c}', '\u{1f7c}', IdentifierType::Recommended), - ('\u{1f7d}', '\u{1f7d}', IdentifierType::Not_NFKC), ('\u{1f80}', '\u{1fb4}', - IdentifierType::Recommended), ('\u{1fb6}', '\u{1fba}', IdentifierType::Recommended), - ('\u{1fbb}', '\u{1fbb}', IdentifierType::Not_NFKC), ('\u{1fbc}', '\u{1fbc}', - IdentifierType::Recommended), ('\u{1fbd}', '\u{1fc1}', IdentifierType::Not_NFKC), - ('\u{1fc2}', '\u{1fc4}', IdentifierType::Recommended), ('\u{1fc6}', '\u{1fc8}', - IdentifierType::Recommended), ('\u{1fc9}', '\u{1fc9}', IdentifierType::Not_NFKC), - ('\u{1fca}', '\u{1fca}', IdentifierType::Recommended), ('\u{1fcb}', '\u{1fcb}', - IdentifierType::Not_NFKC), ('\u{1fcc}', '\u{1fcc}', IdentifierType::Recommended), - ('\u{1fcd}', '\u{1fcf}', IdentifierType::Not_NFKC), ('\u{1fd0}', '\u{1fd2}', - IdentifierType::Recommended), ('\u{1fd3}', '\u{1fd3}', IdentifierType::Not_NFKC), - ('\u{1fd6}', '\u{1fda}', IdentifierType::Recommended), ('\u{1fdb}', '\u{1fdb}', - IdentifierType::Not_NFKC), ('\u{1fdd}', '\u{1fdf}', IdentifierType::Not_NFKC), - ('\u{1fe0}', '\u{1fe2}', IdentifierType::Recommended), ('\u{1fe3}', '\u{1fe3}', - IdentifierType::Not_NFKC), ('\u{1fe4}', '\u{1fea}', IdentifierType::Recommended), - ('\u{1feb}', '\u{1feb}', IdentifierType::Not_NFKC), ('\u{1fec}', '\u{1fec}', - IdentifierType::Recommended), ('\u{1fed}', '\u{1fef}', IdentifierType::Not_NFKC), - ('\u{1ff2}', '\u{1ff4}', IdentifierType::Recommended), ('\u{1ff6}', '\u{1ff8}', - IdentifierType::Recommended), ('\u{1ff9}', '\u{1ff9}', IdentifierType::Not_NFKC), - ('\u{1ffa}', '\u{1ffa}', IdentifierType::Recommended), ('\u{1ffb}', '\u{1ffb}', - IdentifierType::Not_NFKC), ('\u{1ffc}', '\u{1ffc}', IdentifierType::Recommended), - ('\u{1ffd}', '\u{1ffe}', IdentifierType::Not_NFKC), ('\u{2000}', '\u{200a}', - IdentifierType::Not_NFKC), ('\u{200b}', '\u{200b}', IdentifierType::Default_Ignorable), - ('\u{200c}', '\u{200d}', IdentifierType::Inclusion), ('\u{200e}', '\u{200f}', - IdentifierType::Default_Ignorable), ('\u{2010}', '\u{2010}', IdentifierType::Inclusion), - ('\u{2011}', '\u{2011}', IdentifierType::Not_NFKC), ('\u{2012}', '\u{2016}', - IdentifierType::Not_XID), ('\u{2017}', '\u{2017}', IdentifierType::Not_NFKC), ('\u{2018}', - '\u{2018}', IdentifierType::Not_XID), ('\u{2019}', '\u{2019}', IdentifierType::Inclusion), - ('\u{201a}', '\u{2023}', IdentifierType::Not_XID), ('\u{2024}', '\u{2026}', - IdentifierType::Not_NFKC), ('\u{2027}', '\u{2027}', IdentifierType::Inclusion), - ('\u{2028}', '\u{2029}', IdentifierType::Not_XID), ('\u{202a}', '\u{202e}', - IdentifierType::Default_Ignorable), ('\u{202f}', '\u{202f}', IdentifierType::Not_NFKC), - ('\u{2030}', '\u{2032}', IdentifierType::Not_XID), ('\u{2033}', '\u{2034}', - IdentifierType::Not_NFKC), ('\u{2035}', '\u{2035}', IdentifierType::Not_XID), ('\u{2036}', - '\u{2037}', IdentifierType::Not_NFKC), ('\u{2038}', '\u{203b}', IdentifierType::Not_XID), - ('\u{203c}', '\u{203c}', IdentifierType::Not_NFKC), ('\u{203d}', '\u{203d}', - IdentifierType::Not_XID), ('\u{203e}', '\u{203e}', IdentifierType::Not_NFKC), ('\u{203f}', - '\u{2040}', IdentifierType::Technical), ('\u{2041}', '\u{2046}', IdentifierType::Not_XID), - ('\u{2047}', '\u{2047}', IdentifierType::Not_NFKC), ('\u{2048}', '\u{2049}', - IdentifierType::Not_NFKC), ('\u{204a}', '\u{204d}', IdentifierType::Not_XID), ('\u{204e}', - '\u{2052}', IdentifierType::Not_XID), ('\u{2053}', '\u{2053}', IdentifierType::Not_XID), - ('\u{2054}', '\u{2054}', IdentifierType::Uncommon_Use), ('\u{2055}', '\u{2055}', - IdentifierType::Not_XID), ('\u{2056}', '\u{2056}', IdentifierType::Obsolete), ('\u{2057}', - '\u{2057}', IdentifierType::Not_NFKC), ('\u{2058}', '\u{205e}', IdentifierType::Obsolete), - ('\u{205f}', '\u{205f}', IdentifierType::Not_NFKC), ('\u{2060}', '\u{2063}', - IdentifierType::Default_Ignorable), ('\u{2064}', '\u{2064}', - IdentifierType::Default_Ignorable), ('\u{2066}', '\u{2069}', + ('\u{1dfa}', '\u{1dfa}', IdentifierType::Limited_Use), ('\u{1dfb}', '\u{1dfb}', + IdentifierType::Technical), ('\u{1dfc}', '\u{1dfc}', IdentifierType::Technical), + ('\u{1dfd}', '\u{1dfd}', IdentifierType::Technical), ('\u{1dfe}', '\u{1dff}', + IdentifierType::Technical), ('\u{1e00}', '\u{1e99}', IdentifierType::Recommended), + ('\u{1e9a}', '\u{1e9a}', IdentifierType::Not_NFKC), ('\u{1e9b}', '\u{1e9b}', + IdentifierType::Not_NFKC), ('\u{1e9c}', '\u{1e9d}', IdentifierType::Technical), + ('\u{1e9e}', '\u{1e9e}', IdentifierType::Recommended), ('\u{1e9f}', '\u{1e9f}', + IdentifierType::Technical), ('\u{1ea0}', '\u{1ef9}', IdentifierType::Recommended), + ('\u{1efa}', '\u{1eff}', IdentifierType::Technical), ('\u{1f00}', '\u{1f15}', + IdentifierType::Recommended), ('\u{1f18}', '\u{1f1d}', IdentifierType::Recommended), + ('\u{1f20}', '\u{1f45}', IdentifierType::Recommended), ('\u{1f48}', '\u{1f4d}', + IdentifierType::Recommended), ('\u{1f50}', '\u{1f57}', IdentifierType::Recommended), + ('\u{1f59}', '\u{1f59}', IdentifierType::Recommended), ('\u{1f5b}', '\u{1f5b}', + IdentifierType::Recommended), ('\u{1f5d}', '\u{1f5d}', IdentifierType::Recommended), + ('\u{1f5f}', '\u{1f70}', IdentifierType::Recommended), ('\u{1f71}', '\u{1f71}', + IdentifierType::Not_NFKC), ('\u{1f72}', '\u{1f72}', IdentifierType::Recommended), + ('\u{1f73}', '\u{1f73}', IdentifierType::Not_NFKC), ('\u{1f74}', '\u{1f74}', + IdentifierType::Recommended), ('\u{1f75}', '\u{1f75}', IdentifierType::Not_NFKC), + ('\u{1f76}', '\u{1f76}', IdentifierType::Recommended), ('\u{1f77}', '\u{1f77}', + IdentifierType::Not_NFKC), ('\u{1f78}', '\u{1f78}', IdentifierType::Recommended), + ('\u{1f79}', '\u{1f79}', IdentifierType::Not_NFKC), ('\u{1f7a}', '\u{1f7a}', + IdentifierType::Recommended), ('\u{1f7b}', '\u{1f7b}', IdentifierType::Not_NFKC), + ('\u{1f7c}', '\u{1f7c}', IdentifierType::Recommended), ('\u{1f7d}', '\u{1f7d}', + IdentifierType::Not_NFKC), ('\u{1f80}', '\u{1fb4}', IdentifierType::Recommended), + ('\u{1fb6}', '\u{1fba}', IdentifierType::Recommended), ('\u{1fbb}', '\u{1fbb}', + IdentifierType::Not_NFKC), ('\u{1fbc}', '\u{1fbc}', IdentifierType::Recommended), + ('\u{1fbd}', '\u{1fc1}', IdentifierType::Not_NFKC), ('\u{1fc2}', '\u{1fc4}', + IdentifierType::Recommended), ('\u{1fc6}', '\u{1fc8}', IdentifierType::Recommended), + ('\u{1fc9}', '\u{1fc9}', IdentifierType::Not_NFKC), ('\u{1fca}', '\u{1fca}', + IdentifierType::Recommended), ('\u{1fcb}', '\u{1fcb}', IdentifierType::Not_NFKC), + ('\u{1fcc}', '\u{1fcc}', IdentifierType::Recommended), ('\u{1fcd}', '\u{1fcf}', + IdentifierType::Not_NFKC), ('\u{1fd0}', '\u{1fd2}', IdentifierType::Recommended), + ('\u{1fd3}', '\u{1fd3}', IdentifierType::Not_NFKC), ('\u{1fd6}', '\u{1fda}', + IdentifierType::Recommended), ('\u{1fdb}', '\u{1fdb}', IdentifierType::Not_NFKC), + ('\u{1fdd}', '\u{1fdf}', IdentifierType::Not_NFKC), ('\u{1fe0}', '\u{1fe2}', + IdentifierType::Recommended), ('\u{1fe3}', '\u{1fe3}', IdentifierType::Not_NFKC), + ('\u{1fe4}', '\u{1fea}', IdentifierType::Recommended), ('\u{1feb}', '\u{1feb}', + IdentifierType::Not_NFKC), ('\u{1fec}', '\u{1fec}', IdentifierType::Recommended), + ('\u{1fed}', '\u{1fef}', IdentifierType::Not_NFKC), ('\u{1ff2}', '\u{1ff4}', + IdentifierType::Recommended), ('\u{1ff6}', '\u{1ff8}', IdentifierType::Recommended), + ('\u{1ff9}', '\u{1ff9}', IdentifierType::Not_NFKC), ('\u{1ffa}', '\u{1ffa}', + IdentifierType::Recommended), ('\u{1ffb}', '\u{1ffb}', IdentifierType::Not_NFKC), + ('\u{1ffc}', '\u{1ffc}', IdentifierType::Recommended), ('\u{1ffd}', '\u{1ffe}', + IdentifierType::Not_NFKC), ('\u{2000}', '\u{200a}', IdentifierType::Not_NFKC), + ('\u{200b}', '\u{200f}', IdentifierType::Default_Ignorable), ('\u{2010}', '\u{2010}', + IdentifierType::Inclusion), ('\u{2011}', '\u{2011}', IdentifierType::Not_NFKC), + ('\u{2012}', '\u{2016}', IdentifierType::Not_XID), ('\u{2017}', '\u{2017}', + IdentifierType::Not_NFKC), ('\u{2018}', '\u{2018}', IdentifierType::Not_XID), ('\u{2019}', + '\u{2019}', IdentifierType::Inclusion), ('\u{201a}', '\u{2023}', IdentifierType::Not_XID), + ('\u{2024}', '\u{2026}', IdentifierType::Not_NFKC), ('\u{2027}', '\u{2027}', + IdentifierType::Inclusion), ('\u{2028}', '\u{2029}', IdentifierType::Not_XID), + ('\u{202a}', '\u{202e}', IdentifierType::Default_Ignorable), ('\u{202f}', '\u{202f}', + IdentifierType::Not_NFKC), ('\u{2030}', '\u{2032}', IdentifierType::Not_XID), ('\u{2033}', + '\u{2034}', IdentifierType::Not_NFKC), ('\u{2035}', '\u{2035}', IdentifierType::Not_XID), + ('\u{2036}', '\u{2037}', IdentifierType::Not_NFKC), ('\u{2038}', '\u{203b}', + IdentifierType::Not_XID), ('\u{203c}', '\u{203c}', IdentifierType::Not_NFKC), ('\u{203d}', + '\u{203d}', IdentifierType::Not_XID), ('\u{203e}', '\u{203e}', IdentifierType::Not_NFKC), + ('\u{203f}', '\u{2040}', IdentifierType::Technical), ('\u{2041}', '\u{2046}', + IdentifierType::Not_XID), ('\u{2047}', '\u{2047}', IdentifierType::Not_NFKC), ('\u{2048}', + '\u{2049}', IdentifierType::Not_NFKC), ('\u{204a}', '\u{204d}', IdentifierType::Not_XID), + ('\u{204e}', '\u{2052}', IdentifierType::Not_XID), ('\u{2053}', '\u{2053}', + IdentifierType::Not_XID), ('\u{2054}', '\u{2054}', IdentifierType::Uncommon_Use), + ('\u{2055}', '\u{2055}', IdentifierType::Not_XID), ('\u{2056}', '\u{2056}', + IdentifierType::Obsolete), ('\u{2057}', '\u{2057}', IdentifierType::Not_NFKC), + ('\u{2058}', '\u{205e}', IdentifierType::Obsolete), ('\u{205f}', '\u{205f}', + IdentifierType::Not_NFKC), ('\u{2060}', '\u{2063}', IdentifierType::Default_Ignorable), + ('\u{2064}', '\u{2064}', IdentifierType::Default_Ignorable), ('\u{2066}', '\u{2069}', IdentifierType::Default_Ignorable), ('\u{206a}', '\u{206f}', IdentifierType::Deprecated), ('\u{2070}', '\u{2070}', IdentifierType::Not_NFKC), ('\u{2071}', '\u{2071}', IdentifierType::Not_NFKC), ('\u{2074}', '\u{208e}', IdentifierType::Not_NFKC), @@ -924,18 +945,19 @@ pub mod identifier { ('\u{20b6}', '\u{20b8}', IdentifierType::Not_XID), ('\u{20b9}', '\u{20b9}', IdentifierType::Not_XID), ('\u{20ba}', '\u{20ba}', IdentifierType::Not_XID), ('\u{20bb}', '\u{20bd}', IdentifierType::Not_XID), ('\u{20be}', '\u{20be}', IdentifierType::Not_XID), - ('\u{20bf}', '\u{20bf}', IdentifierType::Not_XID), ('\u{20d0}', '\u{20dc}', - IdentifierType::Technical), ('\u{20dd}', '\u{20e0}', IdentifierType::Technical), - ('\u{20e1}', '\u{20e1}', IdentifierType::Technical), ('\u{20e2}', '\u{20e3}', - IdentifierType::Technical), ('\u{20e4}', '\u{20e4}', IdentifierType::Technical), - ('\u{20e5}', '\u{20ea}', IdentifierType::Technical), ('\u{20eb}', '\u{20eb}', - IdentifierType::Technical), ('\u{20ec}', '\u{20ef}', IdentifierType::Technical), - ('\u{20f0}', '\u{20f0}', IdentifierType::Technical), ('\u{2100}', '\u{2103}', - IdentifierType::Not_NFKC), ('\u{2104}', '\u{2104}', IdentifierType::Not_XID), ('\u{2105}', - '\u{2107}', IdentifierType::Not_NFKC), ('\u{2108}', '\u{2108}', IdentifierType::Not_XID), - ('\u{2109}', '\u{2113}', IdentifierType::Not_NFKC), ('\u{2114}', '\u{2114}', - IdentifierType::Not_XID), ('\u{2115}', '\u{2116}', IdentifierType::Not_NFKC), ('\u{2117}', - '\u{2117}', IdentifierType::Not_XID), ('\u{2118}', '\u{2118}', IdentifierType::Technical), + ('\u{20bf}', '\u{20bf}', IdentifierType::Not_XID), ('\u{20c0}', '\u{20c0}', + IdentifierType::Not_XID), ('\u{20d0}', '\u{20dc}', IdentifierType::Technical), + ('\u{20dd}', '\u{20e0}', IdentifierType::Technical), ('\u{20e1}', '\u{20e1}', + IdentifierType::Technical), ('\u{20e2}', '\u{20e3}', IdentifierType::Technical), + ('\u{20e4}', '\u{20e4}', IdentifierType::Technical), ('\u{20e5}', '\u{20ea}', + IdentifierType::Technical), ('\u{20eb}', '\u{20eb}', IdentifierType::Technical), + ('\u{20ec}', '\u{20ef}', IdentifierType::Technical), ('\u{20f0}', '\u{20f0}', + IdentifierType::Technical), ('\u{2100}', '\u{2103}', IdentifierType::Not_NFKC), + ('\u{2104}', '\u{2104}', IdentifierType::Not_XID), ('\u{2105}', '\u{2107}', + IdentifierType::Not_NFKC), ('\u{2108}', '\u{2108}', IdentifierType::Not_XID), ('\u{2109}', + '\u{2113}', IdentifierType::Not_NFKC), ('\u{2114}', '\u{2114}', IdentifierType::Not_XID), + ('\u{2115}', '\u{2116}', IdentifierType::Not_NFKC), ('\u{2117}', '\u{2117}', + IdentifierType::Not_XID), ('\u{2118}', '\u{2118}', IdentifierType::Technical), ('\u{2119}', '\u{211d}', IdentifierType::Not_NFKC), ('\u{211e}', '\u{211f}', IdentifierType::Not_XID), ('\u{2120}', '\u{2122}', IdentifierType::Not_NFKC), ('\u{2123}', '\u{2123}', IdentifierType::Not_XID), ('\u{2124}', '\u{2124}', IdentifierType::Not_NFKC), @@ -1036,42 +1058,44 @@ pub mod identifier { '\u{2bd2}', IdentifierType::Not_XID), ('\u{2bd3}', '\u{2beb}', IdentifierType::Not_XID), ('\u{2bec}', '\u{2bef}', IdentifierType::Uncommon_Use), ('\u{2bf0}', '\u{2bfe}', IdentifierType::Not_XID), ('\u{2bff}', '\u{2bff}', IdentifierType::Not_XID), ('\u{2c00}', - '\u{2c2e}', IdentifierType::Exclusion), ('\u{2c30}', '\u{2c5e}', - IdentifierType::Exclusion), ('\u{2c60}', '\u{2c67}', IdentifierType::Technical), - ('\u{2c68}', '\u{2c6c}', IdentifierType::Uncommon_Use), ('\u{2c6d}', '\u{2c6f}', - IdentifierType::Obsolete), ('\u{2c70}', '\u{2c70}', IdentifierType::Obsolete), - ('\u{2c71}', '\u{2c73}', IdentifierType::Obsolete), ('\u{2c74}', '\u{2c76}', - IdentifierType::Obsolete), ('\u{2c77}', '\u{2c77}', IdentifierType::Technical), - ('\u{2c78}', '\u{2c7b}', IdentifierType::Technical), ('\u{2c7c}', '\u{2c7d}', - IdentifierType::Not_NFKC), ('\u{2c7e}', '\u{2c7f}', IdentifierType::Obsolete), - ('\u{2c80}', '\u{2ce4}', IdentifierType::Exclusion), ('\u{2ce5}', '\u{2cea}', - IdentifierType::Exclusion), ('\u{2ceb}', '\u{2cef}', IdentifierType::Exclusion), - ('\u{2cf0}', '\u{2cf1}', IdentifierType::Technical), ('\u{2cf2}', '\u{2cf3}', - IdentifierType::Exclusion), ('\u{2cf9}', '\u{2cff}', IdentifierType::Exclusion), - ('\u{2d00}', '\u{2d25}', IdentifierType::Obsolete), ('\u{2d27}', '\u{2d27}', - IdentifierType::Recommended), ('\u{2d2d}', '\u{2d2d}', IdentifierType::Recommended), - ('\u{2d30}', '\u{2d65}', IdentifierType::Limited_Use), ('\u{2d66}', '\u{2d67}', - IdentifierType::Limited_Use), ('\u{2d6f}', '\u{2d6f}', IdentifierType::Not_NFKC), - ('\u{2d70}', '\u{2d70}', IdentifierType::Limited_Use), ('\u{2d7f}', '\u{2d7f}', - IdentifierType::Limited_Use), ('\u{2d80}', '\u{2d96}', IdentifierType::Recommended), - ('\u{2da0}', '\u{2da6}', IdentifierType::Recommended), ('\u{2da8}', '\u{2dae}', - IdentifierType::Recommended), ('\u{2db0}', '\u{2db6}', IdentifierType::Recommended), - ('\u{2db8}', '\u{2dbe}', IdentifierType::Recommended), ('\u{2dc0}', '\u{2dc6}', - IdentifierType::Recommended), ('\u{2dc8}', '\u{2dce}', IdentifierType::Recommended), - ('\u{2dd0}', '\u{2dd6}', IdentifierType::Recommended), ('\u{2dd8}', '\u{2dde}', - IdentifierType::Recommended), ('\u{2de0}', '\u{2dff}', IdentifierType::Obsolete), - ('\u{2e00}', '\u{2e0d}', IdentifierType::Technical), ('\u{2e0e}', '\u{2e16}', - IdentifierType::Obsolete), ('\u{2e17}', '\u{2e17}', IdentifierType::Not_XID), ('\u{2e18}', - '\u{2e1b}', IdentifierType::Not_XID), ('\u{2e1c}', '\u{2e1d}', IdentifierType::Not_XID), - ('\u{2e1e}', '\u{2e29}', IdentifierType::Not_XID), ('\u{2e2a}', '\u{2e30}', - IdentifierType::Obsolete), ('\u{2e31}', '\u{2e31}', IdentifierType::Obsolete), - ('\u{2e32}', '\u{2e32}', IdentifierType::Obsolete), ('\u{2e33}', '\u{2e34}', - IdentifierType::Not_XID), ('\u{2e35}', '\u{2e35}', IdentifierType::Obsolete), ('\u{2e36}', - '\u{2e38}', IdentifierType::Not_XID), ('\u{2e39}', '\u{2e39}', IdentifierType::Obsolete), - ('\u{2e3a}', '\u{2e3b}', IdentifierType::Not_XID), ('\u{2e3c}', '\u{2e42}', - IdentifierType::Not_XID), ('\u{2e43}', '\u{2e44}', IdentifierType::Not_XID), ('\u{2e45}', - '\u{2e49}', IdentifierType::Not_XID), ('\u{2e4a}', '\u{2e4e}', IdentifierType::Not_XID), - ('\u{2e4f}', '\u{2e4f}', IdentifierType::Not_XID), ('\u{2e50}', '\u{2e52}', + '\u{2c2e}', IdentifierType::Exclusion), ('\u{2c2f}', '\u{2c2f}', + IdentifierType::Exclusion), ('\u{2c30}', '\u{2c5e}', IdentifierType::Exclusion), + ('\u{2c5f}', '\u{2c5f}', IdentifierType::Exclusion), ('\u{2c60}', '\u{2c67}', + IdentifierType::Technical), ('\u{2c68}', '\u{2c6c}', IdentifierType::Uncommon_Use), + ('\u{2c6d}', '\u{2c6f}', IdentifierType::Obsolete), ('\u{2c70}', '\u{2c70}', + IdentifierType::Obsolete), ('\u{2c71}', '\u{2c73}', IdentifierType::Obsolete), + ('\u{2c74}', '\u{2c76}', IdentifierType::Obsolete), ('\u{2c77}', '\u{2c77}', + IdentifierType::Technical), ('\u{2c78}', '\u{2c7b}', IdentifierType::Technical), + ('\u{2c7c}', '\u{2c7d}', IdentifierType::Not_NFKC), ('\u{2c7e}', '\u{2c7f}', + IdentifierType::Obsolete), ('\u{2c80}', '\u{2ce4}', IdentifierType::Exclusion), + ('\u{2ce5}', '\u{2cea}', IdentifierType::Exclusion), ('\u{2ceb}', '\u{2cef}', + IdentifierType::Exclusion), ('\u{2cf0}', '\u{2cf1}', IdentifierType::Technical), + ('\u{2cf2}', '\u{2cf3}', IdentifierType::Exclusion), ('\u{2cf9}', '\u{2cff}', + IdentifierType::Exclusion), ('\u{2d00}', '\u{2d25}', IdentifierType::Obsolete), + ('\u{2d27}', '\u{2d27}', IdentifierType::Recommended), ('\u{2d2d}', '\u{2d2d}', + IdentifierType::Recommended), ('\u{2d30}', '\u{2d65}', IdentifierType::Limited_Use), + ('\u{2d66}', '\u{2d67}', IdentifierType::Limited_Use), ('\u{2d6f}', '\u{2d6f}', + IdentifierType::Not_NFKC), ('\u{2d70}', '\u{2d70}', IdentifierType::Limited_Use), + ('\u{2d7f}', '\u{2d7f}', IdentifierType::Limited_Use), ('\u{2d80}', '\u{2d96}', + IdentifierType::Recommended), ('\u{2da0}', '\u{2da6}', IdentifierType::Recommended), + ('\u{2da8}', '\u{2dae}', IdentifierType::Recommended), ('\u{2db0}', '\u{2db6}', + IdentifierType::Recommended), ('\u{2db8}', '\u{2dbe}', IdentifierType::Recommended), + ('\u{2dc0}', '\u{2dc6}', IdentifierType::Recommended), ('\u{2dc8}', '\u{2dce}', + IdentifierType::Recommended), ('\u{2dd0}', '\u{2dd6}', IdentifierType::Recommended), + ('\u{2dd8}', '\u{2dde}', IdentifierType::Recommended), ('\u{2de0}', '\u{2dff}', + IdentifierType::Obsolete), ('\u{2e00}', '\u{2e0d}', IdentifierType::Technical), + ('\u{2e0e}', '\u{2e16}', IdentifierType::Obsolete), ('\u{2e17}', '\u{2e17}', + IdentifierType::Not_XID), ('\u{2e18}', '\u{2e1b}', IdentifierType::Not_XID), ('\u{2e1c}', + '\u{2e1d}', IdentifierType::Not_XID), ('\u{2e1e}', '\u{2e29}', IdentifierType::Not_XID), + ('\u{2e2a}', '\u{2e30}', IdentifierType::Obsolete), ('\u{2e31}', '\u{2e31}', + IdentifierType::Obsolete), ('\u{2e32}', '\u{2e32}', IdentifierType::Obsolete), + ('\u{2e33}', '\u{2e34}', IdentifierType::Not_XID), ('\u{2e35}', '\u{2e35}', + IdentifierType::Obsolete), ('\u{2e36}', '\u{2e38}', IdentifierType::Not_XID), ('\u{2e39}', + '\u{2e39}', IdentifierType::Obsolete), ('\u{2e3a}', '\u{2e3b}', IdentifierType::Not_XID), + ('\u{2e3c}', '\u{2e42}', IdentifierType::Not_XID), ('\u{2e43}', '\u{2e44}', + IdentifierType::Not_XID), ('\u{2e45}', '\u{2e49}', IdentifierType::Not_XID), ('\u{2e4a}', + '\u{2e4e}', IdentifierType::Not_XID), ('\u{2e4f}', '\u{2e4f}', IdentifierType::Not_XID), + ('\u{2e50}', '\u{2e52}', IdentifierType::Not_XID), ('\u{2e53}', '\u{2e5d}', IdentifierType::Not_XID), ('\u{2e80}', '\u{2e99}', IdentifierType::Not_XID), ('\u{2e9b}', '\u{2e9e}', IdentifierType::Not_XID), ('\u{2e9f}', '\u{2e9f}', IdentifierType::Not_NFKC), ('\u{2ea0}', '\u{2ef2}', IdentifierType::Not_XID), ('\u{2ef3}', '\u{2ef3}', @@ -1104,11 +1128,11 @@ pub mod identifier { IdentifierType::Recommended), ('\u{31b8}', '\u{31ba}', IdentifierType::Recommended), ('\u{31bb}', '\u{31bf}', IdentifierType::Recommended), ('\u{31c0}', '\u{31cf}', IdentifierType::Not_XID), ('\u{31d0}', '\u{31e3}', IdentifierType::Not_XID), ('\u{31f0}', - '\u{31ff}', IdentifierType::Technical), ('\u{3200}', '\u{321c}', - IdentifierType::Not_NFKC), ('\u{321d}', '\u{321e}', IdentifierType::Not_NFKC), - ('\u{3220}', '\u{3243}', IdentifierType::Not_NFKC), ('\u{3244}', '\u{3247}', - IdentifierType::Not_NFKC), ('\u{3248}', '\u{324f}', IdentifierType::Not_XID), ('\u{3250}', - '\u{3250}', IdentifierType::Not_NFKC), ('\u{3251}', '\u{325f}', IdentifierType::Not_NFKC), + '\u{31ff}', IdentifierType::Obsolete), ('\u{3200}', '\u{321c}', IdentifierType::Not_NFKC), + ('\u{321d}', '\u{321e}', IdentifierType::Not_NFKC), ('\u{3220}', '\u{3243}', + IdentifierType::Not_NFKC), ('\u{3244}', '\u{3247}', IdentifierType::Not_NFKC), + ('\u{3248}', '\u{324f}', IdentifierType::Not_XID), ('\u{3250}', '\u{3250}', + IdentifierType::Not_NFKC), ('\u{3251}', '\u{325f}', IdentifierType::Not_NFKC), ('\u{3260}', '\u{327b}', IdentifierType::Not_NFKC), ('\u{327c}', '\u{327d}', IdentifierType::Not_NFKC), ('\u{327e}', '\u{327e}', IdentifierType::Not_NFKC), ('\u{327f}', '\u{327f}', IdentifierType::Technical), ('\u{3280}', '\u{32b0}', @@ -1127,48 +1151,52 @@ pub mod identifier { IdentifierType::Recommended), ('\u{9fcc}', '\u{9fcc}', IdentifierType::Recommended), ('\u{9fcd}', '\u{9fd5}', IdentifierType::Recommended), ('\u{9fd6}', '\u{9fea}', IdentifierType::Recommended), ('\u{9feb}', '\u{9fef}', IdentifierType::Recommended), - ('\u{9ff0}', '\u{9ffc}', IdentifierType::Recommended), ('\u{a000}', '\u{a48c}', - IdentifierType::Limited_Use), ('\u{a490}', '\u{a4a1}', IdentifierType::Limited_Use), - ('\u{a4a2}', '\u{a4a3}', IdentifierType::Limited_Use), ('\u{a4a4}', '\u{a4b3}', - IdentifierType::Limited_Use), ('\u{a4b4}', '\u{a4b4}', IdentifierType::Limited_Use), - ('\u{a4b5}', '\u{a4c0}', IdentifierType::Limited_Use), ('\u{a4c1}', '\u{a4c1}', - IdentifierType::Limited_Use), ('\u{a4c2}', '\u{a4c4}', IdentifierType::Limited_Use), - ('\u{a4c5}', '\u{a4c5}', IdentifierType::Limited_Use), ('\u{a4c6}', '\u{a4c6}', - IdentifierType::Limited_Use), ('\u{a4d0}', '\u{a4fd}', IdentifierType::Limited_Use), - ('\u{a4fe}', '\u{a4ff}', IdentifierType::Limited_Use), ('\u{a500}', '\u{a60c}', - IdentifierType::Limited_Use), ('\u{a60d}', '\u{a60f}', IdentifierType::Limited_Use), - ('\u{a610}', '\u{a612}', IdentifierType::Limited_Use), ('\u{a613}', '\u{a629}', - IdentifierType::Limited_Use), ('\u{a62a}', '\u{a62b}', IdentifierType::Limited_Use), - ('\u{a640}', '\u{a65f}', IdentifierType::Obsolete), ('\u{a660}', '\u{a661}', - IdentifierType::Obsolete), ('\u{a662}', '\u{a66e}', IdentifierType::Obsolete), - ('\u{a66f}', '\u{a66f}', IdentifierType::Uncommon_Use), ('\u{a670}', '\u{a673}', - IdentifierType::Obsolete), ('\u{a674}', '\u{a67b}', IdentifierType::Obsolete), - ('\u{a67c}', '\u{a67d}', IdentifierType::Uncommon_Use), ('\u{a67e}', '\u{a67e}', - IdentifierType::Not_XID), ('\u{a67f}', '\u{a67f}', IdentifierType::Recommended), - ('\u{a680}', '\u{a697}', IdentifierType::Obsolete), ('\u{a698}', '\u{a69b}', - IdentifierType::Obsolete), ('\u{a69c}', '\u{a69d}', IdentifierType::Not_NFKC), - ('\u{a69e}', '\u{a69e}', IdentifierType::Uncommon_Use), ('\u{a69f}', '\u{a69f}', - IdentifierType::Obsolete), ('\u{a6a0}', '\u{a6f1}', IdentifierType::Limited_Use), - ('\u{a6f2}', '\u{a6f7}', IdentifierType::Limited_Use), ('\u{a700}', '\u{a707}', - IdentifierType::Obsolete), ('\u{a708}', '\u{a716}', IdentifierType::Technical), - ('\u{a717}', '\u{a71a}', IdentifierType::Recommended), ('\u{a71b}', '\u{a71f}', - IdentifierType::Recommended), ('\u{a720}', '\u{a721}', IdentifierType::Not_XID), - ('\u{a722}', '\u{a72f}', IdentifierType::Technical), ('\u{a730}', '\u{a76f}', - IdentifierType::Obsolete), ('\u{a770}', '\u{a770}', IdentifierType::Not_NFKC), - ('\u{a771}', '\u{a787}', IdentifierType::Obsolete), ('\u{a788}', '\u{a788}', - IdentifierType::Recommended), ('\u{a789}', '\u{a78a}', IdentifierType::Not_XID), - ('\u{a78b}', '\u{a78c}', IdentifierType::Uncommon_Use), ('\u{a78d}', '\u{a78d}', - IdentifierType::Recommended), ('\u{a78e}', '\u{a78e}', IdentifierType::Technical), - ('\u{a78f}', '\u{a78f}', IdentifierType::Uncommon_Use), ('\u{a790}', '\u{a791}', - IdentifierType::Obsolete), ('\u{a792}', '\u{a793}', IdentifierType::Recommended), - ('\u{a794}', '\u{a79f}', IdentifierType::Obsolete), ('\u{a7a0}', '\u{a7a9}', - IdentifierType::Obsolete), ('\u{a7aa}', '\u{a7aa}', IdentifierType::Recommended), - ('\u{a7ab}', '\u{a7ad}', IdentifierType::Obsolete), ('\u{a7ae}', '\u{a7ae}', - IdentifierType::Recommended), ('\u{a7af}', '\u{a7af}', IdentifierType::Technical), - ('\u{a7b0}', '\u{a7b1}', IdentifierType::Obsolete), ('\u{a7b2}', '\u{a7b7}', - IdentifierType::Uncommon_Use), ('\u{a7b8}', '\u{a7b9}', IdentifierType::Recommended), - ('\u{a7ba}', '\u{a7bf}', IdentifierType::Technical), ('\u{a7c2}', '\u{a7c6}', - IdentifierType::Recommended), ('\u{a7c7}', '\u{a7ca}', IdentifierType::Recommended), + ('\u{9ff0}', '\u{9ffc}', IdentifierType::Recommended), ('\u{9ffd}', '\u{9fff}', + IdentifierType::Recommended), ('\u{a000}', '\u{a48c}', IdentifierType::Limited_Use), + ('\u{a490}', '\u{a4a1}', IdentifierType::Limited_Use), ('\u{a4a2}', '\u{a4a3}', + IdentifierType::Limited_Use), ('\u{a4a4}', '\u{a4b3}', IdentifierType::Limited_Use), + ('\u{a4b4}', '\u{a4b4}', IdentifierType::Limited_Use), ('\u{a4b5}', '\u{a4c0}', + IdentifierType::Limited_Use), ('\u{a4c1}', '\u{a4c1}', IdentifierType::Limited_Use), + ('\u{a4c2}', '\u{a4c4}', IdentifierType::Limited_Use), ('\u{a4c5}', '\u{a4c5}', + IdentifierType::Limited_Use), ('\u{a4c6}', '\u{a4c6}', IdentifierType::Limited_Use), + ('\u{a4d0}', '\u{a4fd}', IdentifierType::Limited_Use), ('\u{a4fe}', '\u{a4ff}', + IdentifierType::Limited_Use), ('\u{a500}', '\u{a60c}', IdentifierType::Limited_Use), + ('\u{a60d}', '\u{a60f}', IdentifierType::Limited_Use), ('\u{a610}', '\u{a612}', + IdentifierType::Limited_Use), ('\u{a613}', '\u{a629}', IdentifierType::Limited_Use), + ('\u{a62a}', '\u{a62b}', IdentifierType::Limited_Use), ('\u{a640}', '\u{a65f}', + IdentifierType::Obsolete), ('\u{a660}', '\u{a661}', IdentifierType::Obsolete), + ('\u{a662}', '\u{a66e}', IdentifierType::Obsolete), ('\u{a66f}', '\u{a66f}', + IdentifierType::Uncommon_Use), ('\u{a670}', '\u{a673}', IdentifierType::Obsolete), + ('\u{a674}', '\u{a67b}', IdentifierType::Obsolete), ('\u{a67c}', '\u{a67d}', + IdentifierType::Uncommon_Use), ('\u{a67e}', '\u{a67e}', IdentifierType::Not_XID), + ('\u{a67f}', '\u{a67f}', IdentifierType::Recommended), ('\u{a680}', '\u{a697}', + IdentifierType::Obsolete), ('\u{a698}', '\u{a69b}', IdentifierType::Obsolete), + ('\u{a69c}', '\u{a69d}', IdentifierType::Not_NFKC), ('\u{a69e}', '\u{a69e}', + IdentifierType::Uncommon_Use), ('\u{a69f}', '\u{a69f}', IdentifierType::Obsolete), + ('\u{a6a0}', '\u{a6f1}', IdentifierType::Limited_Use), ('\u{a6f2}', '\u{a6f7}', + IdentifierType::Limited_Use), ('\u{a700}', '\u{a707}', IdentifierType::Obsolete), + ('\u{a708}', '\u{a716}', IdentifierType::Technical), ('\u{a717}', '\u{a71a}', + IdentifierType::Recommended), ('\u{a71b}', '\u{a71f}', IdentifierType::Recommended), + ('\u{a720}', '\u{a721}', IdentifierType::Not_XID), ('\u{a722}', '\u{a72f}', + IdentifierType::Technical), ('\u{a730}', '\u{a76f}', IdentifierType::Obsolete), + ('\u{a770}', '\u{a770}', IdentifierType::Not_NFKC), ('\u{a771}', '\u{a787}', + IdentifierType::Obsolete), ('\u{a788}', '\u{a788}', IdentifierType::Recommended), + ('\u{a789}', '\u{a78a}', IdentifierType::Not_XID), ('\u{a78b}', '\u{a78c}', + IdentifierType::Uncommon_Use), ('\u{a78d}', '\u{a78d}', IdentifierType::Recommended), + ('\u{a78e}', '\u{a78e}', IdentifierType::Technical), ('\u{a78f}', '\u{a78f}', + IdentifierType::Uncommon_Use), ('\u{a790}', '\u{a791}', IdentifierType::Obsolete), + ('\u{a792}', '\u{a793}', IdentifierType::Recommended), ('\u{a794}', '\u{a79f}', + IdentifierType::Obsolete), ('\u{a7a0}', '\u{a7a9}', IdentifierType::Obsolete), + ('\u{a7aa}', '\u{a7aa}', IdentifierType::Recommended), ('\u{a7ab}', '\u{a7ad}', + IdentifierType::Obsolete), ('\u{a7ae}', '\u{a7ae}', IdentifierType::Technical), + ('\u{a7af}', '\u{a7af}', IdentifierType::Technical), ('\u{a7b0}', '\u{a7b1}', + IdentifierType::Obsolete), ('\u{a7b2}', '\u{a7b7}', IdentifierType::Uncommon_Use), + ('\u{a7b8}', '\u{a7b9}', IdentifierType::Uncommon_Use), ('\u{a7ba}', '\u{a7bf}', + IdentifierType::Technical), ('\u{a7c0}', '\u{a7c1}', IdentifierType::Recommended), + ('\u{a7c2}', '\u{a7c6}', IdentifierType::Recommended), ('\u{a7c7}', '\u{a7ca}', + IdentifierType::Recommended), ('\u{a7d0}', '\u{a7d1}', IdentifierType::Recommended), + ('\u{a7d3}', '\u{a7d3}', IdentifierType::Recommended), ('\u{a7d5}', '\u{a7d9}', + IdentifierType::Recommended), ('\u{a7f2}', '\u{a7f4}', IdentifierType::Not_NFKC), ('\u{a7f5}', '\u{a7f6}', IdentifierType::Obsolete), ('\u{a7f7}', '\u{a7f7}', IdentifierType::Obsolete), ('\u{a7f8}', '\u{a7f9}', IdentifierType::Not_NFKC), ('\u{a7fa}', '\u{a7fa}', IdentifierType::Technical), ('\u{a7fb}', '\u{a7ff}', @@ -1235,119 +1263,133 @@ pub mod identifier { IdentifierType::Not_NFKC), ('\u{fb3e}', '\u{fb3e}', IdentifierType::Not_NFKC), ('\u{fb40}', '\u{fb41}', IdentifierType::Not_NFKC), ('\u{fb43}', '\u{fb44}', IdentifierType::Not_NFKC), ('\u{fb46}', '\u{fbb1}', IdentifierType::Not_NFKC), - ('\u{fbb2}', '\u{fbc1}', IdentifierType::Technical), ('\u{fbd3}', '\u{fd3d}', - IdentifierType::Not_NFKC), ('\u{fd3e}', '\u{fd3f}', IdentifierType::Technical), - ('\u{fd50}', '\u{fd8f}', IdentifierType::Not_NFKC), ('\u{fd92}', '\u{fdc7}', - IdentifierType::Not_NFKC), ('\u{fdf0}', '\u{fdfb}', IdentifierType::Not_NFKC), + ('\u{fbb2}', '\u{fbc1}', IdentifierType::Technical), ('\u{fbc2}', '\u{fbc2}', + IdentifierType::Technical), ('\u{fbd3}', '\u{fd3d}', IdentifierType::Not_NFKC), + ('\u{fd3e}', '\u{fd3f}', IdentifierType::Technical), ('\u{fd40}', '\u{fd4f}', + IdentifierType::Technical), ('\u{fd50}', '\u{fd8f}', IdentifierType::Not_NFKC), + ('\u{fd92}', '\u{fdc7}', IdentifierType::Not_NFKC), ('\u{fdcf}', '\u{fdcf}', + IdentifierType::Technical), ('\u{fdf0}', '\u{fdfb}', IdentifierType::Not_NFKC), ('\u{fdfc}', '\u{fdfc}', IdentifierType::Not_NFKC), ('\u{fdfd}', '\u{fdfd}', - IdentifierType::Technical), ('\u{fe00}', '\u{fe0f}', IdentifierType::Default_Ignorable), - ('\u{fe10}', '\u{fe19}', IdentifierType::Not_NFKC), ('\u{fe20}', '\u{fe23}', - IdentifierType::Technical), ('\u{fe24}', '\u{fe26}', IdentifierType::Technical), - ('\u{fe27}', '\u{fe2d}', IdentifierType::Technical), ('\u{fe2e}', '\u{fe2f}', - IdentifierType::Uncommon_Use), ('\u{fe30}', '\u{fe44}', IdentifierType::Not_NFKC), - ('\u{fe45}', '\u{fe46}', IdentifierType::Technical), ('\u{fe47}', '\u{fe48}', - IdentifierType::Not_NFKC), ('\u{fe49}', '\u{fe52}', IdentifierType::Not_NFKC), - ('\u{fe54}', '\u{fe66}', IdentifierType::Not_NFKC), ('\u{fe68}', '\u{fe6b}', - IdentifierType::Not_NFKC), ('\u{fe70}', '\u{fe72}', IdentifierType::Not_NFKC), - ('\u{fe73}', '\u{fe73}', IdentifierType::Technical), ('\u{fe74}', '\u{fe74}', - IdentifierType::Not_NFKC), ('\u{fe76}', '\u{fefc}', IdentifierType::Not_NFKC), - ('\u{feff}', '\u{feff}', IdentifierType::Default_Ignorable), ('\u{ff01}', '\u{ff5e}', - IdentifierType::Not_NFKC), ('\u{ff5f}', '\u{ff60}', IdentifierType::Not_NFKC), - ('\u{ff61}', '\u{ff9f}', IdentifierType::Not_NFKC), ('\u{ffa0}', '\u{ffa0}', - IdentifierType::Default_Ignorable), ('\u{ffa1}', '\u{ffbe}', IdentifierType::Not_NFKC), - ('\u{ffc2}', '\u{ffc7}', IdentifierType::Not_NFKC), ('\u{ffca}', '\u{ffcf}', - IdentifierType::Not_NFKC), ('\u{ffd2}', '\u{ffd7}', IdentifierType::Not_NFKC), - ('\u{ffda}', '\u{ffdc}', IdentifierType::Not_NFKC), ('\u{ffe0}', '\u{ffe6}', - IdentifierType::Not_NFKC), ('\u{ffe8}', '\u{ffee}', IdentifierType::Not_NFKC), - ('\u{fff9}', '\u{fffb}', IdentifierType::Not_XID), ('\u{fffc}', '\u{fffc}', - IdentifierType::Not_XID), ('\u{fffd}', '\u{fffd}', IdentifierType::Not_XID), ('\u{10000}', - '\u{1000b}', IdentifierType::Exclusion), ('\u{1000d}', '\u{10026}', - IdentifierType::Exclusion), ('\u{10028}', '\u{1003a}', IdentifierType::Exclusion), - ('\u{1003c}', '\u{1003d}', IdentifierType::Exclusion), ('\u{1003f}', '\u{1004d}', - IdentifierType::Exclusion), ('\u{10050}', '\u{1005d}', IdentifierType::Exclusion), - ('\u{10080}', '\u{100fa}', IdentifierType::Exclusion), ('\u{10100}', '\u{10102}', - IdentifierType::Exclusion), ('\u{10107}', '\u{10133}', IdentifierType::Exclusion), - ('\u{10137}', '\u{1013f}', IdentifierType::Exclusion), ('\u{10140}', '\u{10174}', - IdentifierType::Obsolete), ('\u{10175}', '\u{1018a}', IdentifierType::Not_XID), - ('\u{1018b}', '\u{1018c}', IdentifierType::Not_XID), ('\u{1018d}', '\u{1018e}', - IdentifierType::Not_XID), ('\u{10190}', '\u{1019b}', IdentifierType::Not_XID), - ('\u{1019c}', '\u{1019c}', IdentifierType::Not_XID), ('\u{101a0}', '\u{101a0}', - IdentifierType::Not_XID), ('\u{101d0}', '\u{101fc}', IdentifierType::Obsolete), - ('\u{101fd}', '\u{101fd}', IdentifierType::Obsolete), ('\u{10280}', '\u{1029c}', - IdentifierType::Exclusion), ('\u{102a0}', '\u{102d0}', IdentifierType::Exclusion), - ('\u{102e0}', '\u{102e0}', IdentifierType::Obsolete), ('\u{102e1}', '\u{102fb}', - IdentifierType::Obsolete), ('\u{10300}', '\u{1031e}', IdentifierType::Exclusion), - ('\u{1031f}', '\u{1031f}', IdentifierType::Exclusion), ('\u{10320}', '\u{10323}', - IdentifierType::Exclusion), ('\u{1032d}', '\u{1032f}', IdentifierType::Exclusion), - ('\u{10330}', '\u{1034a}', IdentifierType::Exclusion), ('\u{10350}', '\u{1037a}', - IdentifierType::Exclusion), ('\u{10380}', '\u{1039d}', IdentifierType::Exclusion), - ('\u{1039f}', '\u{1039f}', IdentifierType::Exclusion), ('\u{103a0}', '\u{103c3}', - IdentifierType::Exclusion), ('\u{103c8}', '\u{103cf}', IdentifierType::Exclusion), - ('\u{103d0}', '\u{103d0}', IdentifierType::Exclusion), ('\u{103d1}', '\u{103d5}', - IdentifierType::Exclusion), ('\u{10400}', '\u{10425}', IdentifierType::Exclusion), - ('\u{10426}', '\u{10427}', IdentifierType::Exclusion), ('\u{10428}', '\u{1044d}', - IdentifierType::Exclusion), ('\u{1044e}', '\u{1049d}', IdentifierType::Exclusion), - ('\u{104a0}', '\u{104a9}', IdentifierType::Exclusion), ('\u{104b0}', '\u{104d3}', - IdentifierType::Limited_Use), ('\u{104d8}', '\u{104fb}', IdentifierType::Limited_Use), - ('\u{10500}', '\u{10527}', IdentifierType::Exclusion), ('\u{10530}', '\u{10563}', - IdentifierType::Exclusion), ('\u{1056f}', '\u{1056f}', IdentifierType::Exclusion), + IdentifierType::Technical), ('\u{fdfe}', '\u{fdff}', IdentifierType::Technical), + ('\u{fe00}', '\u{fe0f}', IdentifierType::Default_Ignorable), ('\u{fe10}', '\u{fe19}', + IdentifierType::Not_NFKC), ('\u{fe20}', '\u{fe23}', IdentifierType::Technical), + ('\u{fe24}', '\u{fe26}', IdentifierType::Technical), ('\u{fe27}', '\u{fe2d}', + IdentifierType::Technical), ('\u{fe2e}', '\u{fe2f}', IdentifierType::Uncommon_Use), + ('\u{fe30}', '\u{fe44}', IdentifierType::Not_NFKC), ('\u{fe45}', '\u{fe46}', + IdentifierType::Technical), ('\u{fe47}', '\u{fe48}', IdentifierType::Not_NFKC), + ('\u{fe49}', '\u{fe52}', IdentifierType::Not_NFKC), ('\u{fe54}', '\u{fe66}', + IdentifierType::Not_NFKC), ('\u{fe68}', '\u{fe6b}', IdentifierType::Not_NFKC), + ('\u{fe70}', '\u{fe72}', IdentifierType::Not_NFKC), ('\u{fe73}', '\u{fe73}', + IdentifierType::Technical), ('\u{fe74}', '\u{fe74}', IdentifierType::Not_NFKC), + ('\u{fe76}', '\u{fefc}', IdentifierType::Not_NFKC), ('\u{feff}', '\u{feff}', + IdentifierType::Default_Ignorable), ('\u{ff01}', '\u{ff5e}', IdentifierType::Not_NFKC), + ('\u{ff5f}', '\u{ff60}', IdentifierType::Not_NFKC), ('\u{ff61}', '\u{ff9f}', + IdentifierType::Not_NFKC), ('\u{ffa0}', '\u{ffa0}', IdentifierType::Default_Ignorable), + ('\u{ffa1}', '\u{ffbe}', IdentifierType::Not_NFKC), ('\u{ffc2}', '\u{ffc7}', + IdentifierType::Not_NFKC), ('\u{ffca}', '\u{ffcf}', IdentifierType::Not_NFKC), + ('\u{ffd2}', '\u{ffd7}', IdentifierType::Not_NFKC), ('\u{ffda}', '\u{ffdc}', + IdentifierType::Not_NFKC), ('\u{ffe0}', '\u{ffe6}', IdentifierType::Not_NFKC), + ('\u{ffe8}', '\u{ffee}', IdentifierType::Not_NFKC), ('\u{fff9}', '\u{fffb}', + IdentifierType::Not_XID), ('\u{fffc}', '\u{fffc}', IdentifierType::Not_XID), ('\u{fffd}', + '\u{fffd}', IdentifierType::Not_XID), ('\u{10000}', '\u{1000b}', + IdentifierType::Exclusion), ('\u{1000d}', '\u{10026}', IdentifierType::Exclusion), + ('\u{10028}', '\u{1003a}', IdentifierType::Exclusion), ('\u{1003c}', '\u{1003d}', + IdentifierType::Exclusion), ('\u{1003f}', '\u{1004d}', IdentifierType::Exclusion), + ('\u{10050}', '\u{1005d}', IdentifierType::Exclusion), ('\u{10080}', '\u{100fa}', + IdentifierType::Exclusion), ('\u{10100}', '\u{10102}', IdentifierType::Exclusion), + ('\u{10107}', '\u{10133}', IdentifierType::Exclusion), ('\u{10137}', '\u{1013f}', + IdentifierType::Exclusion), ('\u{10140}', '\u{10174}', IdentifierType::Obsolete), + ('\u{10175}', '\u{1018a}', IdentifierType::Not_XID), ('\u{1018b}', '\u{1018c}', + IdentifierType::Not_XID), ('\u{1018d}', '\u{1018e}', IdentifierType::Not_XID), + ('\u{10190}', '\u{1019b}', IdentifierType::Not_XID), ('\u{1019c}', '\u{1019c}', + IdentifierType::Not_XID), ('\u{101a0}', '\u{101a0}', IdentifierType::Not_XID), + ('\u{101d0}', '\u{101fc}', IdentifierType::Obsolete), ('\u{101fd}', '\u{101fd}', + IdentifierType::Obsolete), ('\u{10280}', '\u{1029c}', IdentifierType::Exclusion), + ('\u{102a0}', '\u{102d0}', IdentifierType::Exclusion), ('\u{102e0}', '\u{102e0}', + IdentifierType::Obsolete), ('\u{102e1}', '\u{102fb}', IdentifierType::Obsolete), + ('\u{10300}', '\u{1031e}', IdentifierType::Exclusion), ('\u{1031f}', '\u{1031f}', + IdentifierType::Exclusion), ('\u{10320}', '\u{10323}', IdentifierType::Exclusion), + ('\u{1032d}', '\u{1032f}', IdentifierType::Exclusion), ('\u{10330}', '\u{1034a}', + IdentifierType::Exclusion), ('\u{10350}', '\u{1037a}', IdentifierType::Exclusion), + ('\u{10380}', '\u{1039d}', IdentifierType::Exclusion), ('\u{1039f}', '\u{1039f}', + IdentifierType::Exclusion), ('\u{103a0}', '\u{103c3}', IdentifierType::Exclusion), + ('\u{103c8}', '\u{103cf}', IdentifierType::Exclusion), ('\u{103d0}', '\u{103d0}', + IdentifierType::Exclusion), ('\u{103d1}', '\u{103d5}', IdentifierType::Exclusion), + ('\u{10400}', '\u{10425}', IdentifierType::Exclusion), ('\u{10426}', '\u{10427}', + IdentifierType::Exclusion), ('\u{10428}', '\u{1044d}', IdentifierType::Exclusion), + ('\u{1044e}', '\u{1049d}', IdentifierType::Exclusion), ('\u{104a0}', '\u{104a9}', + IdentifierType::Exclusion), ('\u{104b0}', '\u{104d3}', IdentifierType::Limited_Use), + ('\u{104d8}', '\u{104fb}', IdentifierType::Limited_Use), ('\u{10500}', '\u{10527}', + IdentifierType::Exclusion), ('\u{10530}', '\u{10563}', IdentifierType::Exclusion), + ('\u{1056f}', '\u{1056f}', IdentifierType::Exclusion), ('\u{10570}', '\u{1057a}', + IdentifierType::Exclusion), ('\u{1057c}', '\u{1058a}', IdentifierType::Exclusion), + ('\u{1058c}', '\u{10592}', IdentifierType::Exclusion), ('\u{10594}', '\u{10595}', + IdentifierType::Exclusion), ('\u{10597}', '\u{105a1}', IdentifierType::Exclusion), + ('\u{105a3}', '\u{105b1}', IdentifierType::Exclusion), ('\u{105b3}', '\u{105b9}', + IdentifierType::Exclusion), ('\u{105bb}', '\u{105bc}', IdentifierType::Exclusion), ('\u{10600}', '\u{10736}', IdentifierType::Exclusion), ('\u{10740}', '\u{10755}', IdentifierType::Exclusion), ('\u{10760}', '\u{10767}', IdentifierType::Exclusion), - ('\u{10800}', '\u{10805}', IdentifierType::Exclusion), ('\u{10808}', '\u{10808}', - IdentifierType::Exclusion), ('\u{1080a}', '\u{10835}', IdentifierType::Exclusion), - ('\u{10837}', '\u{10838}', IdentifierType::Exclusion), ('\u{1083c}', '\u{1083c}', - IdentifierType::Exclusion), ('\u{1083f}', '\u{1083f}', IdentifierType::Exclusion), - ('\u{10840}', '\u{10855}', IdentifierType::Exclusion), ('\u{10857}', '\u{1085f}', - IdentifierType::Exclusion), ('\u{10860}', '\u{10876}', IdentifierType::Exclusion), - ('\u{10877}', '\u{1087f}', IdentifierType::Exclusion), ('\u{10880}', '\u{1089e}', - IdentifierType::Exclusion), ('\u{108a7}', '\u{108af}', IdentifierType::Exclusion), - ('\u{108e0}', '\u{108f2}', IdentifierType::Exclusion), ('\u{108f4}', '\u{108f5}', - IdentifierType::Exclusion), ('\u{108fb}', '\u{108ff}', IdentifierType::Exclusion), - ('\u{10900}', '\u{10915}', IdentifierType::Exclusion), ('\u{10916}', '\u{10919}', - IdentifierType::Exclusion), ('\u{1091a}', '\u{1091b}', IdentifierType::Exclusion), - ('\u{1091f}', '\u{1091f}', IdentifierType::Exclusion), ('\u{10920}', '\u{10939}', - IdentifierType::Exclusion), ('\u{1093f}', '\u{1093f}', IdentifierType::Exclusion), - ('\u{10980}', '\u{109b7}', IdentifierType::Exclusion), ('\u{109bc}', '\u{109bd}', - IdentifierType::Exclusion), ('\u{109be}', '\u{109bf}', IdentifierType::Exclusion), - ('\u{109c0}', '\u{109cf}', IdentifierType::Exclusion), ('\u{109d2}', '\u{109ff}', - IdentifierType::Exclusion), ('\u{10a00}', '\u{10a03}', IdentifierType::Exclusion), - ('\u{10a05}', '\u{10a06}', IdentifierType::Exclusion), ('\u{10a0c}', '\u{10a13}', - IdentifierType::Exclusion), ('\u{10a15}', '\u{10a17}', IdentifierType::Exclusion), - ('\u{10a19}', '\u{10a33}', IdentifierType::Exclusion), ('\u{10a34}', '\u{10a35}', - IdentifierType::Exclusion), ('\u{10a38}', '\u{10a3a}', IdentifierType::Exclusion), - ('\u{10a3f}', '\u{10a3f}', IdentifierType::Exclusion), ('\u{10a40}', '\u{10a47}', - IdentifierType::Exclusion), ('\u{10a48}', '\u{10a48}', IdentifierType::Exclusion), - ('\u{10a50}', '\u{10a58}', IdentifierType::Exclusion), ('\u{10a60}', '\u{10a7c}', - IdentifierType::Exclusion), ('\u{10a7d}', '\u{10a7f}', IdentifierType::Exclusion), - ('\u{10a80}', '\u{10a9c}', IdentifierType::Exclusion), ('\u{10a9d}', '\u{10a9f}', - IdentifierType::Exclusion), ('\u{10ac0}', '\u{10ac7}', IdentifierType::Exclusion), - ('\u{10ac8}', '\u{10ac8}', IdentifierType::Exclusion), ('\u{10ac9}', '\u{10ae6}', - IdentifierType::Exclusion), ('\u{10aeb}', '\u{10af6}', IdentifierType::Exclusion), - ('\u{10b00}', '\u{10b35}', IdentifierType::Exclusion), ('\u{10b39}', '\u{10b3f}', - IdentifierType::Exclusion), ('\u{10b40}', '\u{10b55}', IdentifierType::Exclusion), - ('\u{10b58}', '\u{10b5f}', IdentifierType::Exclusion), ('\u{10b60}', '\u{10b72}', - IdentifierType::Exclusion), ('\u{10b78}', '\u{10b7f}', IdentifierType::Exclusion), - ('\u{10b80}', '\u{10b91}', IdentifierType::Exclusion), ('\u{10b99}', '\u{10b9c}', - IdentifierType::Exclusion), ('\u{10ba9}', '\u{10baf}', IdentifierType::Exclusion), - ('\u{10c00}', '\u{10c48}', IdentifierType::Exclusion), ('\u{10c80}', '\u{10cb2}', - IdentifierType::Exclusion), ('\u{10cc0}', '\u{10cf2}', IdentifierType::Exclusion), - ('\u{10cfa}', '\u{10cff}', IdentifierType::Exclusion), ('\u{10d00}', '\u{10d27}', - IdentifierType::Limited_Use), ('\u{10d30}', '\u{10d39}', IdentifierType::Limited_Use), - ('\u{10e60}', '\u{10e7e}', IdentifierType::Not_XID), ('\u{10e80}', '\u{10ea9}', - IdentifierType::Exclusion), ('\u{10eab}', '\u{10eac}', IdentifierType::Exclusion), - ('\u{10ead}', '\u{10ead}', IdentifierType::Exclusion), ('\u{10eb0}', '\u{10eb1}', - IdentifierType::Exclusion), ('\u{10f00}', '\u{10f1c}', IdentifierType::Exclusion), - ('\u{10f1d}', '\u{10f26}', IdentifierType::Exclusion), ('\u{10f27}', '\u{10f27}', - IdentifierType::Exclusion), ('\u{10f30}', '\u{10f50}', IdentifierType::Exclusion), - ('\u{10f51}', '\u{10f59}', IdentifierType::Exclusion), ('\u{10fb0}', '\u{10fc4}', - IdentifierType::Exclusion), ('\u{10fc5}', '\u{10fcb}', IdentifierType::Exclusion), - ('\u{10fe0}', '\u{10ff6}', IdentifierType::Exclusion), ('\u{11000}', '\u{11046}', - IdentifierType::Exclusion), ('\u{11047}', '\u{1104d}', IdentifierType::Exclusion), - ('\u{11052}', '\u{11065}', IdentifierType::Exclusion), ('\u{11066}', '\u{1106f}', - IdentifierType::Exclusion), ('\u{1107f}', '\u{1107f}', IdentifierType::Exclusion), - ('\u{11080}', '\u{110ba}', IdentifierType::Exclusion), ('\u{110bb}', '\u{110bc}', - IdentifierType::Exclusion), ('\u{110bd}', '\u{110bd}', IdentifierType::Exclusion), - ('\u{110be}', '\u{110c1}', IdentifierType::Exclusion), ('\u{110cd}', '\u{110cd}', + ('\u{10780}', '\u{10780}', IdentifierType::Uncommon_Use), ('\u{10781}', '\u{10785}', + IdentifierType::Not_NFKC), ('\u{10787}', '\u{107b0}', IdentifierType::Not_NFKC), + ('\u{107b2}', '\u{107ba}', IdentifierType::Not_NFKC), ('\u{10800}', '\u{10805}', + IdentifierType::Exclusion), ('\u{10808}', '\u{10808}', IdentifierType::Exclusion), + ('\u{1080a}', '\u{10835}', IdentifierType::Exclusion), ('\u{10837}', '\u{10838}', + IdentifierType::Exclusion), ('\u{1083c}', '\u{1083c}', IdentifierType::Exclusion), + ('\u{1083f}', '\u{1083f}', IdentifierType::Exclusion), ('\u{10840}', '\u{10855}', + IdentifierType::Exclusion), ('\u{10857}', '\u{1085f}', IdentifierType::Exclusion), + ('\u{10860}', '\u{10876}', IdentifierType::Exclusion), ('\u{10877}', '\u{1087f}', + IdentifierType::Exclusion), ('\u{10880}', '\u{1089e}', IdentifierType::Exclusion), + ('\u{108a7}', '\u{108af}', IdentifierType::Exclusion), ('\u{108e0}', '\u{108f2}', + IdentifierType::Exclusion), ('\u{108f4}', '\u{108f5}', IdentifierType::Exclusion), + ('\u{108fb}', '\u{108ff}', IdentifierType::Exclusion), ('\u{10900}', '\u{10915}', + IdentifierType::Exclusion), ('\u{10916}', '\u{10919}', IdentifierType::Exclusion), + ('\u{1091a}', '\u{1091b}', IdentifierType::Exclusion), ('\u{1091f}', '\u{1091f}', + IdentifierType::Exclusion), ('\u{10920}', '\u{10939}', IdentifierType::Exclusion), + ('\u{1093f}', '\u{1093f}', IdentifierType::Exclusion), ('\u{10980}', '\u{109b7}', + IdentifierType::Exclusion), ('\u{109bc}', '\u{109bd}', IdentifierType::Exclusion), + ('\u{109be}', '\u{109bf}', IdentifierType::Exclusion), ('\u{109c0}', '\u{109cf}', + IdentifierType::Exclusion), ('\u{109d2}', '\u{109ff}', IdentifierType::Exclusion), + ('\u{10a00}', '\u{10a03}', IdentifierType::Exclusion), ('\u{10a05}', '\u{10a06}', + IdentifierType::Exclusion), ('\u{10a0c}', '\u{10a13}', IdentifierType::Exclusion), + ('\u{10a15}', '\u{10a17}', IdentifierType::Exclusion), ('\u{10a19}', '\u{10a33}', + IdentifierType::Exclusion), ('\u{10a34}', '\u{10a35}', IdentifierType::Exclusion), + ('\u{10a38}', '\u{10a3a}', IdentifierType::Exclusion), ('\u{10a3f}', '\u{10a3f}', + IdentifierType::Exclusion), ('\u{10a40}', '\u{10a47}', IdentifierType::Exclusion), + ('\u{10a48}', '\u{10a48}', IdentifierType::Exclusion), ('\u{10a50}', '\u{10a58}', + IdentifierType::Exclusion), ('\u{10a60}', '\u{10a7c}', IdentifierType::Exclusion), + ('\u{10a7d}', '\u{10a7f}', IdentifierType::Exclusion), ('\u{10a80}', '\u{10a9c}', + IdentifierType::Exclusion), ('\u{10a9d}', '\u{10a9f}', IdentifierType::Exclusion), + ('\u{10ac0}', '\u{10ac7}', IdentifierType::Exclusion), ('\u{10ac8}', '\u{10ac8}', + IdentifierType::Exclusion), ('\u{10ac9}', '\u{10ae6}', IdentifierType::Exclusion), + ('\u{10aeb}', '\u{10af6}', IdentifierType::Exclusion), ('\u{10b00}', '\u{10b35}', + IdentifierType::Exclusion), ('\u{10b39}', '\u{10b3f}', IdentifierType::Exclusion), + ('\u{10b40}', '\u{10b55}', IdentifierType::Exclusion), ('\u{10b58}', '\u{10b5f}', + IdentifierType::Exclusion), ('\u{10b60}', '\u{10b72}', IdentifierType::Exclusion), + ('\u{10b78}', '\u{10b7f}', IdentifierType::Exclusion), ('\u{10b80}', '\u{10b91}', + IdentifierType::Exclusion), ('\u{10b99}', '\u{10b9c}', IdentifierType::Exclusion), + ('\u{10ba9}', '\u{10baf}', IdentifierType::Exclusion), ('\u{10c00}', '\u{10c48}', + IdentifierType::Exclusion), ('\u{10c80}', '\u{10cb2}', IdentifierType::Exclusion), + ('\u{10cc0}', '\u{10cf2}', IdentifierType::Exclusion), ('\u{10cfa}', '\u{10cff}', + IdentifierType::Exclusion), ('\u{10d00}', '\u{10d27}', IdentifierType::Limited_Use), + ('\u{10d30}', '\u{10d39}', IdentifierType::Limited_Use), ('\u{10e60}', '\u{10e7e}', + IdentifierType::Not_XID), ('\u{10e80}', '\u{10ea9}', IdentifierType::Exclusion), + ('\u{10eab}', '\u{10eac}', IdentifierType::Exclusion), ('\u{10ead}', '\u{10ead}', + IdentifierType::Exclusion), ('\u{10eb0}', '\u{10eb1}', IdentifierType::Exclusion), + ('\u{10efd}', '\u{10eff}', IdentifierType::Uncommon_Use), ('\u{10f00}', '\u{10f1c}', + IdentifierType::Exclusion), ('\u{10f1d}', '\u{10f26}', IdentifierType::Exclusion), + ('\u{10f27}', '\u{10f27}', IdentifierType::Exclusion), ('\u{10f30}', '\u{10f50}', + IdentifierType::Exclusion), ('\u{10f51}', '\u{10f59}', IdentifierType::Exclusion), + ('\u{10f70}', '\u{10f85}', IdentifierType::Exclusion), ('\u{10f86}', '\u{10f89}', + IdentifierType::Exclusion), ('\u{10fb0}', '\u{10fc4}', IdentifierType::Exclusion), + ('\u{10fc5}', '\u{10fcb}', IdentifierType::Exclusion), ('\u{10fe0}', '\u{10ff6}', + IdentifierType::Exclusion), ('\u{11000}', '\u{11046}', IdentifierType::Exclusion), + ('\u{11047}', '\u{1104d}', IdentifierType::Exclusion), ('\u{11052}', '\u{11065}', + IdentifierType::Exclusion), ('\u{11066}', '\u{1106f}', IdentifierType::Exclusion), + ('\u{11070}', '\u{11075}', IdentifierType::Exclusion), ('\u{1107f}', '\u{1107f}', + IdentifierType::Exclusion), ('\u{11080}', '\u{110ba}', IdentifierType::Exclusion), + ('\u{110bb}', '\u{110bc}', IdentifierType::Exclusion), ('\u{110bd}', '\u{110bd}', + IdentifierType::Exclusion), ('\u{110be}', '\u{110c1}', IdentifierType::Exclusion), + ('\u{110c2}', '\u{110c2}', IdentifierType::Exclusion), ('\u{110cd}', '\u{110cd}', IdentifierType::Exclusion), ('\u{110d0}', '\u{110e8}', IdentifierType::Exclusion), ('\u{110f0}', '\u{110f9}', IdentifierType::Exclusion), ('\u{11100}', '\u{11134}', IdentifierType::Limited_Use), ('\u{11136}', '\u{1113f}', IdentifierType::Limited_Use), @@ -1365,45 +1407,47 @@ pub mod identifier { IdentifierType::Not_XID), ('\u{11200}', '\u{11211}', IdentifierType::Exclusion), ('\u{11213}', '\u{11237}', IdentifierType::Exclusion), ('\u{11238}', '\u{1123d}', IdentifierType::Exclusion), ('\u{1123e}', '\u{1123e}', IdentifierType::Exclusion), - ('\u{11280}', '\u{11286}', IdentifierType::Exclusion), ('\u{11288}', '\u{11288}', - IdentifierType::Exclusion), ('\u{1128a}', '\u{1128d}', IdentifierType::Exclusion), - ('\u{1128f}', '\u{1129d}', IdentifierType::Exclusion), ('\u{1129f}', '\u{112a8}', - IdentifierType::Exclusion), ('\u{112a9}', '\u{112a9}', IdentifierType::Exclusion), - ('\u{112b0}', '\u{112ea}', IdentifierType::Exclusion), ('\u{112f0}', '\u{112f9}', - IdentifierType::Exclusion), ('\u{11300}', '\u{11300}', IdentifierType::Exclusion), - ('\u{11301}', '\u{11301}', IdentifierType::Recommended), ('\u{11302}', '\u{11302}', - IdentifierType::Exclusion), ('\u{11303}', '\u{11303}', IdentifierType::Recommended), - ('\u{11305}', '\u{1130c}', IdentifierType::Exclusion), ('\u{1130f}', '\u{11310}', - IdentifierType::Exclusion), ('\u{11313}', '\u{11328}', IdentifierType::Exclusion), - ('\u{1132a}', '\u{11330}', IdentifierType::Exclusion), ('\u{11332}', '\u{11333}', - IdentifierType::Exclusion), ('\u{11335}', '\u{11339}', IdentifierType::Exclusion), - ('\u{1133b}', '\u{1133b}', IdentifierType::Recommended), ('\u{1133c}', '\u{1133c}', - IdentifierType::Recommended), ('\u{1133d}', '\u{11344}', IdentifierType::Exclusion), - ('\u{11347}', '\u{11348}', IdentifierType::Exclusion), ('\u{1134b}', '\u{1134d}', - IdentifierType::Exclusion), ('\u{11350}', '\u{11350}', IdentifierType::Exclusion), - ('\u{11357}', '\u{11357}', IdentifierType::Exclusion), ('\u{1135d}', '\u{11363}', - IdentifierType::Exclusion), ('\u{11366}', '\u{1136c}', IdentifierType::Exclusion), - ('\u{11370}', '\u{11374}', IdentifierType::Exclusion), ('\u{11400}', '\u{1144a}', - IdentifierType::Limited_Use), ('\u{1144b}', '\u{1144f}', IdentifierType::Limited_Use), - ('\u{11450}', '\u{11459}', IdentifierType::Limited_Use), ('\u{1145a}', '\u{1145a}', - IdentifierType::Limited_Use), ('\u{1145b}', '\u{1145b}', IdentifierType::Limited_Use), - ('\u{1145d}', '\u{1145d}', IdentifierType::Limited_Use), ('\u{1145e}', '\u{1145e}', - IdentifierType::Limited_Use), ('\u{1145f}', '\u{1145f}', IdentifierType::Limited_Use), - ('\u{11460}', '\u{11461}', IdentifierType::Limited_Use), ('\u{11480}', '\u{114c5}', - IdentifierType::Exclusion), ('\u{114c6}', '\u{114c6}', IdentifierType::Exclusion), - ('\u{114c7}', '\u{114c7}', IdentifierType::Exclusion), ('\u{114d0}', '\u{114d9}', - IdentifierType::Exclusion), ('\u{11580}', '\u{115b5}', IdentifierType::Exclusion), - ('\u{115b8}', '\u{115c0}', IdentifierType::Exclusion), ('\u{115c1}', '\u{115c9}', - IdentifierType::Exclusion), ('\u{115ca}', '\u{115d7}', IdentifierType::Exclusion), - ('\u{115d8}', '\u{115dd}', IdentifierType::Exclusion), ('\u{11600}', '\u{11640}', - IdentifierType::Exclusion), ('\u{11641}', '\u{11643}', IdentifierType::Exclusion), - ('\u{11644}', '\u{11644}', IdentifierType::Exclusion), ('\u{11650}', '\u{11659}', - IdentifierType::Exclusion), ('\u{11660}', '\u{1166c}', IdentifierType::Exclusion), - ('\u{11680}', '\u{116b7}', IdentifierType::Exclusion), ('\u{116b8}', '\u{116b8}', - IdentifierType::Exclusion), ('\u{116c0}', '\u{116c9}', IdentifierType::Exclusion), - ('\u{11700}', '\u{11719}', IdentifierType::Exclusion), ('\u{1171a}', '\u{1171a}', - IdentifierType::Exclusion), ('\u{1171d}', '\u{1172b}', IdentifierType::Exclusion), - ('\u{11730}', '\u{11739}', IdentifierType::Exclusion), ('\u{1173a}', '\u{1173f}', + ('\u{1123f}', '\u{11241}', IdentifierType::Exclusion), ('\u{11280}', '\u{11286}', + IdentifierType::Exclusion), ('\u{11288}', '\u{11288}', IdentifierType::Exclusion), + ('\u{1128a}', '\u{1128d}', IdentifierType::Exclusion), ('\u{1128f}', '\u{1129d}', + IdentifierType::Exclusion), ('\u{1129f}', '\u{112a8}', IdentifierType::Exclusion), + ('\u{112a9}', '\u{112a9}', IdentifierType::Exclusion), ('\u{112b0}', '\u{112ea}', + IdentifierType::Exclusion), ('\u{112f0}', '\u{112f9}', IdentifierType::Exclusion), + ('\u{11300}', '\u{11300}', IdentifierType::Exclusion), ('\u{11301}', '\u{11301}', + IdentifierType::Recommended), ('\u{11302}', '\u{11302}', IdentifierType::Exclusion), + ('\u{11303}', '\u{11303}', IdentifierType::Recommended), ('\u{11305}', '\u{1130c}', + IdentifierType::Exclusion), ('\u{1130f}', '\u{11310}', IdentifierType::Exclusion), + ('\u{11313}', '\u{11328}', IdentifierType::Exclusion), ('\u{1132a}', '\u{11330}', + IdentifierType::Exclusion), ('\u{11332}', '\u{11333}', IdentifierType::Exclusion), + ('\u{11335}', '\u{11339}', IdentifierType::Exclusion), ('\u{1133b}', '\u{1133b}', + IdentifierType::Recommended), ('\u{1133c}', '\u{1133c}', IdentifierType::Recommended), + ('\u{1133d}', '\u{11344}', IdentifierType::Exclusion), ('\u{11347}', '\u{11348}', + IdentifierType::Exclusion), ('\u{1134b}', '\u{1134d}', IdentifierType::Exclusion), + ('\u{11350}', '\u{11350}', IdentifierType::Exclusion), ('\u{11357}', '\u{11357}', + IdentifierType::Exclusion), ('\u{1135d}', '\u{11363}', IdentifierType::Exclusion), + ('\u{11366}', '\u{1136c}', IdentifierType::Exclusion), ('\u{11370}', '\u{11374}', + IdentifierType::Exclusion), ('\u{11400}', '\u{1144a}', IdentifierType::Limited_Use), + ('\u{1144b}', '\u{1144f}', IdentifierType::Limited_Use), ('\u{11450}', '\u{11459}', + IdentifierType::Limited_Use), ('\u{1145a}', '\u{1145a}', IdentifierType::Limited_Use), + ('\u{1145b}', '\u{1145b}', IdentifierType::Limited_Use), ('\u{1145d}', '\u{1145d}', + IdentifierType::Limited_Use), ('\u{1145e}', '\u{1145e}', IdentifierType::Limited_Use), + ('\u{1145f}', '\u{1145f}', IdentifierType::Limited_Use), ('\u{11460}', '\u{11461}', + IdentifierType::Limited_Use), ('\u{11480}', '\u{114c5}', IdentifierType::Exclusion), + ('\u{114c6}', '\u{114c6}', IdentifierType::Exclusion), ('\u{114c7}', '\u{114c7}', + IdentifierType::Exclusion), ('\u{114d0}', '\u{114d9}', IdentifierType::Exclusion), + ('\u{11580}', '\u{115b5}', IdentifierType::Exclusion), ('\u{115b8}', '\u{115c0}', + IdentifierType::Exclusion), ('\u{115c1}', '\u{115c9}', IdentifierType::Exclusion), + ('\u{115ca}', '\u{115d7}', IdentifierType::Exclusion), ('\u{115d8}', '\u{115dd}', + IdentifierType::Exclusion), ('\u{11600}', '\u{11640}', IdentifierType::Exclusion), + ('\u{11641}', '\u{11643}', IdentifierType::Exclusion), ('\u{11644}', '\u{11644}', + IdentifierType::Exclusion), ('\u{11650}', '\u{11659}', IdentifierType::Exclusion), + ('\u{11660}', '\u{1166c}', IdentifierType::Exclusion), ('\u{11680}', '\u{116b7}', + IdentifierType::Exclusion), ('\u{116b8}', '\u{116b8}', IdentifierType::Exclusion), + ('\u{116b9}', '\u{116b9}', IdentifierType::Exclusion), ('\u{116c0}', '\u{116c9}', + IdentifierType::Exclusion), ('\u{11700}', '\u{11719}', IdentifierType::Exclusion), + ('\u{1171a}', '\u{1171a}', IdentifierType::Exclusion), ('\u{1171d}', '\u{1172b}', + IdentifierType::Exclusion), ('\u{11730}', '\u{11739}', IdentifierType::Exclusion), + ('\u{1173a}', '\u{1173f}', IdentifierType::Exclusion), ('\u{11740}', '\u{11746}', IdentifierType::Exclusion), ('\u{11800}', '\u{1183a}', IdentifierType::Exclusion), ('\u{1183b}', '\u{1183b}', IdentifierType::Exclusion), ('\u{118a0}', '\u{118e9}', IdentifierType::Exclusion), ('\u{118ea}', '\u{118f2}', IdentifierType::Exclusion), @@ -1423,255 +1467,283 @@ pub mod identifier { IdentifierType::Exclusion), ('\u{11a86}', '\u{11a99}', IdentifierType::Exclusion), ('\u{11a9a}', '\u{11a9c}', IdentifierType::Exclusion), ('\u{11a9d}', '\u{11a9d}', IdentifierType::Exclusion), ('\u{11a9e}', '\u{11aa2}', IdentifierType::Exclusion), - ('\u{11ac0}', '\u{11af8}', IdentifierType::Exclusion), ('\u{11c00}', '\u{11c08}', - IdentifierType::Exclusion), ('\u{11c0a}', '\u{11c36}', IdentifierType::Exclusion), - ('\u{11c38}', '\u{11c40}', IdentifierType::Exclusion), ('\u{11c41}', '\u{11c45}', - IdentifierType::Exclusion), ('\u{11c50}', '\u{11c59}', IdentifierType::Exclusion), - ('\u{11c5a}', '\u{11c6c}', IdentifierType::Exclusion), ('\u{11c70}', '\u{11c71}', - IdentifierType::Exclusion), ('\u{11c72}', '\u{11c8f}', IdentifierType::Exclusion), - ('\u{11c92}', '\u{11ca7}', IdentifierType::Exclusion), ('\u{11ca9}', '\u{11cb6}', - IdentifierType::Exclusion), ('\u{11d00}', '\u{11d06}', IdentifierType::Exclusion), - ('\u{11d08}', '\u{11d09}', IdentifierType::Exclusion), ('\u{11d0b}', '\u{11d36}', - IdentifierType::Exclusion), ('\u{11d3a}', '\u{11d3a}', IdentifierType::Exclusion), - ('\u{11d3c}', '\u{11d3d}', IdentifierType::Exclusion), ('\u{11d3f}', '\u{11d47}', - IdentifierType::Exclusion), ('\u{11d50}', '\u{11d59}', IdentifierType::Exclusion), - ('\u{11d60}', '\u{11d65}', IdentifierType::Limited_Use), ('\u{11d67}', '\u{11d68}', - IdentifierType::Limited_Use), ('\u{11d6a}', '\u{11d8e}', IdentifierType::Limited_Use), - ('\u{11d90}', '\u{11d91}', IdentifierType::Limited_Use), ('\u{11d93}', '\u{11d98}', - IdentifierType::Limited_Use), ('\u{11da0}', '\u{11da9}', IdentifierType::Limited_Use), - ('\u{11ee0}', '\u{11ef6}', IdentifierType::Exclusion), ('\u{11ef7}', '\u{11ef8}', - IdentifierType::Exclusion), ('\u{11fb0}', '\u{11fb0}', IdentifierType::Limited_Use), - ('\u{11fc0}', '\u{11ff1}', IdentifierType::Not_XID), ('\u{11fff}', '\u{11fff}', - IdentifierType::Not_XID), ('\u{12000}', '\u{1236e}', IdentifierType::Exclusion), - ('\u{1236f}', '\u{12398}', IdentifierType::Exclusion), ('\u{12399}', '\u{12399}', - IdentifierType::Exclusion), ('\u{12400}', '\u{12462}', IdentifierType::Exclusion), - ('\u{12463}', '\u{1246e}', IdentifierType::Exclusion), ('\u{12470}', '\u{12473}', - IdentifierType::Exclusion), ('\u{12474}', '\u{12474}', IdentifierType::Exclusion), - ('\u{12480}', '\u{12543}', IdentifierType::Exclusion), ('\u{13000}', '\u{1342e}', - IdentifierType::Exclusion), ('\u{13430}', '\u{13438}', IdentifierType::Exclusion), + ('\u{11ab0}', '\u{11abf}', IdentifierType::Limited_Use), ('\u{11ac0}', '\u{11af8}', + IdentifierType::Exclusion), ('\u{11b00}', '\u{11b09}', IdentifierType::Not_XID), + ('\u{11c00}', '\u{11c08}', IdentifierType::Exclusion), ('\u{11c0a}', '\u{11c36}', + IdentifierType::Exclusion), ('\u{11c38}', '\u{11c40}', IdentifierType::Exclusion), + ('\u{11c41}', '\u{11c45}', IdentifierType::Exclusion), ('\u{11c50}', '\u{11c59}', + IdentifierType::Exclusion), ('\u{11c5a}', '\u{11c6c}', IdentifierType::Exclusion), + ('\u{11c70}', '\u{11c71}', IdentifierType::Exclusion), ('\u{11c72}', '\u{11c8f}', + IdentifierType::Exclusion), ('\u{11c92}', '\u{11ca7}', IdentifierType::Exclusion), + ('\u{11ca9}', '\u{11cb6}', IdentifierType::Exclusion), ('\u{11d00}', '\u{11d06}', + IdentifierType::Exclusion), ('\u{11d08}', '\u{11d09}', IdentifierType::Exclusion), + ('\u{11d0b}', '\u{11d36}', IdentifierType::Exclusion), ('\u{11d3a}', '\u{11d3a}', + IdentifierType::Exclusion), ('\u{11d3c}', '\u{11d3d}', IdentifierType::Exclusion), + ('\u{11d3f}', '\u{11d47}', IdentifierType::Exclusion), ('\u{11d50}', '\u{11d59}', + IdentifierType::Exclusion), ('\u{11d60}', '\u{11d65}', IdentifierType::Limited_Use), + ('\u{11d67}', '\u{11d68}', IdentifierType::Limited_Use), ('\u{11d6a}', '\u{11d8e}', + IdentifierType::Limited_Use), ('\u{11d90}', '\u{11d91}', IdentifierType::Limited_Use), + ('\u{11d93}', '\u{11d98}', IdentifierType::Limited_Use), ('\u{11da0}', '\u{11da9}', + IdentifierType::Limited_Use), ('\u{11ee0}', '\u{11ef6}', IdentifierType::Exclusion), + ('\u{11ef7}', '\u{11ef8}', IdentifierType::Exclusion), ('\u{11f00}', '\u{11f10}', + IdentifierType::Exclusion), ('\u{11f12}', '\u{11f3a}', IdentifierType::Exclusion), + ('\u{11f3e}', '\u{11f42}', IdentifierType::Exclusion), ('\u{11f43}', '\u{11f4f}', + IdentifierType::Exclusion), ('\u{11f50}', '\u{11f59}', IdentifierType::Exclusion), + ('\u{11fb0}', '\u{11fb0}', IdentifierType::Limited_Use), ('\u{11fc0}', '\u{11ff1}', + IdentifierType::Not_XID), ('\u{11fff}', '\u{11fff}', IdentifierType::Not_XID), + ('\u{12000}', '\u{1236e}', IdentifierType::Exclusion), ('\u{1236f}', '\u{12398}', + IdentifierType::Exclusion), ('\u{12399}', '\u{12399}', IdentifierType::Exclusion), + ('\u{12400}', '\u{12462}', IdentifierType::Exclusion), ('\u{12463}', '\u{1246e}', + IdentifierType::Exclusion), ('\u{12470}', '\u{12473}', IdentifierType::Exclusion), + ('\u{12474}', '\u{12474}', IdentifierType::Exclusion), ('\u{12480}', '\u{12543}', + IdentifierType::Exclusion), ('\u{12f90}', '\u{12ff0}', IdentifierType::Exclusion), + ('\u{12ff1}', '\u{12ff2}', IdentifierType::Exclusion), ('\u{13000}', '\u{1342e}', + IdentifierType::Exclusion), ('\u{1342f}', '\u{1342f}', IdentifierType::Exclusion), + ('\u{13430}', '\u{13438}', IdentifierType::Exclusion), ('\u{13439}', '\u{1343f}', + IdentifierType::Exclusion), ('\u{13440}', '\u{13455}', IdentifierType::Exclusion), ('\u{14400}', '\u{14646}', IdentifierType::Exclusion), ('\u{16800}', '\u{16a38}', IdentifierType::Limited_Use), ('\u{16a40}', '\u{16a5e}', IdentifierType::Uncommon_Use), ('\u{16a60}', '\u{16a69}', IdentifierType::Uncommon_Use), ('\u{16a6e}', '\u{16a6f}', - IdentifierType::Exclusion), ('\u{16ad0}', '\u{16aed}', IdentifierType::Exclusion), - ('\u{16af0}', '\u{16af4}', IdentifierType::Exclusion), ('\u{16af5}', '\u{16af5}', - IdentifierType::Exclusion), ('\u{16b00}', '\u{16b36}', IdentifierType::Exclusion), - ('\u{16b37}', '\u{16b3f}', IdentifierType::Exclusion), ('\u{16b40}', '\u{16b43}', - IdentifierType::Exclusion), ('\u{16b44}', '\u{16b45}', IdentifierType::Exclusion), - ('\u{16b50}', '\u{16b59}', IdentifierType::Exclusion), ('\u{16b5b}', '\u{16b61}', - IdentifierType::Exclusion), ('\u{16b63}', '\u{16b77}', IdentifierType::Exclusion), - ('\u{16b7d}', '\u{16b8f}', IdentifierType::Exclusion), ('\u{16e40}', '\u{16e7f}', - IdentifierType::Exclusion), ('\u{16e80}', '\u{16e9a}', IdentifierType::Exclusion), - ('\u{16f00}', '\u{16f44}', IdentifierType::Limited_Use), ('\u{16f45}', '\u{16f4a}', - IdentifierType::Limited_Use), ('\u{16f4f}', '\u{16f4f}', IdentifierType::Limited_Use), - ('\u{16f50}', '\u{16f7e}', IdentifierType::Limited_Use), ('\u{16f7f}', '\u{16f87}', - IdentifierType::Limited_Use), ('\u{16f8f}', '\u{16f9f}', IdentifierType::Limited_Use), - ('\u{16fe0}', '\u{16fe0}', IdentifierType::Exclusion), ('\u{16fe1}', '\u{16fe1}', - IdentifierType::Exclusion), ('\u{16fe2}', '\u{16fe2}', IdentifierType::Not_XID), - ('\u{16fe3}', '\u{16fe3}', IdentifierType::Obsolete), ('\u{16fe4}', '\u{16fe4}', - IdentifierType::Exclusion), ('\u{16ff0}', '\u{16ff1}', IdentifierType::Recommended), - ('\u{17000}', '\u{187ec}', IdentifierType::Exclusion), ('\u{187ed}', '\u{187f1}', - IdentifierType::Exclusion), ('\u{187f2}', '\u{187f7}', IdentifierType::Exclusion), - ('\u{18800}', '\u{18af2}', IdentifierType::Exclusion), ('\u{18af3}', '\u{18cd5}', - IdentifierType::Exclusion), ('\u{18d00}', '\u{18d08}', IdentifierType::Exclusion), - ('\u{1b000}', '\u{1b001}', IdentifierType::Obsolete), ('\u{1b002}', '\u{1b11e}', - IdentifierType::Obsolete), ('\u{1b150}', '\u{1b152}', IdentifierType::Recommended), - ('\u{1b164}', '\u{1b167}', IdentifierType::Recommended), ('\u{1b170}', '\u{1b2fb}', - IdentifierType::Exclusion), ('\u{1bc00}', '\u{1bc6a}', IdentifierType::Exclusion), - ('\u{1bc70}', '\u{1bc7c}', IdentifierType::Exclusion), ('\u{1bc80}', '\u{1bc88}', - IdentifierType::Exclusion), ('\u{1bc90}', '\u{1bc99}', IdentifierType::Exclusion), - ('\u{1bc9c}', '\u{1bc9c}', IdentifierType::Exclusion), ('\u{1bc9d}', '\u{1bc9e}', - IdentifierType::Exclusion), ('\u{1bc9f}', '\u{1bc9f}', IdentifierType::Exclusion), - ('\u{1bca0}', '\u{1bca3}', IdentifierType::Default_Ignorable), ('\u{1d000}', '\u{1d0f5}', - IdentifierType::Technical), ('\u{1d100}', '\u{1d126}', IdentifierType::Technical), - ('\u{1d129}', '\u{1d129}', IdentifierType::Technical), ('\u{1d12a}', '\u{1d15d}', - IdentifierType::Technical), ('\u{1d15e}', '\u{1d164}', IdentifierType::Not_NFKC), - ('\u{1d165}', '\u{1d169}', IdentifierType::Technical), ('\u{1d16a}', '\u{1d16c}', - IdentifierType::Technical), ('\u{1d16d}', '\u{1d172}', IdentifierType::Technical), - ('\u{1d173}', '\u{1d17a}', IdentifierType::Default_Ignorable), ('\u{1d17b}', '\u{1d182}', - IdentifierType::Technical), ('\u{1d183}', '\u{1d184}', IdentifierType::Technical), - ('\u{1d185}', '\u{1d18b}', IdentifierType::Technical), ('\u{1d18c}', '\u{1d1a9}', - IdentifierType::Technical), ('\u{1d1aa}', '\u{1d1ad}', IdentifierType::Technical), - ('\u{1d1ae}', '\u{1d1ba}', IdentifierType::Technical), ('\u{1d1bb}', '\u{1d1c0}', - IdentifierType::Not_NFKC), ('\u{1d1c1}', '\u{1d1dd}', IdentifierType::Technical), - ('\u{1d1de}', '\u{1d1e8}', IdentifierType::Uncommon_Use), ('\u{1d200}', '\u{1d241}', + IdentifierType::Exclusion), ('\u{16a70}', '\u{16abe}', IdentifierType::Exclusion), + ('\u{16ac0}', '\u{16ac9}', IdentifierType::Exclusion), ('\u{16ad0}', '\u{16aed}', + IdentifierType::Exclusion), ('\u{16af0}', '\u{16af4}', IdentifierType::Exclusion), + ('\u{16af5}', '\u{16af5}', IdentifierType::Exclusion), ('\u{16b00}', '\u{16b36}', + IdentifierType::Exclusion), ('\u{16b37}', '\u{16b3f}', IdentifierType::Exclusion), + ('\u{16b40}', '\u{16b43}', IdentifierType::Exclusion), ('\u{16b44}', '\u{16b45}', + IdentifierType::Exclusion), ('\u{16b50}', '\u{16b59}', IdentifierType::Exclusion), + ('\u{16b5b}', '\u{16b61}', IdentifierType::Exclusion), ('\u{16b63}', '\u{16b77}', + IdentifierType::Exclusion), ('\u{16b7d}', '\u{16b8f}', IdentifierType::Exclusion), + ('\u{16e40}', '\u{16e7f}', IdentifierType::Exclusion), ('\u{16e80}', '\u{16e9a}', + IdentifierType::Exclusion), ('\u{16f00}', '\u{16f44}', IdentifierType::Limited_Use), + ('\u{16f45}', '\u{16f4a}', IdentifierType::Limited_Use), ('\u{16f4f}', '\u{16f4f}', + IdentifierType::Limited_Use), ('\u{16f50}', '\u{16f7e}', IdentifierType::Limited_Use), + ('\u{16f7f}', '\u{16f87}', IdentifierType::Limited_Use), ('\u{16f8f}', '\u{16f9f}', + IdentifierType::Limited_Use), ('\u{16fe0}', '\u{16fe0}', IdentifierType::Exclusion), + ('\u{16fe1}', '\u{16fe1}', IdentifierType::Exclusion), ('\u{16fe2}', '\u{16fe2}', + IdentifierType::Not_XID), ('\u{16fe3}', '\u{16fe3}', IdentifierType::Obsolete), + ('\u{16fe4}', '\u{16fe4}', IdentifierType::Exclusion), ('\u{16ff0}', '\u{16ff1}', + IdentifierType::Recommended), ('\u{17000}', '\u{187ec}', IdentifierType::Exclusion), + ('\u{187ed}', '\u{187f1}', IdentifierType::Exclusion), ('\u{187f2}', '\u{187f7}', + IdentifierType::Exclusion), ('\u{18800}', '\u{18af2}', IdentifierType::Exclusion), + ('\u{18af3}', '\u{18cd5}', IdentifierType::Exclusion), ('\u{18d00}', '\u{18d08}', + IdentifierType::Exclusion), ('\u{1aff0}', '\u{1aff3}', IdentifierType::Uncommon_Use), + ('\u{1aff5}', '\u{1affb}', IdentifierType::Uncommon_Use), ('\u{1affd}', '\u{1affe}', + IdentifierType::Uncommon_Use), ('\u{1b000}', '\u{1b001}', IdentifierType::Obsolete), + ('\u{1b002}', '\u{1b11e}', IdentifierType::Obsolete), ('\u{1b11f}', '\u{1b122}', + IdentifierType::Recommended), ('\u{1b132}', '\u{1b132}', IdentifierType::Recommended), + ('\u{1b150}', '\u{1b152}', IdentifierType::Recommended), ('\u{1b155}', '\u{1b155}', + IdentifierType::Recommended), ('\u{1b164}', '\u{1b167}', IdentifierType::Recommended), + ('\u{1b170}', '\u{1b2fb}', IdentifierType::Exclusion), ('\u{1bc00}', '\u{1bc6a}', + IdentifierType::Exclusion), ('\u{1bc70}', '\u{1bc7c}', IdentifierType::Exclusion), + ('\u{1bc80}', '\u{1bc88}', IdentifierType::Exclusion), ('\u{1bc90}', '\u{1bc99}', + IdentifierType::Exclusion), ('\u{1bc9c}', '\u{1bc9c}', IdentifierType::Exclusion), + ('\u{1bc9d}', '\u{1bc9e}', IdentifierType::Exclusion), ('\u{1bc9f}', '\u{1bc9f}', + IdentifierType::Exclusion), ('\u{1bca0}', '\u{1bca3}', IdentifierType::Default_Ignorable), + ('\u{1cf00}', '\u{1cf2d}', IdentifierType::Technical), ('\u{1cf30}', '\u{1cf46}', + IdentifierType::Technical), ('\u{1cf50}', '\u{1cfc3}', IdentifierType::Technical), + ('\u{1d000}', '\u{1d0f5}', IdentifierType::Technical), ('\u{1d100}', '\u{1d126}', + IdentifierType::Technical), ('\u{1d129}', '\u{1d129}', IdentifierType::Technical), + ('\u{1d12a}', '\u{1d15d}', IdentifierType::Technical), ('\u{1d15e}', '\u{1d164}', + IdentifierType::Not_NFKC), ('\u{1d165}', '\u{1d169}', IdentifierType::Technical), + ('\u{1d16a}', '\u{1d16c}', IdentifierType::Technical), ('\u{1d16d}', '\u{1d172}', + IdentifierType::Technical), ('\u{1d173}', '\u{1d17a}', IdentifierType::Default_Ignorable), + ('\u{1d17b}', '\u{1d182}', IdentifierType::Technical), ('\u{1d183}', '\u{1d184}', + IdentifierType::Technical), ('\u{1d185}', '\u{1d18b}', IdentifierType::Technical), + ('\u{1d18c}', '\u{1d1a9}', IdentifierType::Technical), ('\u{1d1aa}', '\u{1d1ad}', + IdentifierType::Technical), ('\u{1d1ae}', '\u{1d1ba}', IdentifierType::Technical), + ('\u{1d1bb}', '\u{1d1c0}', IdentifierType::Not_NFKC), ('\u{1d1c1}', '\u{1d1dd}', + IdentifierType::Technical), ('\u{1d1de}', '\u{1d1e8}', IdentifierType::Uncommon_Use), + ('\u{1d1e9}', '\u{1d1ea}', IdentifierType::Technical), ('\u{1d200}', '\u{1d241}', IdentifierType::Obsolete), ('\u{1d242}', '\u{1d244}', IdentifierType::Technical), - ('\u{1d245}', '\u{1d245}', IdentifierType::Obsolete), ('\u{1d2e0}', '\u{1d2f3}', - IdentifierType::Not_XID), ('\u{1d300}', '\u{1d356}', IdentifierType::Technical), - ('\u{1d360}', '\u{1d371}', IdentifierType::Not_XID), ('\u{1d372}', '\u{1d378}', - IdentifierType::Not_XID), ('\u{1d400}', '\u{1d454}', IdentifierType::Not_NFKC), - ('\u{1d456}', '\u{1d49c}', IdentifierType::Not_NFKC), ('\u{1d49e}', '\u{1d49f}', - IdentifierType::Not_NFKC), ('\u{1d4a2}', '\u{1d4a2}', IdentifierType::Not_NFKC), - ('\u{1d4a5}', '\u{1d4a6}', IdentifierType::Not_NFKC), ('\u{1d4a9}', '\u{1d4ac}', - IdentifierType::Not_NFKC), ('\u{1d4ae}', '\u{1d4b9}', IdentifierType::Not_NFKC), - ('\u{1d4bb}', '\u{1d4bb}', IdentifierType::Not_NFKC), ('\u{1d4bd}', '\u{1d4c0}', - IdentifierType::Not_NFKC), ('\u{1d4c1}', '\u{1d4c1}', IdentifierType::Not_NFKC), - ('\u{1d4c2}', '\u{1d4c3}', IdentifierType::Not_NFKC), ('\u{1d4c5}', '\u{1d505}', - IdentifierType::Not_NFKC), ('\u{1d507}', '\u{1d50a}', IdentifierType::Not_NFKC), - ('\u{1d50d}', '\u{1d514}', IdentifierType::Not_NFKC), ('\u{1d516}', '\u{1d51c}', - IdentifierType::Not_NFKC), ('\u{1d51e}', '\u{1d539}', IdentifierType::Not_NFKC), - ('\u{1d53b}', '\u{1d53e}', IdentifierType::Not_NFKC), ('\u{1d540}', '\u{1d544}', - IdentifierType::Not_NFKC), ('\u{1d546}', '\u{1d546}', IdentifierType::Not_NFKC), - ('\u{1d54a}', '\u{1d550}', IdentifierType::Not_NFKC), ('\u{1d552}', '\u{1d6a3}', - IdentifierType::Not_NFKC), ('\u{1d6a4}', '\u{1d6a5}', IdentifierType::Not_NFKC), - ('\u{1d6a8}', '\u{1d7c9}', IdentifierType::Not_NFKC), ('\u{1d7ca}', '\u{1d7cb}', - IdentifierType::Not_NFKC), ('\u{1d7ce}', '\u{1d7ff}', IdentifierType::Not_NFKC), - ('\u{1d800}', '\u{1d9ff}', IdentifierType::Exclusion), ('\u{1da00}', '\u{1da36}', - IdentifierType::Exclusion), ('\u{1da37}', '\u{1da3a}', IdentifierType::Exclusion), - ('\u{1da3b}', '\u{1da6c}', IdentifierType::Exclusion), ('\u{1da6d}', '\u{1da74}', - IdentifierType::Exclusion), ('\u{1da75}', '\u{1da75}', IdentifierType::Exclusion), - ('\u{1da76}', '\u{1da83}', IdentifierType::Exclusion), ('\u{1da84}', '\u{1da84}', - IdentifierType::Exclusion), ('\u{1da85}', '\u{1da8b}', IdentifierType::Exclusion), - ('\u{1da9b}', '\u{1da9f}', IdentifierType::Exclusion), ('\u{1daa1}', '\u{1daaf}', - IdentifierType::Exclusion), ('\u{1e000}', '\u{1e006}', IdentifierType::Exclusion), + ('\u{1d245}', '\u{1d245}', IdentifierType::Obsolete), ('\u{1d2c0}', '\u{1d2d3}', + IdentifierType::Not_XID), ('\u{1d2e0}', '\u{1d2f3}', IdentifierType::Not_XID), + ('\u{1d300}', '\u{1d356}', IdentifierType::Technical), ('\u{1d360}', '\u{1d371}', + IdentifierType::Not_XID), ('\u{1d372}', '\u{1d378}', IdentifierType::Not_XID), + ('\u{1d400}', '\u{1d454}', IdentifierType::Not_NFKC), ('\u{1d456}', '\u{1d49c}', + IdentifierType::Not_NFKC), ('\u{1d49e}', '\u{1d49f}', IdentifierType::Not_NFKC), + ('\u{1d4a2}', '\u{1d4a2}', IdentifierType::Not_NFKC), ('\u{1d4a5}', '\u{1d4a6}', + IdentifierType::Not_NFKC), ('\u{1d4a9}', '\u{1d4ac}', IdentifierType::Not_NFKC), + ('\u{1d4ae}', '\u{1d4b9}', IdentifierType::Not_NFKC), ('\u{1d4bb}', '\u{1d4bb}', + IdentifierType::Not_NFKC), ('\u{1d4bd}', '\u{1d4c0}', IdentifierType::Not_NFKC), + ('\u{1d4c1}', '\u{1d4c1}', IdentifierType::Not_NFKC), ('\u{1d4c2}', '\u{1d4c3}', + IdentifierType::Not_NFKC), ('\u{1d4c5}', '\u{1d505}', IdentifierType::Not_NFKC), + ('\u{1d507}', '\u{1d50a}', IdentifierType::Not_NFKC), ('\u{1d50d}', '\u{1d514}', + IdentifierType::Not_NFKC), ('\u{1d516}', '\u{1d51c}', IdentifierType::Not_NFKC), + ('\u{1d51e}', '\u{1d539}', IdentifierType::Not_NFKC), ('\u{1d53b}', '\u{1d53e}', + IdentifierType::Not_NFKC), ('\u{1d540}', '\u{1d544}', IdentifierType::Not_NFKC), + ('\u{1d546}', '\u{1d546}', IdentifierType::Not_NFKC), ('\u{1d54a}', '\u{1d550}', + IdentifierType::Not_NFKC), ('\u{1d552}', '\u{1d6a3}', IdentifierType::Not_NFKC), + ('\u{1d6a4}', '\u{1d6a5}', IdentifierType::Not_NFKC), ('\u{1d6a8}', '\u{1d7c9}', + IdentifierType::Not_NFKC), ('\u{1d7ca}', '\u{1d7cb}', IdentifierType::Not_NFKC), + ('\u{1d7ce}', '\u{1d7ff}', IdentifierType::Not_NFKC), ('\u{1d800}', '\u{1d9ff}', + IdentifierType::Exclusion), ('\u{1da00}', '\u{1da36}', IdentifierType::Exclusion), + ('\u{1da37}', '\u{1da3a}', IdentifierType::Exclusion), ('\u{1da3b}', '\u{1da6c}', + IdentifierType::Exclusion), ('\u{1da6d}', '\u{1da74}', IdentifierType::Exclusion), + ('\u{1da75}', '\u{1da75}', IdentifierType::Exclusion), ('\u{1da76}', '\u{1da83}', + IdentifierType::Exclusion), ('\u{1da84}', '\u{1da84}', IdentifierType::Exclusion), + ('\u{1da85}', '\u{1da8b}', IdentifierType::Exclusion), ('\u{1da9b}', '\u{1da9f}', + IdentifierType::Exclusion), ('\u{1daa1}', '\u{1daaf}', IdentifierType::Exclusion), + ('\u{1df00}', '\u{1df1e}', IdentifierType::Recommended), ('\u{1df25}', '\u{1df2a}', + IdentifierType::Recommended), ('\u{1e000}', '\u{1e006}', IdentifierType::Exclusion), ('\u{1e008}', '\u{1e018}', IdentifierType::Exclusion), ('\u{1e01b}', '\u{1e021}', IdentifierType::Exclusion), ('\u{1e023}', '\u{1e024}', IdentifierType::Exclusion), - ('\u{1e026}', '\u{1e02a}', IdentifierType::Exclusion), ('\u{1e100}', '\u{1e12c}', - IdentifierType::Limited_Use), ('\u{1e130}', '\u{1e13d}', IdentifierType::Limited_Use), - ('\u{1e140}', '\u{1e149}', IdentifierType::Limited_Use), ('\u{1e14e}', '\u{1e14e}', - IdentifierType::Limited_Use), ('\u{1e14f}', '\u{1e14f}', IdentifierType::Limited_Use), + ('\u{1e026}', '\u{1e02a}', IdentifierType::Exclusion), ('\u{1e030}', '\u{1e06d}', + IdentifierType::Not_NFKC), ('\u{1e08f}', '\u{1e08f}', IdentifierType::Recommended), + ('\u{1e100}', '\u{1e12c}', IdentifierType::Limited_Use), ('\u{1e130}', '\u{1e13d}', + IdentifierType::Limited_Use), ('\u{1e140}', '\u{1e149}', IdentifierType::Limited_Use), + ('\u{1e14e}', '\u{1e14e}', IdentifierType::Limited_Use), ('\u{1e14f}', '\u{1e14f}', + IdentifierType::Limited_Use), ('\u{1e290}', '\u{1e2ae}', IdentifierType::Exclusion), ('\u{1e2c0}', '\u{1e2f9}', IdentifierType::Limited_Use), ('\u{1e2ff}', '\u{1e2ff}', - IdentifierType::Limited_Use), ('\u{1e800}', '\u{1e8c4}', IdentifierType::Exclusion), - ('\u{1e8c7}', '\u{1e8cf}', IdentifierType::Exclusion), ('\u{1e8d0}', '\u{1e8d6}', - IdentifierType::Exclusion), ('\u{1e900}', '\u{1e94a}', IdentifierType::Limited_Use), - ('\u{1e94b}', '\u{1e94b}', IdentifierType::Limited_Use), ('\u{1e950}', '\u{1e959}', - IdentifierType::Limited_Use), ('\u{1e95e}', '\u{1e95f}', IdentifierType::Limited_Use), - ('\u{1ec71}', '\u{1ecb4}', IdentifierType::Not_XID), ('\u{1ed01}', '\u{1ed3d}', - IdentifierType::Not_XID), ('\u{1ee00}', '\u{1ee03}', IdentifierType::Not_NFKC), - ('\u{1ee05}', '\u{1ee1f}', IdentifierType::Not_NFKC), ('\u{1ee21}', '\u{1ee22}', - IdentifierType::Not_NFKC), ('\u{1ee24}', '\u{1ee24}', IdentifierType::Not_NFKC), - ('\u{1ee27}', '\u{1ee27}', IdentifierType::Not_NFKC), ('\u{1ee29}', '\u{1ee32}', - IdentifierType::Not_NFKC), ('\u{1ee34}', '\u{1ee37}', IdentifierType::Not_NFKC), - ('\u{1ee39}', '\u{1ee39}', IdentifierType::Not_NFKC), ('\u{1ee3b}', '\u{1ee3b}', - IdentifierType::Not_NFKC), ('\u{1ee42}', '\u{1ee42}', IdentifierType::Not_NFKC), - ('\u{1ee47}', '\u{1ee47}', IdentifierType::Not_NFKC), ('\u{1ee49}', '\u{1ee49}', - IdentifierType::Not_NFKC), ('\u{1ee4b}', '\u{1ee4b}', IdentifierType::Not_NFKC), - ('\u{1ee4d}', '\u{1ee4f}', IdentifierType::Not_NFKC), ('\u{1ee51}', '\u{1ee52}', - IdentifierType::Not_NFKC), ('\u{1ee54}', '\u{1ee54}', IdentifierType::Not_NFKC), - ('\u{1ee57}', '\u{1ee57}', IdentifierType::Not_NFKC), ('\u{1ee59}', '\u{1ee59}', - IdentifierType::Not_NFKC), ('\u{1ee5b}', '\u{1ee5b}', IdentifierType::Not_NFKC), - ('\u{1ee5d}', '\u{1ee5d}', IdentifierType::Not_NFKC), ('\u{1ee5f}', '\u{1ee5f}', - IdentifierType::Not_NFKC), ('\u{1ee61}', '\u{1ee62}', IdentifierType::Not_NFKC), - ('\u{1ee64}', '\u{1ee64}', IdentifierType::Not_NFKC), ('\u{1ee67}', '\u{1ee6a}', - IdentifierType::Not_NFKC), ('\u{1ee6c}', '\u{1ee72}', IdentifierType::Not_NFKC), - ('\u{1ee74}', '\u{1ee77}', IdentifierType::Not_NFKC), ('\u{1ee79}', '\u{1ee7c}', - IdentifierType::Not_NFKC), ('\u{1ee7e}', '\u{1ee7e}', IdentifierType::Not_NFKC), - ('\u{1ee80}', '\u{1ee89}', IdentifierType::Not_NFKC), ('\u{1ee8b}', '\u{1ee9b}', - IdentifierType::Not_NFKC), ('\u{1eea1}', '\u{1eea3}', IdentifierType::Not_NFKC), - ('\u{1eea5}', '\u{1eea9}', IdentifierType::Not_NFKC), ('\u{1eeab}', '\u{1eebb}', - IdentifierType::Not_NFKC), ('\u{1eef0}', '\u{1eef1}', IdentifierType::Not_XID), - ('\u{1f000}', '\u{1f02b}', IdentifierType::Not_XID), ('\u{1f030}', '\u{1f093}', - IdentifierType::Not_XID), ('\u{1f0a0}', '\u{1f0ae}', IdentifierType::Not_XID), - ('\u{1f0b1}', '\u{1f0be}', IdentifierType::Not_XID), ('\u{1f0bf}', '\u{1f0bf}', - IdentifierType::Not_XID), ('\u{1f0c1}', '\u{1f0cf}', IdentifierType::Not_XID), - ('\u{1f0d1}', '\u{1f0df}', IdentifierType::Not_XID), ('\u{1f0e0}', '\u{1f0f5}', - IdentifierType::Not_XID), ('\u{1f100}', '\u{1f10a}', IdentifierType::Not_NFKC), - ('\u{1f10b}', '\u{1f10c}', IdentifierType::Not_XID), ('\u{1f10d}', '\u{1f10f}', - IdentifierType::Not_XID), ('\u{1f110}', '\u{1f12e}', IdentifierType::Not_NFKC), - ('\u{1f12f}', '\u{1f12f}', IdentifierType::Not_XID), ('\u{1f130}', '\u{1f130}', - IdentifierType::Not_NFKC), ('\u{1f131}', '\u{1f131}', IdentifierType::Not_NFKC), - ('\u{1f132}', '\u{1f13c}', IdentifierType::Not_NFKC), ('\u{1f13d}', '\u{1f13d}', - IdentifierType::Not_NFKC), ('\u{1f13e}', '\u{1f13e}', IdentifierType::Not_NFKC), - ('\u{1f13f}', '\u{1f13f}', IdentifierType::Not_NFKC), ('\u{1f140}', '\u{1f141}', - IdentifierType::Not_NFKC), ('\u{1f142}', '\u{1f142}', IdentifierType::Not_NFKC), - ('\u{1f143}', '\u{1f145}', IdentifierType::Not_NFKC), ('\u{1f146}', '\u{1f146}', - IdentifierType::Not_NFKC), ('\u{1f147}', '\u{1f149}', IdentifierType::Not_NFKC), - ('\u{1f14a}', '\u{1f14e}', IdentifierType::Not_NFKC), ('\u{1f14f}', '\u{1f14f}', - IdentifierType::Not_NFKC), ('\u{1f150}', '\u{1f156}', IdentifierType::Not_XID), - ('\u{1f157}', '\u{1f157}', IdentifierType::Not_XID), ('\u{1f158}', '\u{1f15e}', - IdentifierType::Not_XID), ('\u{1f15f}', '\u{1f15f}', IdentifierType::Not_XID), - ('\u{1f160}', '\u{1f169}', IdentifierType::Not_XID), ('\u{1f16a}', '\u{1f16b}', - IdentifierType::Not_NFKC), ('\u{1f16c}', '\u{1f16c}', IdentifierType::Not_NFKC), - ('\u{1f16d}', '\u{1f16f}', IdentifierType::Not_XID), ('\u{1f170}', '\u{1f178}', - IdentifierType::Not_XID), ('\u{1f179}', '\u{1f179}', IdentifierType::Not_XID), - ('\u{1f17a}', '\u{1f17a}', IdentifierType::Not_XID), ('\u{1f17b}', '\u{1f17c}', - IdentifierType::Not_XID), ('\u{1f17d}', '\u{1f17e}', IdentifierType::Not_XID), - ('\u{1f17f}', '\u{1f17f}', IdentifierType::Not_XID), ('\u{1f180}', '\u{1f189}', - IdentifierType::Not_XID), ('\u{1f18a}', '\u{1f18d}', IdentifierType::Not_XID), - ('\u{1f18e}', '\u{1f18f}', IdentifierType::Not_XID), ('\u{1f190}', '\u{1f190}', - IdentifierType::Not_NFKC), ('\u{1f191}', '\u{1f19a}', IdentifierType::Not_XID), - ('\u{1f19b}', '\u{1f1ac}', IdentifierType::Not_XID), ('\u{1f1ad}', '\u{1f1ad}', - IdentifierType::Not_XID), ('\u{1f1e6}', '\u{1f1ff}', IdentifierType::Not_XID), - ('\u{1f200}', '\u{1f200}', IdentifierType::Not_NFKC), ('\u{1f201}', '\u{1f202}', - IdentifierType::Not_NFKC), ('\u{1f210}', '\u{1f231}', IdentifierType::Not_NFKC), - ('\u{1f232}', '\u{1f23a}', IdentifierType::Not_NFKC), ('\u{1f23b}', '\u{1f23b}', - IdentifierType::Not_NFKC), ('\u{1f240}', '\u{1f248}', IdentifierType::Not_NFKC), - ('\u{1f250}', '\u{1f251}', IdentifierType::Not_NFKC), ('\u{1f260}', '\u{1f265}', - IdentifierType::Not_XID), ('\u{1f300}', '\u{1f320}', IdentifierType::Not_XID), - ('\u{1f321}', '\u{1f32c}', IdentifierType::Not_XID), ('\u{1f32d}', '\u{1f32f}', - IdentifierType::Not_XID), ('\u{1f330}', '\u{1f335}', IdentifierType::Not_XID), - ('\u{1f336}', '\u{1f336}', IdentifierType::Not_XID), ('\u{1f337}', '\u{1f37c}', - IdentifierType::Not_XID), ('\u{1f37d}', '\u{1f37d}', IdentifierType::Not_XID), - ('\u{1f37e}', '\u{1f37f}', IdentifierType::Not_XID), ('\u{1f380}', '\u{1f393}', - IdentifierType::Not_XID), ('\u{1f394}', '\u{1f39f}', IdentifierType::Not_XID), - ('\u{1f3a0}', '\u{1f3c4}', IdentifierType::Not_XID), ('\u{1f3c5}', '\u{1f3c5}', - IdentifierType::Not_XID), ('\u{1f3c6}', '\u{1f3ca}', IdentifierType::Not_XID), - ('\u{1f3cb}', '\u{1f3ce}', IdentifierType::Not_XID), ('\u{1f3cf}', '\u{1f3d3}', - IdentifierType::Not_XID), ('\u{1f3d4}', '\u{1f3df}', IdentifierType::Not_XID), - ('\u{1f3e0}', '\u{1f3f0}', IdentifierType::Not_XID), ('\u{1f3f1}', '\u{1f3f7}', - IdentifierType::Not_XID), ('\u{1f3f8}', '\u{1f3ff}', IdentifierType::Not_XID), - ('\u{1f400}', '\u{1f43e}', IdentifierType::Not_XID), ('\u{1f43f}', '\u{1f43f}', - IdentifierType::Not_XID), ('\u{1f440}', '\u{1f440}', IdentifierType::Not_XID), - ('\u{1f441}', '\u{1f441}', IdentifierType::Not_XID), ('\u{1f442}', '\u{1f4f7}', - IdentifierType::Not_XID), ('\u{1f4f8}', '\u{1f4f8}', IdentifierType::Not_XID), - ('\u{1f4f9}', '\u{1f4fc}', IdentifierType::Not_XID), ('\u{1f4fd}', '\u{1f4fe}', - IdentifierType::Not_XID), ('\u{1f4ff}', '\u{1f4ff}', IdentifierType::Not_XID), - ('\u{1f500}', '\u{1f53d}', IdentifierType::Not_XID), ('\u{1f53e}', '\u{1f53f}', - IdentifierType::Not_XID), ('\u{1f540}', '\u{1f543}', IdentifierType::Not_XID), - ('\u{1f544}', '\u{1f54a}', IdentifierType::Not_XID), ('\u{1f54b}', '\u{1f54e}', - IdentifierType::Not_XID), ('\u{1f54f}', '\u{1f54f}', IdentifierType::Uncommon_Use), - ('\u{1f550}', '\u{1f567}', IdentifierType::Not_XID), ('\u{1f568}', '\u{1f579}', - IdentifierType::Not_XID), ('\u{1f57a}', '\u{1f57a}', IdentifierType::Not_XID), - ('\u{1f57b}', '\u{1f5a3}', IdentifierType::Not_XID), ('\u{1f5a4}', '\u{1f5a4}', - IdentifierType::Not_XID), ('\u{1f5a5}', '\u{1f5fa}', IdentifierType::Not_XID), - ('\u{1f5fb}', '\u{1f5ff}', IdentifierType::Not_XID), ('\u{1f600}', '\u{1f600}', - IdentifierType::Not_XID), ('\u{1f601}', '\u{1f610}', IdentifierType::Not_XID), - ('\u{1f611}', '\u{1f611}', IdentifierType::Not_XID), ('\u{1f612}', '\u{1f614}', - IdentifierType::Not_XID), ('\u{1f615}', '\u{1f615}', IdentifierType::Not_XID), - ('\u{1f616}', '\u{1f616}', IdentifierType::Not_XID), ('\u{1f617}', '\u{1f617}', - IdentifierType::Not_XID), ('\u{1f618}', '\u{1f618}', IdentifierType::Not_XID), - ('\u{1f619}', '\u{1f619}', IdentifierType::Not_XID), ('\u{1f61a}', '\u{1f61a}', - IdentifierType::Not_XID), ('\u{1f61b}', '\u{1f61b}', IdentifierType::Not_XID), - ('\u{1f61c}', '\u{1f61e}', IdentifierType::Not_XID), ('\u{1f61f}', '\u{1f61f}', - IdentifierType::Not_XID), ('\u{1f620}', '\u{1f625}', IdentifierType::Not_XID), - ('\u{1f626}', '\u{1f627}', IdentifierType::Not_XID), ('\u{1f628}', '\u{1f62b}', - IdentifierType::Not_XID), ('\u{1f62c}', '\u{1f62c}', IdentifierType::Not_XID), - ('\u{1f62d}', '\u{1f62d}', IdentifierType::Not_XID), ('\u{1f62e}', '\u{1f62f}', - IdentifierType::Not_XID), ('\u{1f630}', '\u{1f633}', IdentifierType::Not_XID), - ('\u{1f634}', '\u{1f634}', IdentifierType::Not_XID), ('\u{1f635}', '\u{1f640}', - IdentifierType::Not_XID), ('\u{1f641}', '\u{1f642}', IdentifierType::Not_XID), - ('\u{1f643}', '\u{1f644}', IdentifierType::Not_XID), ('\u{1f645}', '\u{1f64f}', - IdentifierType::Not_XID), ('\u{1f650}', '\u{1f67f}', IdentifierType::Not_XID), - ('\u{1f680}', '\u{1f6c5}', IdentifierType::Not_XID), ('\u{1f6c6}', '\u{1f6cf}', - IdentifierType::Not_XID), ('\u{1f6d0}', '\u{1f6d0}', IdentifierType::Not_XID), - ('\u{1f6d1}', '\u{1f6d2}', IdentifierType::Not_XID), ('\u{1f6d3}', '\u{1f6d4}', - IdentifierType::Not_XID), ('\u{1f6d5}', '\u{1f6d5}', IdentifierType::Not_XID), - ('\u{1f6d6}', '\u{1f6d7}', IdentifierType::Not_XID), ('\u{1f6e0}', '\u{1f6ec}', - IdentifierType::Not_XID), ('\u{1f6f0}', '\u{1f6f3}', IdentifierType::Not_XID), - ('\u{1f6f4}', '\u{1f6f6}', IdentifierType::Not_XID), ('\u{1f6f7}', '\u{1f6f8}', - IdentifierType::Not_XID), ('\u{1f6f9}', '\u{1f6f9}', IdentifierType::Not_XID), - ('\u{1f6fa}', '\u{1f6fa}', IdentifierType::Not_XID), ('\u{1f6fb}', '\u{1f6fc}', - IdentifierType::Not_XID), ('\u{1f700}', '\u{1f773}', IdentifierType::Not_XID), + IdentifierType::Limited_Use), ('\u{1e4d0}', '\u{1e4f9}', IdentifierType::Exclusion), + ('\u{1e7e0}', '\u{1e7e6}', IdentifierType::Recommended), ('\u{1e7e8}', '\u{1e7eb}', + IdentifierType::Recommended), ('\u{1e7ed}', '\u{1e7ee}', IdentifierType::Recommended), + ('\u{1e7f0}', '\u{1e7fe}', IdentifierType::Recommended), ('\u{1e800}', '\u{1e8c4}', + IdentifierType::Exclusion), ('\u{1e8c7}', '\u{1e8cf}', IdentifierType::Exclusion), + ('\u{1e8d0}', '\u{1e8d6}', IdentifierType::Exclusion), ('\u{1e900}', '\u{1e94a}', + IdentifierType::Limited_Use), ('\u{1e94b}', '\u{1e94b}', IdentifierType::Limited_Use), + ('\u{1e950}', '\u{1e959}', IdentifierType::Limited_Use), ('\u{1e95e}', '\u{1e95f}', + IdentifierType::Limited_Use), ('\u{1ec71}', '\u{1ecb4}', IdentifierType::Not_XID), + ('\u{1ed01}', '\u{1ed3d}', IdentifierType::Not_XID), ('\u{1ee00}', '\u{1ee03}', + IdentifierType::Not_NFKC), ('\u{1ee05}', '\u{1ee1f}', IdentifierType::Not_NFKC), + ('\u{1ee21}', '\u{1ee22}', IdentifierType::Not_NFKC), ('\u{1ee24}', '\u{1ee24}', + IdentifierType::Not_NFKC), ('\u{1ee27}', '\u{1ee27}', IdentifierType::Not_NFKC), + ('\u{1ee29}', '\u{1ee32}', IdentifierType::Not_NFKC), ('\u{1ee34}', '\u{1ee37}', + IdentifierType::Not_NFKC), ('\u{1ee39}', '\u{1ee39}', IdentifierType::Not_NFKC), + ('\u{1ee3b}', '\u{1ee3b}', IdentifierType::Not_NFKC), ('\u{1ee42}', '\u{1ee42}', + IdentifierType::Not_NFKC), ('\u{1ee47}', '\u{1ee47}', IdentifierType::Not_NFKC), + ('\u{1ee49}', '\u{1ee49}', IdentifierType::Not_NFKC), ('\u{1ee4b}', '\u{1ee4b}', + IdentifierType::Not_NFKC), ('\u{1ee4d}', '\u{1ee4f}', IdentifierType::Not_NFKC), + ('\u{1ee51}', '\u{1ee52}', IdentifierType::Not_NFKC), ('\u{1ee54}', '\u{1ee54}', + IdentifierType::Not_NFKC), ('\u{1ee57}', '\u{1ee57}', IdentifierType::Not_NFKC), + ('\u{1ee59}', '\u{1ee59}', IdentifierType::Not_NFKC), ('\u{1ee5b}', '\u{1ee5b}', + IdentifierType::Not_NFKC), ('\u{1ee5d}', '\u{1ee5d}', IdentifierType::Not_NFKC), + ('\u{1ee5f}', '\u{1ee5f}', IdentifierType::Not_NFKC), ('\u{1ee61}', '\u{1ee62}', + IdentifierType::Not_NFKC), ('\u{1ee64}', '\u{1ee64}', IdentifierType::Not_NFKC), + ('\u{1ee67}', '\u{1ee6a}', IdentifierType::Not_NFKC), ('\u{1ee6c}', '\u{1ee72}', + IdentifierType::Not_NFKC), ('\u{1ee74}', '\u{1ee77}', IdentifierType::Not_NFKC), + ('\u{1ee79}', '\u{1ee7c}', IdentifierType::Not_NFKC), ('\u{1ee7e}', '\u{1ee7e}', + IdentifierType::Not_NFKC), ('\u{1ee80}', '\u{1ee89}', IdentifierType::Not_NFKC), + ('\u{1ee8b}', '\u{1ee9b}', IdentifierType::Not_NFKC), ('\u{1eea1}', '\u{1eea3}', + IdentifierType::Not_NFKC), ('\u{1eea5}', '\u{1eea9}', IdentifierType::Not_NFKC), + ('\u{1eeab}', '\u{1eebb}', IdentifierType::Not_NFKC), ('\u{1eef0}', '\u{1eef1}', + IdentifierType::Not_XID), ('\u{1f000}', '\u{1f02b}', IdentifierType::Not_XID), + ('\u{1f030}', '\u{1f093}', IdentifierType::Not_XID), ('\u{1f0a0}', '\u{1f0ae}', + IdentifierType::Not_XID), ('\u{1f0b1}', '\u{1f0be}', IdentifierType::Not_XID), + ('\u{1f0bf}', '\u{1f0bf}', IdentifierType::Not_XID), ('\u{1f0c1}', '\u{1f0cf}', + IdentifierType::Not_XID), ('\u{1f0d1}', '\u{1f0df}', IdentifierType::Not_XID), + ('\u{1f0e0}', '\u{1f0f5}', IdentifierType::Not_XID), ('\u{1f100}', '\u{1f10a}', + IdentifierType::Not_NFKC), ('\u{1f10b}', '\u{1f10c}', IdentifierType::Not_XID), + ('\u{1f10d}', '\u{1f10f}', IdentifierType::Not_XID), ('\u{1f110}', '\u{1f12e}', + IdentifierType::Not_NFKC), ('\u{1f12f}', '\u{1f12f}', IdentifierType::Not_XID), + ('\u{1f130}', '\u{1f130}', IdentifierType::Not_NFKC), ('\u{1f131}', '\u{1f131}', + IdentifierType::Not_NFKC), ('\u{1f132}', '\u{1f13c}', IdentifierType::Not_NFKC), + ('\u{1f13d}', '\u{1f13d}', IdentifierType::Not_NFKC), ('\u{1f13e}', '\u{1f13e}', + IdentifierType::Not_NFKC), ('\u{1f13f}', '\u{1f13f}', IdentifierType::Not_NFKC), + ('\u{1f140}', '\u{1f141}', IdentifierType::Not_NFKC), ('\u{1f142}', '\u{1f142}', + IdentifierType::Not_NFKC), ('\u{1f143}', '\u{1f145}', IdentifierType::Not_NFKC), + ('\u{1f146}', '\u{1f146}', IdentifierType::Not_NFKC), ('\u{1f147}', '\u{1f149}', + IdentifierType::Not_NFKC), ('\u{1f14a}', '\u{1f14e}', IdentifierType::Not_NFKC), + ('\u{1f14f}', '\u{1f14f}', IdentifierType::Not_NFKC), ('\u{1f150}', '\u{1f156}', + IdentifierType::Not_XID), ('\u{1f157}', '\u{1f157}', IdentifierType::Not_XID), + ('\u{1f158}', '\u{1f15e}', IdentifierType::Not_XID), ('\u{1f15f}', '\u{1f15f}', + IdentifierType::Not_XID), ('\u{1f160}', '\u{1f169}', IdentifierType::Not_XID), + ('\u{1f16a}', '\u{1f16b}', IdentifierType::Not_NFKC), ('\u{1f16c}', '\u{1f16c}', + IdentifierType::Not_NFKC), ('\u{1f16d}', '\u{1f16f}', IdentifierType::Not_XID), + ('\u{1f170}', '\u{1f178}', IdentifierType::Not_XID), ('\u{1f179}', '\u{1f179}', + IdentifierType::Not_XID), ('\u{1f17a}', '\u{1f17a}', IdentifierType::Not_XID), + ('\u{1f17b}', '\u{1f17c}', IdentifierType::Not_XID), ('\u{1f17d}', '\u{1f17e}', + IdentifierType::Not_XID), ('\u{1f17f}', '\u{1f17f}', IdentifierType::Not_XID), + ('\u{1f180}', '\u{1f189}', IdentifierType::Not_XID), ('\u{1f18a}', '\u{1f18d}', + IdentifierType::Not_XID), ('\u{1f18e}', '\u{1f18f}', IdentifierType::Not_XID), + ('\u{1f190}', '\u{1f190}', IdentifierType::Not_NFKC), ('\u{1f191}', '\u{1f19a}', + IdentifierType::Not_XID), ('\u{1f19b}', '\u{1f1ac}', IdentifierType::Not_XID), + ('\u{1f1ad}', '\u{1f1ad}', IdentifierType::Not_XID), ('\u{1f1e6}', '\u{1f1ff}', + IdentifierType::Not_XID), ('\u{1f200}', '\u{1f200}', IdentifierType::Not_NFKC), + ('\u{1f201}', '\u{1f202}', IdentifierType::Not_NFKC), ('\u{1f210}', '\u{1f231}', + IdentifierType::Not_NFKC), ('\u{1f232}', '\u{1f23a}', IdentifierType::Not_NFKC), + ('\u{1f23b}', '\u{1f23b}', IdentifierType::Not_NFKC), ('\u{1f240}', '\u{1f248}', + IdentifierType::Not_NFKC), ('\u{1f250}', '\u{1f251}', IdentifierType::Not_NFKC), + ('\u{1f260}', '\u{1f265}', IdentifierType::Not_XID), ('\u{1f300}', '\u{1f320}', + IdentifierType::Not_XID), ('\u{1f321}', '\u{1f32c}', IdentifierType::Not_XID), + ('\u{1f32d}', '\u{1f32f}', IdentifierType::Not_XID), ('\u{1f330}', '\u{1f335}', + IdentifierType::Not_XID), ('\u{1f336}', '\u{1f336}', IdentifierType::Not_XID), + ('\u{1f337}', '\u{1f37c}', IdentifierType::Not_XID), ('\u{1f37d}', '\u{1f37d}', + IdentifierType::Not_XID), ('\u{1f37e}', '\u{1f37f}', IdentifierType::Not_XID), + ('\u{1f380}', '\u{1f393}', IdentifierType::Not_XID), ('\u{1f394}', '\u{1f39f}', + IdentifierType::Not_XID), ('\u{1f3a0}', '\u{1f3c4}', IdentifierType::Not_XID), + ('\u{1f3c5}', '\u{1f3c5}', IdentifierType::Not_XID), ('\u{1f3c6}', '\u{1f3ca}', + IdentifierType::Not_XID), ('\u{1f3cb}', '\u{1f3ce}', IdentifierType::Not_XID), + ('\u{1f3cf}', '\u{1f3d3}', IdentifierType::Not_XID), ('\u{1f3d4}', '\u{1f3df}', + IdentifierType::Not_XID), ('\u{1f3e0}', '\u{1f3f0}', IdentifierType::Not_XID), + ('\u{1f3f1}', '\u{1f3f7}', IdentifierType::Not_XID), ('\u{1f3f8}', '\u{1f3ff}', + IdentifierType::Not_XID), ('\u{1f400}', '\u{1f43e}', IdentifierType::Not_XID), + ('\u{1f43f}', '\u{1f43f}', IdentifierType::Not_XID), ('\u{1f440}', '\u{1f440}', + IdentifierType::Not_XID), ('\u{1f441}', '\u{1f441}', IdentifierType::Not_XID), + ('\u{1f442}', '\u{1f4f7}', IdentifierType::Not_XID), ('\u{1f4f8}', '\u{1f4f8}', + IdentifierType::Not_XID), ('\u{1f4f9}', '\u{1f4fc}', IdentifierType::Not_XID), + ('\u{1f4fd}', '\u{1f4fe}', IdentifierType::Not_XID), ('\u{1f4ff}', '\u{1f4ff}', + IdentifierType::Not_XID), ('\u{1f500}', '\u{1f53d}', IdentifierType::Not_XID), + ('\u{1f53e}', '\u{1f53f}', IdentifierType::Not_XID), ('\u{1f540}', '\u{1f543}', + IdentifierType::Not_XID), ('\u{1f544}', '\u{1f54a}', IdentifierType::Not_XID), + ('\u{1f54b}', '\u{1f54e}', IdentifierType::Not_XID), ('\u{1f54f}', '\u{1f54f}', + IdentifierType::Uncommon_Use), ('\u{1f550}', '\u{1f567}', IdentifierType::Not_XID), + ('\u{1f568}', '\u{1f579}', IdentifierType::Not_XID), ('\u{1f57a}', '\u{1f57a}', + IdentifierType::Not_XID), ('\u{1f57b}', '\u{1f5a3}', IdentifierType::Not_XID), + ('\u{1f5a4}', '\u{1f5a4}', IdentifierType::Not_XID), ('\u{1f5a5}', '\u{1f5fa}', + IdentifierType::Not_XID), ('\u{1f5fb}', '\u{1f5ff}', IdentifierType::Not_XID), + ('\u{1f600}', '\u{1f600}', IdentifierType::Not_XID), ('\u{1f601}', '\u{1f610}', + IdentifierType::Not_XID), ('\u{1f611}', '\u{1f611}', IdentifierType::Not_XID), + ('\u{1f612}', '\u{1f614}', IdentifierType::Not_XID), ('\u{1f615}', '\u{1f615}', + IdentifierType::Not_XID), ('\u{1f616}', '\u{1f616}', IdentifierType::Not_XID), + ('\u{1f617}', '\u{1f617}', IdentifierType::Not_XID), ('\u{1f618}', '\u{1f618}', + IdentifierType::Not_XID), ('\u{1f619}', '\u{1f619}', IdentifierType::Not_XID), + ('\u{1f61a}', '\u{1f61a}', IdentifierType::Not_XID), ('\u{1f61b}', '\u{1f61b}', + IdentifierType::Not_XID), ('\u{1f61c}', '\u{1f61e}', IdentifierType::Not_XID), + ('\u{1f61f}', '\u{1f61f}', IdentifierType::Not_XID), ('\u{1f620}', '\u{1f625}', + IdentifierType::Not_XID), ('\u{1f626}', '\u{1f627}', IdentifierType::Not_XID), + ('\u{1f628}', '\u{1f62b}', IdentifierType::Not_XID), ('\u{1f62c}', '\u{1f62c}', + IdentifierType::Not_XID), ('\u{1f62d}', '\u{1f62d}', IdentifierType::Not_XID), + ('\u{1f62e}', '\u{1f62f}', IdentifierType::Not_XID), ('\u{1f630}', '\u{1f633}', + IdentifierType::Not_XID), ('\u{1f634}', '\u{1f634}', IdentifierType::Not_XID), + ('\u{1f635}', '\u{1f640}', IdentifierType::Not_XID), ('\u{1f641}', '\u{1f642}', + IdentifierType::Not_XID), ('\u{1f643}', '\u{1f644}', IdentifierType::Not_XID), + ('\u{1f645}', '\u{1f64f}', IdentifierType::Not_XID), ('\u{1f650}', '\u{1f67f}', + IdentifierType::Not_XID), ('\u{1f680}', '\u{1f6c5}', IdentifierType::Not_XID), + ('\u{1f6c6}', '\u{1f6cf}', IdentifierType::Not_XID), ('\u{1f6d0}', '\u{1f6d0}', + IdentifierType::Not_XID), ('\u{1f6d1}', '\u{1f6d2}', IdentifierType::Not_XID), + ('\u{1f6d3}', '\u{1f6d4}', IdentifierType::Not_XID), ('\u{1f6d5}', '\u{1f6d5}', + IdentifierType::Not_XID), ('\u{1f6d6}', '\u{1f6d7}', IdentifierType::Not_XID), + ('\u{1f6dc}', '\u{1f6dc}', IdentifierType::Not_XID), ('\u{1f6dd}', '\u{1f6df}', + IdentifierType::Not_XID), ('\u{1f6e0}', '\u{1f6ec}', IdentifierType::Not_XID), + ('\u{1f6f0}', '\u{1f6f3}', IdentifierType::Not_XID), ('\u{1f6f4}', '\u{1f6f6}', + IdentifierType::Not_XID), ('\u{1f6f7}', '\u{1f6f8}', IdentifierType::Not_XID), + ('\u{1f6f9}', '\u{1f6f9}', IdentifierType::Not_XID), ('\u{1f6fa}', '\u{1f6fa}', + IdentifierType::Not_XID), ('\u{1f6fb}', '\u{1f6fc}', IdentifierType::Not_XID), + ('\u{1f700}', '\u{1f773}', IdentifierType::Not_XID), ('\u{1f774}', '\u{1f776}', + IdentifierType::Not_XID), ('\u{1f77b}', '\u{1f77f}', IdentifierType::Not_XID), ('\u{1f780}', '\u{1f7d4}', IdentifierType::Not_XID), ('\u{1f7d5}', '\u{1f7d8}', - IdentifierType::Not_XID), ('\u{1f7e0}', '\u{1f7eb}', IdentifierType::Not_XID), - ('\u{1f800}', '\u{1f80b}', IdentifierType::Not_XID), ('\u{1f810}', '\u{1f847}', - IdentifierType::Not_XID), ('\u{1f850}', '\u{1f859}', IdentifierType::Not_XID), - ('\u{1f860}', '\u{1f887}', IdentifierType::Not_XID), ('\u{1f890}', '\u{1f8ad}', - IdentifierType::Not_XID), ('\u{1f8b0}', '\u{1f8b1}', IdentifierType::Not_XID), - ('\u{1f900}', '\u{1f90b}', IdentifierType::Not_XID), ('\u{1f90c}', '\u{1f90c}', - IdentifierType::Not_XID), ('\u{1f90d}', '\u{1f90f}', IdentifierType::Not_XID), - ('\u{1f910}', '\u{1f918}', IdentifierType::Not_XID), ('\u{1f919}', '\u{1f91e}', - IdentifierType::Not_XID), ('\u{1f91f}', '\u{1f91f}', IdentifierType::Not_XID), - ('\u{1f920}', '\u{1f927}', IdentifierType::Not_XID), ('\u{1f928}', '\u{1f92f}', - IdentifierType::Not_XID), ('\u{1f930}', '\u{1f930}', IdentifierType::Not_XID), - ('\u{1f931}', '\u{1f932}', IdentifierType::Not_XID), ('\u{1f933}', '\u{1f93e}', - IdentifierType::Not_XID), ('\u{1f93f}', '\u{1f93f}', IdentifierType::Not_XID), - ('\u{1f940}', '\u{1f94b}', IdentifierType::Not_XID), ('\u{1f94c}', '\u{1f94c}', - IdentifierType::Not_XID), ('\u{1f94d}', '\u{1f94f}', IdentifierType::Not_XID), - ('\u{1f950}', '\u{1f95e}', IdentifierType::Not_XID), ('\u{1f95f}', '\u{1f96b}', - IdentifierType::Not_XID), ('\u{1f96c}', '\u{1f970}', IdentifierType::Not_XID), - ('\u{1f971}', '\u{1f971}', IdentifierType::Not_XID), ('\u{1f972}', '\u{1f972}', - IdentifierType::Not_XID), ('\u{1f973}', '\u{1f976}', IdentifierType::Not_XID), - ('\u{1f977}', '\u{1f978}', IdentifierType::Not_XID), ('\u{1f97a}', '\u{1f97a}', + IdentifierType::Not_XID), ('\u{1f7d9}', '\u{1f7d9}', IdentifierType::Not_XID), + ('\u{1f7e0}', '\u{1f7eb}', IdentifierType::Not_XID), ('\u{1f7f0}', '\u{1f7f0}', + IdentifierType::Not_XID), ('\u{1f800}', '\u{1f80b}', IdentifierType::Not_XID), + ('\u{1f810}', '\u{1f847}', IdentifierType::Not_XID), ('\u{1f850}', '\u{1f859}', + IdentifierType::Not_XID), ('\u{1f860}', '\u{1f887}', IdentifierType::Not_XID), + ('\u{1f890}', '\u{1f8ad}', IdentifierType::Not_XID), ('\u{1f8b0}', '\u{1f8b1}', + IdentifierType::Not_XID), ('\u{1f900}', '\u{1f90b}', IdentifierType::Not_XID), + ('\u{1f90c}', '\u{1f90c}', IdentifierType::Not_XID), ('\u{1f90d}', '\u{1f90f}', + IdentifierType::Not_XID), ('\u{1f910}', '\u{1f918}', IdentifierType::Not_XID), + ('\u{1f919}', '\u{1f91e}', IdentifierType::Not_XID), ('\u{1f91f}', '\u{1f91f}', + IdentifierType::Not_XID), ('\u{1f920}', '\u{1f927}', IdentifierType::Not_XID), + ('\u{1f928}', '\u{1f92f}', IdentifierType::Not_XID), ('\u{1f930}', '\u{1f930}', + IdentifierType::Not_XID), ('\u{1f931}', '\u{1f932}', IdentifierType::Not_XID), + ('\u{1f933}', '\u{1f93e}', IdentifierType::Not_XID), ('\u{1f93f}', '\u{1f93f}', + IdentifierType::Not_XID), ('\u{1f940}', '\u{1f94b}', IdentifierType::Not_XID), + ('\u{1f94c}', '\u{1f94c}', IdentifierType::Not_XID), ('\u{1f94d}', '\u{1f94f}', + IdentifierType::Not_XID), ('\u{1f950}', '\u{1f95e}', IdentifierType::Not_XID), + ('\u{1f95f}', '\u{1f96b}', IdentifierType::Not_XID), ('\u{1f96c}', '\u{1f970}', + IdentifierType::Not_XID), ('\u{1f971}', '\u{1f971}', IdentifierType::Not_XID), + ('\u{1f972}', '\u{1f972}', IdentifierType::Not_XID), ('\u{1f973}', '\u{1f976}', + IdentifierType::Not_XID), ('\u{1f977}', '\u{1f978}', IdentifierType::Not_XID), + ('\u{1f979}', '\u{1f979}', IdentifierType::Not_XID), ('\u{1f97a}', '\u{1f97a}', IdentifierType::Not_XID), ('\u{1f97b}', '\u{1f97b}', IdentifierType::Not_XID), ('\u{1f97c}', '\u{1f97f}', IdentifierType::Not_XID), ('\u{1f980}', '\u{1f984}', IdentifierType::Not_XID), ('\u{1f985}', '\u{1f991}', IdentifierType::Not_XID), @@ -1683,23 +1755,37 @@ pub mod identifier { IdentifierType::Not_XID), ('\u{1f9c0}', '\u{1f9c0}', IdentifierType::Not_XID), ('\u{1f9c1}', '\u{1f9c2}', IdentifierType::Not_XID), ('\u{1f9c3}', '\u{1f9ca}', IdentifierType::Not_XID), ('\u{1f9cb}', '\u{1f9cb}', IdentifierType::Not_XID), - ('\u{1f9cd}', '\u{1f9cf}', IdentifierType::Not_XID), ('\u{1f9d0}', '\u{1f9e6}', - IdentifierType::Not_XID), ('\u{1f9e7}', '\u{1f9ff}', IdentifierType::Not_XID), - ('\u{1fa00}', '\u{1fa53}', IdentifierType::Not_XID), ('\u{1fa60}', '\u{1fa6d}', - IdentifierType::Not_XID), ('\u{1fa70}', '\u{1fa73}', IdentifierType::Not_XID), - ('\u{1fa74}', '\u{1fa74}', IdentifierType::Not_XID), ('\u{1fa78}', '\u{1fa7a}', + ('\u{1f9cc}', '\u{1f9cc}', IdentifierType::Not_XID), ('\u{1f9cd}', '\u{1f9cf}', + IdentifierType::Not_XID), ('\u{1f9d0}', '\u{1f9e6}', IdentifierType::Not_XID), + ('\u{1f9e7}', '\u{1f9ff}', IdentifierType::Not_XID), ('\u{1fa00}', '\u{1fa53}', + IdentifierType::Not_XID), ('\u{1fa60}', '\u{1fa6d}', IdentifierType::Not_XID), + ('\u{1fa70}', '\u{1fa73}', IdentifierType::Not_XID), ('\u{1fa74}', '\u{1fa74}', + IdentifierType::Not_XID), ('\u{1fa75}', '\u{1fa77}', IdentifierType::Not_XID), + ('\u{1fa78}', '\u{1fa7a}', IdentifierType::Not_XID), ('\u{1fa7b}', '\u{1fa7c}', IdentifierType::Not_XID), ('\u{1fa80}', '\u{1fa82}', IdentifierType::Not_XID), - ('\u{1fa83}', '\u{1fa86}', IdentifierType::Not_XID), ('\u{1fa90}', '\u{1fa95}', - IdentifierType::Not_XID), ('\u{1fa96}', '\u{1faa8}', IdentifierType::Not_XID), - ('\u{1fab0}', '\u{1fab6}', IdentifierType::Not_XID), ('\u{1fac0}', '\u{1fac2}', - IdentifierType::Not_XID), ('\u{1fad0}', '\u{1fad6}', IdentifierType::Not_XID), - ('\u{1fb00}', '\u{1fb92}', IdentifierType::Not_XID), ('\u{1fb94}', '\u{1fbca}', - IdentifierType::Not_XID), ('\u{1fbf0}', '\u{1fbf9}', IdentifierType::Not_NFKC), - ('\u{20000}', '\u{2a6d6}', IdentifierType::Recommended), ('\u{2a6d7}', '\u{2a6dd}', + ('\u{1fa83}', '\u{1fa86}', IdentifierType::Not_XID), ('\u{1fa87}', '\u{1fa88}', + IdentifierType::Not_XID), ('\u{1fa90}', '\u{1fa95}', IdentifierType::Not_XID), + ('\u{1fa96}', '\u{1faa8}', IdentifierType::Not_XID), ('\u{1faa9}', '\u{1faac}', + IdentifierType::Not_XID), ('\u{1faad}', '\u{1faaf}', IdentifierType::Not_XID), + ('\u{1fab0}', '\u{1fab6}', IdentifierType::Not_XID), ('\u{1fab7}', '\u{1faba}', + IdentifierType::Not_XID), ('\u{1fabb}', '\u{1fabd}', IdentifierType::Not_XID), + ('\u{1fabf}', '\u{1fabf}', IdentifierType::Not_XID), ('\u{1fac0}', '\u{1fac2}', + IdentifierType::Not_XID), ('\u{1fac3}', '\u{1fac5}', IdentifierType::Not_XID), + ('\u{1face}', '\u{1facf}', IdentifierType::Not_XID), ('\u{1fad0}', '\u{1fad6}', + IdentifierType::Not_XID), ('\u{1fad7}', '\u{1fad9}', IdentifierType::Not_XID), + ('\u{1fada}', '\u{1fadb}', IdentifierType::Not_XID), ('\u{1fae0}', '\u{1fae7}', + IdentifierType::Not_XID), ('\u{1fae8}', '\u{1fae8}', IdentifierType::Not_XID), + ('\u{1faf0}', '\u{1faf6}', IdentifierType::Not_XID), ('\u{1faf7}', '\u{1faf8}', + IdentifierType::Not_XID), ('\u{1fb00}', '\u{1fb92}', IdentifierType::Not_XID), + ('\u{1fb94}', '\u{1fbca}', IdentifierType::Not_XID), ('\u{1fbf0}', '\u{1fbf9}', + IdentifierType::Not_NFKC), ('\u{20000}', '\u{2a6d6}', IdentifierType::Recommended), + ('\u{2a6d7}', '\u{2a6dd}', IdentifierType::Recommended), ('\u{2a6de}', '\u{2a6df}', IdentifierType::Recommended), ('\u{2a700}', '\u{2b734}', IdentifierType::Recommended), - ('\u{2b740}', '\u{2b81d}', IdentifierType::Recommended), ('\u{2b820}', '\u{2cea1}', - IdentifierType::Recommended), ('\u{2ceb0}', '\u{2ebe0}', IdentifierType::Recommended), - ('\u{2f800}', '\u{2fa1d}', IdentifierType::Not_NFKC), ('\u{30000}', '\u{3134a}', + ('\u{2b735}', '\u{2b738}', IdentifierType::Recommended), ('\u{2b739}', '\u{2b739}', + IdentifierType::Recommended), ('\u{2b740}', '\u{2b81d}', IdentifierType::Recommended), + ('\u{2b820}', '\u{2cea1}', IdentifierType::Recommended), ('\u{2ceb0}', '\u{2ebe0}', + IdentifierType::Recommended), ('\u{2f800}', '\u{2fa1d}', IdentifierType::Not_NFKC), + ('\u{30000}', '\u{3134a}', IdentifierType::Recommended), ('\u{31350}', '\u{323af}', IdentifierType::Recommended), ('\u{e0001}', '\u{e0001}', IdentifierType::Deprecated), ('\u{e0020}', '\u{e007f}', IdentifierType::Default_Ignorable), ('\u{e0100}', '\u{e01ef}', IdentifierType::Default_Ignorable) @@ -4281,10 +4367,10 @@ pub mod potential_mixed_script_confusable { '\u{101d}', '\u{1036}', '\u{1038}', '\u{1040}', '\u{10e7}', '\u{10ff}', '\u{1200}', '\u{1206}', '\u{1223}', '\u{1240}', '\u{1260}', '\u{1261}', '\u{1294}', '\u{12ae}', '\u{12d0}', '\u{1323}', '\u{17b7}', '\u{17b8}', '\u{17b9}', '\u{17ba}', '\u{17c6}', - '\u{3007}', '\u{304f}', '\u{3078}', '\u{30a4}', '\u{30a8}', '\u{30ab}', '\u{30bf}', - '\u{30c8}', '\u{30cb}', '\u{30ce}', '\u{30cf}', '\u{30d8}', '\u{30ed}', '\u{4e00}', - '\u{4e3f}', '\u{4e8c}', '\u{4ebb}', '\u{516b}', '\u{529b}', '\u{535c}', '\u{53e3}', - '\u{56d7}', '\u{5915}', '\u{5de5}', '\u{a792}', '\u{a793}', '\u{21fe8}' + '\u{17cb}', '\u{3007}', '\u{304f}', '\u{3078}', '\u{30a4}', '\u{30a8}', '\u{30ab}', + '\u{30bf}', '\u{30c8}', '\u{30cb}', '\u{30ce}', '\u{30cf}', '\u{30d8}', '\u{30ed}', + '\u{4e00}', '\u{4e3f}', '\u{4e8c}', '\u{4ebb}', '\u{516b}', '\u{529b}', '\u{535c}', + '\u{53e3}', '\u{56d7}', '\u{5915}', '\u{5de5}', '\u{a792}', '\u{a793}', '\u{21fe8}' ]; } diff --git a/vendor/unicode-segmentation/.cargo-checksum.json b/vendor/unicode-segmentation/.cargo-checksum.json index f9b266839..acc5d5d0e 100644 --- a/vendor/unicode-segmentation/.cargo-checksum.json +++ b/vendor/unicode-segmentation/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"56be6b873eab00a7504dc74b43b67b94945707ad5fb008b970ee55d3bb35faca","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"efe7aa058e004e12d683039dbc4440e2fec3088364201a620703acedbeef8cb2","benches/graphemes.rs":"88a9f672ea7a03cc15fae36ce544a6e7234e532359402483978858ccda47db3d","benches/unicode_words.rs":"95c3a178ebe07c8cb2c560546ee911bfc4f1e1db81a6cd2c1cef1c99ed2a421a","benches/word_bounds.rs":"66acf40c0a4b06cdb6dd97c1759aba8dea961bb30cd7f223de3ebff8198520b2","scripts/unicode.py":"772c3aba1ae87f4cee562e824a225a7a230a710d9ca21593bc7845f1fe70e7ef","scripts/unicode_gen_breaktests.py":"ee96982d8959bec75c2382233cfca7e239f12a89a1be5fbf942601a215bb9283","src/grapheme.rs":"b5a32bdbb529e9417e8ada8d92656339b6ffb4e9bed8e6d32a0409c13a03050b","src/lib.rs":"572789173717edd0fe037ae656530663406951636c548e6793711b7d5caad910","src/sentence.rs":"aac52f69207e0b68925ab0c6c18cc36ed3da8e918006d96d724f0f19d4d9d643","src/tables.rs":"117efdcf284aaf2b456a5da6a0948a65a9b0bde498a9aad687bebb551b5b061e","src/test.rs":"f039fa285d510244672a067bdbe98ce7ff940e4f2ff82926466e012ac48ad95a","src/testdata.rs":"2429f421557d0d65c9b167a5fd29c5e61f0d197c9221053adefc2f862311752c","src/word.rs":"6eeea9351c12f0a4404606596a487e0e8aa948ba4b134c7cb827ee41557a39fe"},"package":"7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"} \ No newline at end of file +{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"55e5a65c91693dd47a27409e54ad6d5ce805ce003b822e4a568bfd070725e956","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"efe7aa058e004e12d683039dbc4440e2fec3088364201a620703acedbeef8cb2","benches/graphemes.rs":"88a9f672ea7a03cc15fae36ce544a6e7234e532359402483978858ccda47db3d","benches/unicode_words.rs":"95c3a178ebe07c8cb2c560546ee911bfc4f1e1db81a6cd2c1cef1c99ed2a421a","benches/word_bounds.rs":"66acf40c0a4b06cdb6dd97c1759aba8dea961bb30cd7f223de3ebff8198520b2","scripts/unicode.py":"d4ba970a0419f33d20f3deb888be12427bfbb40aa25a5719968600d45cf4dadb","scripts/unicode_gen_breaktests.py":"ee96982d8959bec75c2382233cfca7e239f12a89a1be5fbf942601a215bb9283","src/grapheme.rs":"b5a32bdbb529e9417e8ada8d92656339b6ffb4e9bed8e6d32a0409c13a03050b","src/lib.rs":"572789173717edd0fe037ae656530663406951636c548e6793711b7d5caad910","src/sentence.rs":"aac52f69207e0b68925ab0c6c18cc36ed3da8e918006d96d724f0f19d4d9d643","src/tables.rs":"ba9fa1774b6294ed14565ec6be0f2ec316759d54e3af7c002b6848973d7b1f3c","src/test.rs":"f039fa285d510244672a067bdbe98ce7ff940e4f2ff82926466e012ac48ad95a","src/testdata.rs":"533c02ecace1bec3d46b65d101c7619bc83a2fb2c187a2c960346533c09a0e3e","src/word.rs":"6eeea9351c12f0a4404606596a487e0e8aa948ba4b134c7cb827ee41557a39fe"},"package":"0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"} \ No newline at end of file diff --git a/vendor/unicode-segmentation/Cargo.toml b/vendor/unicode-segmentation/Cargo.toml index 697beb38a..0da56c81e 100644 --- a/vendor/unicode-segmentation/Cargo.toml +++ b/vendor/unicode-segmentation/Cargo.toml @@ -12,14 +12,32 @@ [package] edition = "2018" name = "unicode-segmentation" -version = "1.9.0" -authors = ["kwantam ", "Manish Goregaokar "] -exclude = ["target/*", "Cargo.lock", "scripts/tmp", "benches/texts/*", "*.txt"] -description = "This crate provides Grapheme Cluster, Word and Sentence boundaries\naccording to Unicode Standard Annex #29 rules.\n" +version = "1.10.0" +authors = [ + "kwantam ", + "Manish Goregaokar ", +] +exclude = [ + "target/*", + "Cargo.lock", + "scripts/tmp", + "benches/texts/*", + "*.txt", +] +description = """ +This crate provides Grapheme Cluster, Word and Sentence boundaries +according to Unicode Standard Annex #29 rules. +""" homepage = "https://github.com/unicode-rs/unicode-segmentation" documentation = "https://unicode-rs.github.io/unicode-segmentation" readme = "README.md" -keywords = ["text", "unicode", "grapheme", "word", "boundary"] +keywords = [ + "text", + "unicode", + "grapheme", + "word", + "boundary", +] license = "MIT/Apache-2.0" repository = "https://github.com/unicode-rs/unicode-segmentation" @@ -34,6 +52,7 @@ harness = false [[bench]] name = "word_bounds" harness = false + [dev-dependencies.criterion] version = "0.3" diff --git a/vendor/unicode-segmentation/scripts/unicode.py b/vendor/unicode-segmentation/scripts/unicode.py index 4976d62e3..7aed85e7c 100755 --- a/vendor/unicode-segmentation/scripts/unicode.py +++ b/vendor/unicode-segmentation/scripts/unicode.py @@ -54,7 +54,7 @@ expanded_categories = { # these are the surrogate codepoints, which are not valid rust characters surrogate_codepoints = (0xd800, 0xdfff) -UNICODE_VERSION = (14, 0, 0) +UNICODE_VERSION = (15, 0, 0) UNICODE_VERSION_NUMBER = "%s.%s.%s" %UNICODE_VERSION diff --git a/vendor/unicode-segmentation/src/tables.rs b/vendor/unicode-segmentation/src/tables.rs index b96a01d56..5a811c922 100644 --- a/vendor/unicode-segmentation/src/tables.rs +++ b/vendor/unicode-segmentation/src/tables.rs @@ -14,7 +14,7 @@ /// The version of [Unicode](http://www.unicode.org/) /// that this version of unicode-segmentation is based on. -pub const UNICODE_VERSION: (u64, u64, u64) = (14, 0, 0); +pub const UNICODE_VERSION: (u64, u64, u64) = (15, 0, 0); pub mod util { #[inline] @@ -87,11 +87,12 @@ mod general_category { ('\u{11450}', '\u{11459}'), ('\u{114d0}', '\u{114d9}'), ('\u{11650}', '\u{11659}'), ('\u{116c0}', '\u{116c9}'), ('\u{11730}', '\u{1173b}'), ('\u{118e0}', '\u{118f2}'), ('\u{11950}', '\u{11959}'), ('\u{11c50}', '\u{11c6c}'), ('\u{11d50}', '\u{11d59}'), - ('\u{11da0}', '\u{11da9}'), ('\u{11fc0}', '\u{11fd4}'), ('\u{12400}', '\u{1246e}'), - ('\u{16a60}', '\u{16a69}'), ('\u{16ac0}', '\u{16ac9}'), ('\u{16b50}', '\u{16b59}'), - ('\u{16b5b}', '\u{16b61}'), ('\u{16e80}', '\u{16e96}'), ('\u{1d2e0}', '\u{1d2f3}'), - ('\u{1d360}', '\u{1d378}'), ('\u{1d7ce}', '\u{1d7ff}'), ('\u{1e140}', '\u{1e149}'), - ('\u{1e2f0}', '\u{1e2f9}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1e950}', '\u{1e959}'), + ('\u{11da0}', '\u{11da9}'), ('\u{11f50}', '\u{11f59}'), ('\u{11fc0}', '\u{11fd4}'), + ('\u{12400}', '\u{1246e}'), ('\u{16a60}', '\u{16a69}'), ('\u{16ac0}', '\u{16ac9}'), + ('\u{16b50}', '\u{16b59}'), ('\u{16b5b}', '\u{16b61}'), ('\u{16e80}', '\u{16e96}'), + ('\u{1d2c0}', '\u{1d2d3}'), ('\u{1d2e0}', '\u{1d2f3}'), ('\u{1d360}', '\u{1d378}'), + ('\u{1d7ce}', '\u{1d7ff}'), ('\u{1e140}', '\u{1e149}'), ('\u{1e2f0}', '\u{1e2f9}'), + ('\u{1e4f0}', '\u{1e4f9}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1e950}', '\u{1e959}'), ('\u{1ec71}', '\u{1ecab}'), ('\u{1ecad}', '\u{1ecaf}'), ('\u{1ecb1}', '\u{1ecb4}'), ('\u{1ed01}', '\u{1ed2d}'), ('\u{1ed2f}', '\u{1ed3d}'), ('\u{1f100}', '\u{1f10c}'), ('\u{1fbf0}', '\u{1fbf9}') @@ -144,189 +145,192 @@ mod derived_property { '\u{b9a}'), ('\u{b9c}', '\u{b9c}'), ('\u{b9e}', '\u{b9f}'), ('\u{ba3}', '\u{ba4}'), ('\u{ba8}', '\u{baa}'), ('\u{bae}', '\u{bb9}'), ('\u{bbe}', '\u{bc2}'), ('\u{bc6}', '\u{bc8}'), ('\u{bca}', '\u{bcc}'), ('\u{bd0}', '\u{bd0}'), ('\u{bd7}', '\u{bd7}'), - ('\u{c00}', '\u{c03}'), ('\u{c05}', '\u{c0c}'), ('\u{c0e}', '\u{c10}'), ('\u{c12}', - '\u{c28}'), ('\u{c2a}', '\u{c39}'), ('\u{c3d}', '\u{c44}'), ('\u{c46}', '\u{c48}'), - ('\u{c4a}', '\u{c4c}'), ('\u{c55}', '\u{c56}'), ('\u{c58}', '\u{c5a}'), ('\u{c5d}', - '\u{c5d}'), ('\u{c60}', '\u{c63}'), ('\u{c80}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), - ('\u{c8e}', '\u{c90}'), ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', - '\u{cb9}'), ('\u{cbd}', '\u{cc4}'), ('\u{cc6}', '\u{cc8}'), ('\u{cca}', '\u{ccc}'), - ('\u{cd5}', '\u{cd6}'), ('\u{cdd}', '\u{cde}'), ('\u{ce0}', '\u{ce3}'), ('\u{cf1}', - '\u{cf2}'), ('\u{d00}', '\u{d0c}'), ('\u{d0e}', '\u{d10}'), ('\u{d12}', '\u{d3a}'), - ('\u{d3d}', '\u{d44}'), ('\u{d46}', '\u{d48}'), ('\u{d4a}', '\u{d4c}'), ('\u{d4e}', - '\u{d4e}'), ('\u{d54}', '\u{d57}'), ('\u{d5f}', '\u{d63}'), ('\u{d7a}', '\u{d7f}'), - ('\u{d81}', '\u{d83}'), ('\u{d85}', '\u{d96}'), ('\u{d9a}', '\u{db1}'), ('\u{db3}', - '\u{dbb}'), ('\u{dbd}', '\u{dbd}'), ('\u{dc0}', '\u{dc6}'), ('\u{dcf}', '\u{dd4}'), - ('\u{dd6}', '\u{dd6}'), ('\u{dd8}', '\u{ddf}'), ('\u{df2}', '\u{df3}'), ('\u{e01}', - '\u{e3a}'), ('\u{e40}', '\u{e46}'), ('\u{e4d}', '\u{e4d}'), ('\u{e81}', '\u{e82}'), - ('\u{e84}', '\u{e84}'), ('\u{e86}', '\u{e8a}'), ('\u{e8c}', '\u{ea3}'), ('\u{ea5}', - '\u{ea5}'), ('\u{ea7}', '\u{eb9}'), ('\u{ebb}', '\u{ebd}'), ('\u{ec0}', '\u{ec4}'), - ('\u{ec6}', '\u{ec6}'), ('\u{ecd}', '\u{ecd}'), ('\u{edc}', '\u{edf}'), ('\u{f00}', - '\u{f00}'), ('\u{f40}', '\u{f47}'), ('\u{f49}', '\u{f6c}'), ('\u{f71}', '\u{f81}'), - ('\u{f88}', '\u{f97}'), ('\u{f99}', '\u{fbc}'), ('\u{1000}', '\u{1036}'), ('\u{1038}', - '\u{1038}'), ('\u{103b}', '\u{103f}'), ('\u{1050}', '\u{108f}'), ('\u{109a}', '\u{109d}'), - ('\u{10a0}', '\u{10c5}'), ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), ('\u{10d0}', - '\u{10fa}'), ('\u{10fc}', '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', '\u{1256}'), - ('\u{1258}', '\u{1258}'), ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1288}'), ('\u{128a}', - '\u{128d}'), ('\u{1290}', '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), ('\u{12b8}', '\u{12be}'), - ('\u{12c0}', '\u{12c0}'), ('\u{12c2}', '\u{12c5}'), ('\u{12c8}', '\u{12d6}'), ('\u{12d8}', - '\u{1310}'), ('\u{1312}', '\u{1315}'), ('\u{1318}', '\u{135a}'), ('\u{1380}', '\u{138f}'), - ('\u{13a0}', '\u{13f5}'), ('\u{13f8}', '\u{13fd}'), ('\u{1401}', '\u{166c}'), ('\u{166f}', - '\u{167f}'), ('\u{1681}', '\u{169a}'), ('\u{16a0}', '\u{16ea}'), ('\u{16ee}', '\u{16f8}'), - ('\u{1700}', '\u{1713}'), ('\u{171f}', '\u{1733}'), ('\u{1740}', '\u{1753}'), ('\u{1760}', - '\u{176c}'), ('\u{176e}', '\u{1770}'), ('\u{1772}', '\u{1773}'), ('\u{1780}', '\u{17b3}'), - ('\u{17b6}', '\u{17c8}'), ('\u{17d7}', '\u{17d7}'), ('\u{17dc}', '\u{17dc}'), ('\u{1820}', - '\u{1878}'), ('\u{1880}', '\u{18aa}'), ('\u{18b0}', '\u{18f5}'), ('\u{1900}', '\u{191e}'), - ('\u{1920}', '\u{192b}'), ('\u{1930}', '\u{1938}'), ('\u{1950}', '\u{196d}'), ('\u{1970}', - '\u{1974}'), ('\u{1980}', '\u{19ab}'), ('\u{19b0}', '\u{19c9}'), ('\u{1a00}', '\u{1a1b}'), - ('\u{1a20}', '\u{1a5e}'), ('\u{1a61}', '\u{1a74}'), ('\u{1aa7}', '\u{1aa7}'), ('\u{1abf}', - '\u{1ac0}'), ('\u{1acc}', '\u{1ace}'), ('\u{1b00}', '\u{1b33}'), ('\u{1b35}', '\u{1b43}'), - ('\u{1b45}', '\u{1b4c}'), ('\u{1b80}', '\u{1ba9}'), ('\u{1bac}', '\u{1baf}'), ('\u{1bba}', - '\u{1be5}'), ('\u{1be7}', '\u{1bf1}'), ('\u{1c00}', '\u{1c36}'), ('\u{1c4d}', '\u{1c4f}'), - ('\u{1c5a}', '\u{1c7d}'), ('\u{1c80}', '\u{1c88}'), ('\u{1c90}', '\u{1cba}'), ('\u{1cbd}', - '\u{1cbf}'), ('\u{1ce9}', '\u{1cec}'), ('\u{1cee}', '\u{1cf3}'), ('\u{1cf5}', '\u{1cf6}'), - ('\u{1cfa}', '\u{1cfa}'), ('\u{1d00}', '\u{1dbf}'), ('\u{1de7}', '\u{1df4}'), ('\u{1e00}', - '\u{1f15}'), ('\u{1f18}', '\u{1f1d}'), ('\u{1f20}', '\u{1f45}'), ('\u{1f48}', '\u{1f4d}'), - ('\u{1f50}', '\u{1f57}'), ('\u{1f59}', '\u{1f59}'), ('\u{1f5b}', '\u{1f5b}'), ('\u{1f5d}', - '\u{1f5d}'), ('\u{1f5f}', '\u{1f7d}'), ('\u{1f80}', '\u{1fb4}'), ('\u{1fb6}', '\u{1fbc}'), - ('\u{1fbe}', '\u{1fbe}'), ('\u{1fc2}', '\u{1fc4}'), ('\u{1fc6}', '\u{1fcc}'), ('\u{1fd0}', - '\u{1fd3}'), ('\u{1fd6}', '\u{1fdb}'), ('\u{1fe0}', '\u{1fec}'), ('\u{1ff2}', '\u{1ff4}'), - ('\u{1ff6}', '\u{1ffc}'), ('\u{2071}', '\u{2071}'), ('\u{207f}', '\u{207f}'), ('\u{2090}', - '\u{209c}'), ('\u{2102}', '\u{2102}'), ('\u{2107}', '\u{2107}'), ('\u{210a}', '\u{2113}'), - ('\u{2115}', '\u{2115}'), ('\u{2119}', '\u{211d}'), ('\u{2124}', '\u{2124}'), ('\u{2126}', - '\u{2126}'), ('\u{2128}', '\u{2128}'), ('\u{212a}', '\u{212d}'), ('\u{212f}', '\u{2139}'), - ('\u{213c}', '\u{213f}'), ('\u{2145}', '\u{2149}'), ('\u{214e}', '\u{214e}'), ('\u{2160}', - '\u{2188}'), ('\u{24b6}', '\u{24e9}'), ('\u{2c00}', '\u{2ce4}'), ('\u{2ceb}', '\u{2cee}'), - ('\u{2cf2}', '\u{2cf3}'), ('\u{2d00}', '\u{2d25}'), ('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', - '\u{2d2d}'), ('\u{2d30}', '\u{2d67}'), ('\u{2d6f}', '\u{2d6f}'), ('\u{2d80}', '\u{2d96}'), - ('\u{2da0}', '\u{2da6}'), ('\u{2da8}', '\u{2dae}'), ('\u{2db0}', '\u{2db6}'), ('\u{2db8}', - '\u{2dbe}'), ('\u{2dc0}', '\u{2dc6}'), ('\u{2dc8}', '\u{2dce}'), ('\u{2dd0}', '\u{2dd6}'), - ('\u{2dd8}', '\u{2dde}'), ('\u{2de0}', '\u{2dff}'), ('\u{2e2f}', '\u{2e2f}'), ('\u{3005}', - '\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3031}', '\u{3035}'), ('\u{3038}', '\u{303c}'), - ('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'), ('\u{30fc}', - '\u{30ff}'), ('\u{3105}', '\u{312f}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}', '\u{31bf}'), - ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4dbf}'), ('\u{4e00}', '\u{a48c}'), ('\u{a4d0}', - '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), - ('\u{a640}', '\u{a66e}'), ('\u{a674}', '\u{a67b}'), ('\u{a67f}', '\u{a6ef}'), ('\u{a717}', - '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}', '\u{a7ca}'), ('\u{a7d0}', '\u{a7d1}'), - ('\u{a7d3}', '\u{a7d3}'), ('\u{a7d5}', '\u{a7d9}'), ('\u{a7f2}', '\u{a805}'), ('\u{a807}', - '\u{a827}'), ('\u{a840}', '\u{a873}'), ('\u{a880}', '\u{a8c3}'), ('\u{a8c5}', '\u{a8c5}'), - ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a8fd}', '\u{a8ff}'), ('\u{a90a}', - '\u{a92a}'), ('\u{a930}', '\u{a952}'), ('\u{a960}', '\u{a97c}'), ('\u{a980}', '\u{a9b2}'), - ('\u{a9b4}', '\u{a9bf}'), ('\u{a9cf}', '\u{a9cf}'), ('\u{a9e0}', '\u{a9ef}'), ('\u{a9fa}', - '\u{a9fe}'), ('\u{aa00}', '\u{aa36}'), ('\u{aa40}', '\u{aa4d}'), ('\u{aa60}', '\u{aa76}'), - ('\u{aa7a}', '\u{aabe}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', - '\u{aadd}'), ('\u{aae0}', '\u{aaef}'), ('\u{aaf2}', '\u{aaf5}'), ('\u{ab01}', '\u{ab06}'), - ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', - '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'), ('\u{ab5c}', '\u{ab69}'), ('\u{ab70}', '\u{abea}'), - ('\u{ac00}', '\u{d7a3}'), ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', - '\u{fa6d}'), ('\u{fa70}', '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), - ('\u{fb1d}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}', - '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'), - ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}', - '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}', '\u{ff3a}'), - ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}', - '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}', '\u{1000b}'), - ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}', '\u{1003d}'), - ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}', '\u{100fa}'), - ('\u{10140}', '\u{10174}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), - ('\u{10300}', '\u{1031f}'), ('\u{1032d}', '\u{1034a}'), ('\u{10350}', '\u{1037a}'), - ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), - ('\u{103d1}', '\u{103d5}'), ('\u{10400}', '\u{1049d}'), ('\u{104b0}', '\u{104d3}'), - ('\u{104d8}', '\u{104fb}'), ('\u{10500}', '\u{10527}'), ('\u{10530}', '\u{10563}'), - ('\u{10570}', '\u{1057a}'), ('\u{1057c}', '\u{1058a}'), ('\u{1058c}', '\u{10592}'), - ('\u{10594}', '\u{10595}'), ('\u{10597}', '\u{105a1}'), ('\u{105a3}', '\u{105b1}'), - ('\u{105b3}', '\u{105b9}'), ('\u{105bb}', '\u{105bc}'), ('\u{10600}', '\u{10736}'), - ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}'), ('\u{10780}', '\u{10785}'), - ('\u{10787}', '\u{107b0}'), ('\u{107b2}', '\u{107ba}'), ('\u{10800}', '\u{10805}'), - ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), - ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), - ('\u{10880}', '\u{1089e}'), ('\u{108e0}', '\u{108f2}'), ('\u{108f4}', '\u{108f5}'), - ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), - ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), - ('\u{10a0c}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a35}'), - ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), - ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), - ('\u{10b60}', '\u{10b72}'), ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), - ('\u{10c80}', '\u{10cb2}'), ('\u{10cc0}', '\u{10cf2}'), ('\u{10d00}', '\u{10d27}'), - ('\u{10e80}', '\u{10ea9}'), ('\u{10eab}', '\u{10eac}'), ('\u{10eb0}', '\u{10eb1}'), - ('\u{10f00}', '\u{10f1c}'), ('\u{10f27}', '\u{10f27}'), ('\u{10f30}', '\u{10f45}'), - ('\u{10f70}', '\u{10f81}'), ('\u{10fb0}', '\u{10fc4}'), ('\u{10fe0}', '\u{10ff6}'), - ('\u{11000}', '\u{11045}'), ('\u{11071}', '\u{11075}'), ('\u{11082}', '\u{110b8}'), - ('\u{110c2}', '\u{110c2}'), ('\u{110d0}', '\u{110e8}'), ('\u{11100}', '\u{11132}'), - ('\u{11144}', '\u{11147}'), ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), - ('\u{11180}', '\u{111bf}'), ('\u{111c1}', '\u{111c4}'), ('\u{111ce}', '\u{111cf}'), - ('\u{111da}', '\u{111da}'), ('\u{111dc}', '\u{111dc}'), ('\u{11200}', '\u{11211}'), - ('\u{11213}', '\u{11234}'), ('\u{11237}', '\u{11237}'), ('\u{1123e}', '\u{1123e}'), - ('\u{11280}', '\u{11286}'), ('\u{11288}', '\u{11288}'), ('\u{1128a}', '\u{1128d}'), - ('\u{1128f}', '\u{1129d}'), ('\u{1129f}', '\u{112a8}'), ('\u{112b0}', '\u{112e8}'), - ('\u{11300}', '\u{11303}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}', '\u{11310}'), - ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}', '\u{11333}'), - ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{11344}'), ('\u{11347}', '\u{11348}'), - ('\u{1134b}', '\u{1134c}'), ('\u{11350}', '\u{11350}'), ('\u{11357}', '\u{11357}'), - ('\u{1135d}', '\u{11363}'), ('\u{11400}', '\u{11441}'), ('\u{11443}', '\u{11445}'), - ('\u{11447}', '\u{1144a}'), ('\u{1145f}', '\u{11461}'), ('\u{11480}', '\u{114c1}'), - ('\u{114c4}', '\u{114c5}'), ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115b5}'), - ('\u{115b8}', '\u{115be}'), ('\u{115d8}', '\u{115dd}'), ('\u{11600}', '\u{1163e}'), - ('\u{11640}', '\u{11640}'), ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116b5}'), - ('\u{116b8}', '\u{116b8}'), ('\u{11700}', '\u{1171a}'), ('\u{1171d}', '\u{1172a}'), - ('\u{11740}', '\u{11746}'), ('\u{11800}', '\u{11838}'), ('\u{118a0}', '\u{118df}'), - ('\u{118ff}', '\u{11906}'), ('\u{11909}', '\u{11909}'), ('\u{1190c}', '\u{11913}'), - ('\u{11915}', '\u{11916}'), ('\u{11918}', '\u{11935}'), ('\u{11937}', '\u{11938}'), - ('\u{1193b}', '\u{1193c}'), ('\u{1193f}', '\u{11942}'), ('\u{119a0}', '\u{119a7}'), - ('\u{119aa}', '\u{119d7}'), ('\u{119da}', '\u{119df}'), ('\u{119e1}', '\u{119e1}'), - ('\u{119e3}', '\u{119e4}'), ('\u{11a00}', '\u{11a32}'), ('\u{11a35}', '\u{11a3e}'), - ('\u{11a50}', '\u{11a97}'), ('\u{11a9d}', '\u{11a9d}'), ('\u{11ab0}', '\u{11af8}'), - ('\u{11c00}', '\u{11c08}'), ('\u{11c0a}', '\u{11c36}'), ('\u{11c38}', '\u{11c3e}'), - ('\u{11c40}', '\u{11c40}'), ('\u{11c72}', '\u{11c8f}'), ('\u{11c92}', '\u{11ca7}'), - ('\u{11ca9}', '\u{11cb6}'), ('\u{11d00}', '\u{11d06}'), ('\u{11d08}', '\u{11d09}'), - ('\u{11d0b}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'), - ('\u{11d3f}', '\u{11d41}'), ('\u{11d43}', '\u{11d43}'), ('\u{11d46}', '\u{11d47}'), - ('\u{11d60}', '\u{11d65}'), ('\u{11d67}', '\u{11d68}'), ('\u{11d6a}', '\u{11d8e}'), - ('\u{11d90}', '\u{11d91}'), ('\u{11d93}', '\u{11d96}'), ('\u{11d98}', '\u{11d98}'), - ('\u{11ee0}', '\u{11ef6}'), ('\u{11fb0}', '\u{11fb0}'), ('\u{12000}', '\u{12399}'), - ('\u{12400}', '\u{1246e}'), ('\u{12480}', '\u{12543}'), ('\u{12f90}', '\u{12ff0}'), - ('\u{13000}', '\u{1342e}'), ('\u{14400}', '\u{14646}'), ('\u{16800}', '\u{16a38}'), - ('\u{16a40}', '\u{16a5e}'), ('\u{16a70}', '\u{16abe}'), ('\u{16ad0}', '\u{16aed}'), - ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}', '\u{16b77}'), - ('\u{16b7d}', '\u{16b8f}'), ('\u{16e40}', '\u{16e7f}'), ('\u{16f00}', '\u{16f4a}'), - ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '\u{16f9f}'), ('\u{16fe0}', '\u{16fe1}'), - ('\u{16fe3}', '\u{16fe3}'), ('\u{16ff0}', '\u{16ff1}'), ('\u{17000}', '\u{187f7}'), - ('\u{18800}', '\u{18cd5}'), ('\u{18d00}', '\u{18d08}'), ('\u{1aff0}', '\u{1aff3}'), - ('\u{1aff5}', '\u{1affb}'), ('\u{1affd}', '\u{1affe}'), ('\u{1b000}', '\u{1b122}'), - ('\u{1b150}', '\u{1b152}'), ('\u{1b164}', '\u{1b167}'), ('\u{1b170}', '\u{1b2fb}'), - ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), - ('\u{1bc90}', '\u{1bc99}'), ('\u{1bc9e}', '\u{1bc9e}'), ('\u{1d400}', '\u{1d454}'), - ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}', '\u{1d49f}'), ('\u{1d4a2}', '\u{1d4a2}'), - ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}', '\u{1d4ac}'), ('\u{1d4ae}', '\u{1d4b9}'), - ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}', '\u{1d4c3}'), ('\u{1d4c5}', '\u{1d505}'), - ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}', '\u{1d514}'), ('\u{1d516}', '\u{1d51c}'), - ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}', '\u{1d53e}'), ('\u{1d540}', '\u{1d544}'), - ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}', '\u{1d550}'), ('\u{1d552}', '\u{1d6a5}'), - ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}', '\u{1d6da}'), ('\u{1d6dc}', '\u{1d6fa}'), - ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}', '\u{1d734}'), ('\u{1d736}', '\u{1d74e}'), - ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}', '\u{1d788}'), ('\u{1d78a}', '\u{1d7a8}'), - ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'), ('\u{1df00}', '\u{1df1e}'), - ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'), - ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'), ('\u{1e100}', '\u{1e12c}'), - ('\u{1e137}', '\u{1e13d}'), ('\u{1e14e}', '\u{1e14e}'), ('\u{1e290}', '\u{1e2ad}'), - ('\u{1e2c0}', '\u{1e2eb}'), ('\u{1e7e0}', '\u{1e7e6}'), ('\u{1e7e8}', '\u{1e7eb}'), - ('\u{1e7ed}', '\u{1e7ee}'), ('\u{1e7f0}', '\u{1e7fe}'), ('\u{1e800}', '\u{1e8c4}'), - ('\u{1e900}', '\u{1e943}'), ('\u{1e947}', '\u{1e947}'), ('\u{1e94b}', '\u{1e94b}'), - ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), - ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), - ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), - ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), - ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), - ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), - ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), - ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), - ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), - ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), - ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), - ('\u{1f130}', '\u{1f149}'), ('\u{1f150}', '\u{1f169}'), ('\u{1f170}', '\u{1f189}'), - ('\u{20000}', '\u{2a6df}'), ('\u{2a700}', '\u{2b738}'), ('\u{2b740}', '\u{2b81d}'), - ('\u{2b820}', '\u{2cea1}'), ('\u{2ceb0}', '\u{2ebe0}'), ('\u{2f800}', '\u{2fa1d}'), - ('\u{30000}', '\u{3134a}') + ('\u{c00}', '\u{c0c}'), ('\u{c0e}', '\u{c10}'), ('\u{c12}', '\u{c28}'), ('\u{c2a}', + '\u{c39}'), ('\u{c3d}', '\u{c44}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4c}'), + ('\u{c55}', '\u{c56}'), ('\u{c58}', '\u{c5a}'), ('\u{c5d}', '\u{c5d}'), ('\u{c60}', + '\u{c63}'), ('\u{c80}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), ('\u{c8e}', '\u{c90}'), + ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', '\u{cb9}'), ('\u{cbd}', + '\u{cc4}'), ('\u{cc6}', '\u{cc8}'), ('\u{cca}', '\u{ccc}'), ('\u{cd5}', '\u{cd6}'), + ('\u{cdd}', '\u{cde}'), ('\u{ce0}', '\u{ce3}'), ('\u{cf1}', '\u{cf3}'), ('\u{d00}', + '\u{d0c}'), ('\u{d0e}', '\u{d10}'), ('\u{d12}', '\u{d3a}'), ('\u{d3d}', '\u{d44}'), + ('\u{d46}', '\u{d48}'), ('\u{d4a}', '\u{d4c}'), ('\u{d4e}', '\u{d4e}'), ('\u{d54}', + '\u{d57}'), ('\u{d5f}', '\u{d63}'), ('\u{d7a}', '\u{d7f}'), ('\u{d81}', '\u{d83}'), + ('\u{d85}', '\u{d96}'), ('\u{d9a}', '\u{db1}'), ('\u{db3}', '\u{dbb}'), ('\u{dbd}', + '\u{dbd}'), ('\u{dc0}', '\u{dc6}'), ('\u{dcf}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), + ('\u{dd8}', '\u{ddf}'), ('\u{df2}', '\u{df3}'), ('\u{e01}', '\u{e3a}'), ('\u{e40}', + '\u{e46}'), ('\u{e4d}', '\u{e4d}'), ('\u{e81}', '\u{e82}'), ('\u{e84}', '\u{e84}'), + ('\u{e86}', '\u{e8a}'), ('\u{e8c}', '\u{ea3}'), ('\u{ea5}', '\u{ea5}'), ('\u{ea7}', + '\u{eb9}'), ('\u{ebb}', '\u{ebd}'), ('\u{ec0}', '\u{ec4}'), ('\u{ec6}', '\u{ec6}'), + ('\u{ecd}', '\u{ecd}'), ('\u{edc}', '\u{edf}'), ('\u{f00}', '\u{f00}'), ('\u{f40}', + '\u{f47}'), ('\u{f49}', '\u{f6c}'), ('\u{f71}', '\u{f83}'), ('\u{f88}', '\u{f97}'), + ('\u{f99}', '\u{fbc}'), ('\u{1000}', '\u{1036}'), ('\u{1038}', '\u{1038}'), ('\u{103b}', + '\u{103f}'), ('\u{1050}', '\u{108f}'), ('\u{109a}', '\u{109d}'), ('\u{10a0}', '\u{10c5}'), + ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), ('\u{10d0}', '\u{10fa}'), ('\u{10fc}', + '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', '\u{1256}'), ('\u{1258}', '\u{1258}'), + ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1288}'), ('\u{128a}', '\u{128d}'), ('\u{1290}', + '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), ('\u{12b8}', '\u{12be}'), ('\u{12c0}', '\u{12c0}'), + ('\u{12c2}', '\u{12c5}'), ('\u{12c8}', '\u{12d6}'), ('\u{12d8}', '\u{1310}'), ('\u{1312}', + '\u{1315}'), ('\u{1318}', '\u{135a}'), ('\u{1380}', '\u{138f}'), ('\u{13a0}', '\u{13f5}'), + ('\u{13f8}', '\u{13fd}'), ('\u{1401}', '\u{166c}'), ('\u{166f}', '\u{167f}'), ('\u{1681}', + '\u{169a}'), ('\u{16a0}', '\u{16ea}'), ('\u{16ee}', '\u{16f8}'), ('\u{1700}', '\u{1713}'), + ('\u{171f}', '\u{1733}'), ('\u{1740}', '\u{1753}'), ('\u{1760}', '\u{176c}'), ('\u{176e}', + '\u{1770}'), ('\u{1772}', '\u{1773}'), ('\u{1780}', '\u{17b3}'), ('\u{17b6}', '\u{17c8}'), + ('\u{17d7}', '\u{17d7}'), ('\u{17dc}', '\u{17dc}'), ('\u{1820}', '\u{1878}'), ('\u{1880}', + '\u{18aa}'), ('\u{18b0}', '\u{18f5}'), ('\u{1900}', '\u{191e}'), ('\u{1920}', '\u{192b}'), + ('\u{1930}', '\u{1938}'), ('\u{1950}', '\u{196d}'), ('\u{1970}', '\u{1974}'), ('\u{1980}', + '\u{19ab}'), ('\u{19b0}', '\u{19c9}'), ('\u{1a00}', '\u{1a1b}'), ('\u{1a20}', '\u{1a5e}'), + ('\u{1a61}', '\u{1a74}'), ('\u{1aa7}', '\u{1aa7}'), ('\u{1abf}', '\u{1ac0}'), ('\u{1acc}', + '\u{1ace}'), ('\u{1b00}', '\u{1b33}'), ('\u{1b35}', '\u{1b43}'), ('\u{1b45}', '\u{1b4c}'), + ('\u{1b80}', '\u{1ba9}'), ('\u{1bac}', '\u{1baf}'), ('\u{1bba}', '\u{1be5}'), ('\u{1be7}', + '\u{1bf1}'), ('\u{1c00}', '\u{1c36}'), ('\u{1c4d}', '\u{1c4f}'), ('\u{1c5a}', '\u{1c7d}'), + ('\u{1c80}', '\u{1c88}'), ('\u{1c90}', '\u{1cba}'), ('\u{1cbd}', '\u{1cbf}'), ('\u{1ce9}', + '\u{1cec}'), ('\u{1cee}', '\u{1cf3}'), ('\u{1cf5}', '\u{1cf6}'), ('\u{1cfa}', '\u{1cfa}'), + ('\u{1d00}', '\u{1dbf}'), ('\u{1de7}', '\u{1df4}'), ('\u{1e00}', '\u{1f15}'), ('\u{1f18}', + '\u{1f1d}'), ('\u{1f20}', '\u{1f45}'), ('\u{1f48}', '\u{1f4d}'), ('\u{1f50}', '\u{1f57}'), + ('\u{1f59}', '\u{1f59}'), ('\u{1f5b}', '\u{1f5b}'), ('\u{1f5d}', '\u{1f5d}'), ('\u{1f5f}', + '\u{1f7d}'), ('\u{1f80}', '\u{1fb4}'), ('\u{1fb6}', '\u{1fbc}'), ('\u{1fbe}', '\u{1fbe}'), + ('\u{1fc2}', '\u{1fc4}'), ('\u{1fc6}', '\u{1fcc}'), ('\u{1fd0}', '\u{1fd3}'), ('\u{1fd6}', + '\u{1fdb}'), ('\u{1fe0}', '\u{1fec}'), ('\u{1ff2}', '\u{1ff4}'), ('\u{1ff6}', '\u{1ffc}'), + ('\u{2071}', '\u{2071}'), ('\u{207f}', '\u{207f}'), ('\u{2090}', '\u{209c}'), ('\u{2102}', + '\u{2102}'), ('\u{2107}', '\u{2107}'), ('\u{210a}', '\u{2113}'), ('\u{2115}', '\u{2115}'), + ('\u{2119}', '\u{211d}'), ('\u{2124}', '\u{2124}'), ('\u{2126}', '\u{2126}'), ('\u{2128}', + '\u{2128}'), ('\u{212a}', '\u{212d}'), ('\u{212f}', '\u{2139}'), ('\u{213c}', '\u{213f}'), + ('\u{2145}', '\u{2149}'), ('\u{214e}', '\u{214e}'), ('\u{2160}', '\u{2188}'), ('\u{24b6}', + '\u{24e9}'), ('\u{2c00}', '\u{2ce4}'), ('\u{2ceb}', '\u{2cee}'), ('\u{2cf2}', '\u{2cf3}'), + ('\u{2d00}', '\u{2d25}'), ('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}'), ('\u{2d30}', + '\u{2d67}'), ('\u{2d6f}', '\u{2d6f}'), ('\u{2d80}', '\u{2d96}'), ('\u{2da0}', '\u{2da6}'), + ('\u{2da8}', '\u{2dae}'), ('\u{2db0}', '\u{2db6}'), ('\u{2db8}', '\u{2dbe}'), ('\u{2dc0}', + '\u{2dc6}'), ('\u{2dc8}', '\u{2dce}'), ('\u{2dd0}', '\u{2dd6}'), ('\u{2dd8}', '\u{2dde}'), + ('\u{2de0}', '\u{2dff}'), ('\u{2e2f}', '\u{2e2f}'), ('\u{3005}', '\u{3007}'), ('\u{3021}', + '\u{3029}'), ('\u{3031}', '\u{3035}'), ('\u{3038}', '\u{303c}'), ('\u{3041}', '\u{3096}'), + ('\u{309d}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'), ('\u{30fc}', '\u{30ff}'), ('\u{3105}', + '\u{312f}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}', '\u{31bf}'), ('\u{31f0}', '\u{31ff}'), + ('\u{3400}', '\u{4dbf}'), ('\u{4e00}', '\u{a48c}'), ('\u{a4d0}', '\u{a4fd}'), ('\u{a500}', + '\u{a60c}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a640}', '\u{a66e}'), + ('\u{a674}', '\u{a67b}'), ('\u{a67f}', '\u{a6ef}'), ('\u{a717}', '\u{a71f}'), ('\u{a722}', + '\u{a788}'), ('\u{a78b}', '\u{a7ca}'), ('\u{a7d0}', '\u{a7d1}'), ('\u{a7d3}', '\u{a7d3}'), + ('\u{a7d5}', '\u{a7d9}'), ('\u{a7f2}', '\u{a805}'), ('\u{a807}', '\u{a827}'), ('\u{a840}', + '\u{a873}'), ('\u{a880}', '\u{a8c3}'), ('\u{a8c5}', '\u{a8c5}'), ('\u{a8f2}', '\u{a8f7}'), + ('\u{a8fb}', '\u{a8fb}'), ('\u{a8fd}', '\u{a8ff}'), ('\u{a90a}', '\u{a92a}'), ('\u{a930}', + '\u{a952}'), ('\u{a960}', '\u{a97c}'), ('\u{a980}', '\u{a9b2}'), ('\u{a9b4}', '\u{a9bf}'), + ('\u{a9cf}', '\u{a9cf}'), ('\u{a9e0}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', + '\u{aa36}'), ('\u{aa40}', '\u{aa4d}'), ('\u{aa60}', '\u{aa76}'), ('\u{aa7a}', '\u{aabe}'), + ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', + '\u{aaef}'), ('\u{aaf2}', '\u{aaf5}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), + ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', + '\u{ab5a}'), ('\u{ab5c}', '\u{ab69}'), ('\u{ab70}', '\u{abea}'), ('\u{ac00}', '\u{d7a3}'), + ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}', + '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}', '\u{fb28}'), + ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', + '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), + ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', + '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}', '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}'), + ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', + '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}', '\u{1000b}'), ('\u{1000d}', + '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', + '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}', '\u{100fa}'), ('\u{10140}', + '\u{10174}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}', + '\u{1031f}'), ('\u{1032d}', '\u{1034a}'), ('\u{10350}', '\u{1037a}'), ('\u{10380}', + '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{103d1}', + '\u{103d5}'), ('\u{10400}', '\u{1049d}'), ('\u{104b0}', '\u{104d3}'), ('\u{104d8}', + '\u{104fb}'), ('\u{10500}', '\u{10527}'), ('\u{10530}', '\u{10563}'), ('\u{10570}', + '\u{1057a}'), ('\u{1057c}', '\u{1058a}'), ('\u{1058c}', '\u{10592}'), ('\u{10594}', + '\u{10595}'), ('\u{10597}', '\u{105a1}'), ('\u{105a3}', '\u{105b1}'), ('\u{105b3}', + '\u{105b9}'), ('\u{105bb}', '\u{105bc}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', + '\u{10755}'), ('\u{10760}', '\u{10767}'), ('\u{10780}', '\u{10785}'), ('\u{10787}', + '\u{107b0}'), ('\u{107b2}', '\u{107ba}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', + '\u{10808}'), ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', + '\u{1083c}'), ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', + '\u{1089e}'), ('\u{108e0}', '\u{108f2}'), ('\u{108f4}', '\u{108f5}'), ('\u{10900}', + '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}', + '\u{109bf}'), ('\u{10a00}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'), ('\u{10a0c}', + '\u{10a13}'), ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a35}'), ('\u{10a60}', + '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', + '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', + '\u{10b72}'), ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{10c80}', + '\u{10cb2}'), ('\u{10cc0}', '\u{10cf2}'), ('\u{10d00}', '\u{10d27}'), ('\u{10e80}', + '\u{10ea9}'), ('\u{10eab}', '\u{10eac}'), ('\u{10eb0}', '\u{10eb1}'), ('\u{10f00}', + '\u{10f1c}'), ('\u{10f27}', '\u{10f27}'), ('\u{10f30}', '\u{10f45}'), ('\u{10f70}', + '\u{10f81}'), ('\u{10fb0}', '\u{10fc4}'), ('\u{10fe0}', '\u{10ff6}'), ('\u{11000}', + '\u{11045}'), ('\u{11071}', '\u{11075}'), ('\u{11080}', '\u{110b8}'), ('\u{110c2}', + '\u{110c2}'), ('\u{110d0}', '\u{110e8}'), ('\u{11100}', '\u{11132}'), ('\u{11144}', + '\u{11147}'), ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11180}', + '\u{111bf}'), ('\u{111c1}', '\u{111c4}'), ('\u{111ce}', '\u{111cf}'), ('\u{111da}', + '\u{111da}'), ('\u{111dc}', '\u{111dc}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', + '\u{11234}'), ('\u{11237}', '\u{11237}'), ('\u{1123e}', '\u{11241}'), ('\u{11280}', + '\u{11286}'), ('\u{11288}', '\u{11288}'), ('\u{1128a}', '\u{1128d}'), ('\u{1128f}', + '\u{1129d}'), ('\u{1129f}', '\u{112a8}'), ('\u{112b0}', '\u{112e8}'), ('\u{11300}', + '\u{11303}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}', '\u{11310}'), ('\u{11313}', + '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}', '\u{11333}'), ('\u{11335}', + '\u{11339}'), ('\u{1133d}', '\u{11344}'), ('\u{11347}', '\u{11348}'), ('\u{1134b}', + '\u{1134c}'), ('\u{11350}', '\u{11350}'), ('\u{11357}', '\u{11357}'), ('\u{1135d}', + '\u{11363}'), ('\u{11400}', '\u{11441}'), ('\u{11443}', '\u{11445}'), ('\u{11447}', + '\u{1144a}'), ('\u{1145f}', '\u{11461}'), ('\u{11480}', '\u{114c1}'), ('\u{114c4}', + '\u{114c5}'), ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115b5}'), ('\u{115b8}', + '\u{115be}'), ('\u{115d8}', '\u{115dd}'), ('\u{11600}', '\u{1163e}'), ('\u{11640}', + '\u{11640}'), ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116b5}'), ('\u{116b8}', + '\u{116b8}'), ('\u{11700}', '\u{1171a}'), ('\u{1171d}', '\u{1172a}'), ('\u{11740}', + '\u{11746}'), ('\u{11800}', '\u{11838}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}', + '\u{11906}'), ('\u{11909}', '\u{11909}'), ('\u{1190c}', '\u{11913}'), ('\u{11915}', + '\u{11916}'), ('\u{11918}', '\u{11935}'), ('\u{11937}', '\u{11938}'), ('\u{1193b}', + '\u{1193c}'), ('\u{1193f}', '\u{11942}'), ('\u{119a0}', '\u{119a7}'), ('\u{119aa}', + '\u{119d7}'), ('\u{119da}', '\u{119df}'), ('\u{119e1}', '\u{119e1}'), ('\u{119e3}', + '\u{119e4}'), ('\u{11a00}', '\u{11a32}'), ('\u{11a35}', '\u{11a3e}'), ('\u{11a50}', + '\u{11a97}'), ('\u{11a9d}', '\u{11a9d}'), ('\u{11ab0}', '\u{11af8}'), ('\u{11c00}', + '\u{11c08}'), ('\u{11c0a}', '\u{11c36}'), ('\u{11c38}', '\u{11c3e}'), ('\u{11c40}', + '\u{11c40}'), ('\u{11c72}', '\u{11c8f}'), ('\u{11c92}', '\u{11ca7}'), ('\u{11ca9}', + '\u{11cb6}'), ('\u{11d00}', '\u{11d06}'), ('\u{11d08}', '\u{11d09}'), ('\u{11d0b}', + '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', '\u{11d3d}'), ('\u{11d3f}', + '\u{11d41}'), ('\u{11d43}', '\u{11d43}'), ('\u{11d46}', '\u{11d47}'), ('\u{11d60}', + '\u{11d65}'), ('\u{11d67}', '\u{11d68}'), ('\u{11d6a}', '\u{11d8e}'), ('\u{11d90}', + '\u{11d91}'), ('\u{11d93}', '\u{11d96}'), ('\u{11d98}', '\u{11d98}'), ('\u{11ee0}', + '\u{11ef6}'), ('\u{11f00}', '\u{11f10}'), ('\u{11f12}', '\u{11f3a}'), ('\u{11f3e}', + '\u{11f40}'), ('\u{11fb0}', '\u{11fb0}'), ('\u{12000}', '\u{12399}'), ('\u{12400}', + '\u{1246e}'), ('\u{12480}', '\u{12543}'), ('\u{12f90}', '\u{12ff0}'), ('\u{13000}', + '\u{1342f}'), ('\u{13441}', '\u{13446}'), ('\u{14400}', '\u{14646}'), ('\u{16800}', + '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16a70}', '\u{16abe}'), ('\u{16ad0}', + '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}', + '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'), ('\u{16e40}', '\u{16e7f}'), ('\u{16f00}', + '\u{16f4a}'), ('\u{16f4f}', '\u{16f87}'), ('\u{16f8f}', '\u{16f9f}'), ('\u{16fe0}', + '\u{16fe1}'), ('\u{16fe3}', '\u{16fe3}'), ('\u{16ff0}', '\u{16ff1}'), ('\u{17000}', + '\u{187f7}'), ('\u{18800}', '\u{18cd5}'), ('\u{18d00}', '\u{18d08}'), ('\u{1aff0}', + '\u{1aff3}'), ('\u{1aff5}', '\u{1affb}'), ('\u{1affd}', '\u{1affe}'), ('\u{1b000}', + '\u{1b122}'), ('\u{1b132}', '\u{1b132}'), ('\u{1b150}', '\u{1b152}'), ('\u{1b155}', + '\u{1b155}'), ('\u{1b164}', '\u{1b167}'), ('\u{1b170}', '\u{1b2fb}'), ('\u{1bc00}', + '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}', + '\u{1bc99}'), ('\u{1bc9e}', '\u{1bc9e}'), ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', + '\u{1d49c}'), ('\u{1d49e}', '\u{1d49f}'), ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', + '\u{1d4a6}'), ('\u{1d4a9}', '\u{1d4ac}'), ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', + '\u{1d4bb}'), ('\u{1d4bd}', '\u{1d4c3}'), ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', + '\u{1d50a}'), ('\u{1d50d}', '\u{1d514}'), ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', + '\u{1d539}'), ('\u{1d53b}', '\u{1d53e}'), ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', + '\u{1d546}'), ('\u{1d54a}', '\u{1d550}'), ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', + '\u{1d6c0}'), ('\u{1d6c2}', '\u{1d6da}'), ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', + '\u{1d714}'), ('\u{1d716}', '\u{1d734}'), ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', + '\u{1d76e}'), ('\u{1d770}', '\u{1d788}'), ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', + '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'), ('\u{1df00}', '\u{1df1e}'), ('\u{1df25}', + '\u{1df2a}'), ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', + '\u{1e021}'), ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'), ('\u{1e030}', + '\u{1e06d}'), ('\u{1e08f}', '\u{1e08f}'), ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', + '\u{1e13d}'), ('\u{1e14e}', '\u{1e14e}'), ('\u{1e290}', '\u{1e2ad}'), ('\u{1e2c0}', + '\u{1e2eb}'), ('\u{1e4d0}', '\u{1e4eb}'), ('\u{1e7e0}', '\u{1e7e6}'), ('\u{1e7e8}', + '\u{1e7eb}'), ('\u{1e7ed}', '\u{1e7ee}'), ('\u{1e7f0}', '\u{1e7fe}'), ('\u{1e800}', + '\u{1e8c4}'), ('\u{1e900}', '\u{1e943}'), ('\u{1e947}', '\u{1e947}'), ('\u{1e94b}', + '\u{1e94b}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', + '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', + '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', + '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', + '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', + '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', + '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', + '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', + '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', + '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', + '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', + '\u{1eebb}'), ('\u{1f130}', '\u{1f149}'), ('\u{1f150}', '\u{1f169}'), ('\u{1f170}', + '\u{1f189}'), ('\u{20000}', '\u{2a6df}'), ('\u{2a700}', '\u{2b739}'), ('\u{2b740}', + '\u{2b81d}'), ('\u{2b820}', '\u{2cea1}'), ('\u{2ceb0}', '\u{2ebe0}'), ('\u{2f800}', + '\u{2fa1d}'), ('\u{30000}', '\u{3134a}'), ('\u{31350}', '\u{323af}') ]; #[inline] @@ -441,55 +445,56 @@ pub mod grapheme { GC_Extend), ('\u{cc3}', '\u{cc4}', GC_SpacingMark), ('\u{cc6}', '\u{cc6}', GC_Extend), ('\u{cc7}', '\u{cc8}', GC_SpacingMark), ('\u{cca}', '\u{ccb}', GC_SpacingMark), ('\u{ccc}', '\u{ccd}', GC_Extend), ('\u{cd5}', '\u{cd6}', GC_Extend), ('\u{ce2}', '\u{ce3}', GC_Extend), - ('\u{d00}', '\u{d01}', GC_Extend), ('\u{d02}', '\u{d03}', GC_SpacingMark), ('\u{d3b}', - '\u{d3c}', GC_Extend), ('\u{d3e}', '\u{d3e}', GC_Extend), ('\u{d3f}', '\u{d40}', - GC_SpacingMark), ('\u{d41}', '\u{d44}', GC_Extend), ('\u{d46}', '\u{d48}', GC_SpacingMark), - ('\u{d4a}', '\u{d4c}', GC_SpacingMark), ('\u{d4d}', '\u{d4d}', GC_Extend), ('\u{d4e}', - '\u{d4e}', GC_Prepend), ('\u{d57}', '\u{d57}', GC_Extend), ('\u{d62}', '\u{d63}', - GC_Extend), ('\u{d81}', '\u{d81}', GC_Extend), ('\u{d82}', '\u{d83}', GC_SpacingMark), - ('\u{dca}', '\u{dca}', GC_Extend), ('\u{dcf}', '\u{dcf}', GC_Extend), ('\u{dd0}', '\u{dd1}', - GC_SpacingMark), ('\u{dd2}', '\u{dd4}', GC_Extend), ('\u{dd6}', '\u{dd6}', GC_Extend), - ('\u{dd8}', '\u{dde}', GC_SpacingMark), ('\u{ddf}', '\u{ddf}', GC_Extend), ('\u{df2}', - '\u{df3}', GC_SpacingMark), ('\u{e31}', '\u{e31}', GC_Extend), ('\u{e33}', '\u{e33}', - GC_SpacingMark), ('\u{e34}', '\u{e3a}', GC_Extend), ('\u{e47}', '\u{e4e}', GC_Extend), - ('\u{eb1}', '\u{eb1}', GC_Extend), ('\u{eb3}', '\u{eb3}', GC_SpacingMark), ('\u{eb4}', - '\u{ebc}', GC_Extend), ('\u{ec8}', '\u{ecd}', GC_Extend), ('\u{f18}', '\u{f19}', GC_Extend), - ('\u{f35}', '\u{f35}', GC_Extend), ('\u{f37}', '\u{f37}', GC_Extend), ('\u{f39}', '\u{f39}', - GC_Extend), ('\u{f3e}', '\u{f3f}', GC_SpacingMark), ('\u{f71}', '\u{f7e}', GC_Extend), - ('\u{f7f}', '\u{f7f}', GC_SpacingMark), ('\u{f80}', '\u{f84}', GC_Extend), ('\u{f86}', - '\u{f87}', GC_Extend), ('\u{f8d}', '\u{f97}', GC_Extend), ('\u{f99}', '\u{fbc}', GC_Extend), - ('\u{fc6}', '\u{fc6}', GC_Extend), ('\u{102d}', '\u{1030}', GC_Extend), ('\u{1031}', - '\u{1031}', GC_SpacingMark), ('\u{1032}', '\u{1037}', GC_Extend), ('\u{1039}', '\u{103a}', - GC_Extend), ('\u{103b}', '\u{103c}', GC_SpacingMark), ('\u{103d}', '\u{103e}', GC_Extend), - ('\u{1056}', '\u{1057}', GC_SpacingMark), ('\u{1058}', '\u{1059}', GC_Extend), ('\u{105e}', - '\u{1060}', GC_Extend), ('\u{1071}', '\u{1074}', GC_Extend), ('\u{1082}', '\u{1082}', - GC_Extend), ('\u{1084}', '\u{1084}', GC_SpacingMark), ('\u{1085}', '\u{1086}', GC_Extend), - ('\u{108d}', '\u{108d}', GC_Extend), ('\u{109d}', '\u{109d}', GC_Extend), ('\u{1100}', - '\u{115f}', GC_L), ('\u{1160}', '\u{11a7}', GC_V), ('\u{11a8}', '\u{11ff}', GC_T), - ('\u{135d}', '\u{135f}', GC_Extend), ('\u{1712}', '\u{1714}', GC_Extend), ('\u{1715}', - '\u{1715}', GC_SpacingMark), ('\u{1732}', '\u{1733}', GC_Extend), ('\u{1734}', '\u{1734}', - GC_SpacingMark), ('\u{1752}', '\u{1753}', GC_Extend), ('\u{1772}', '\u{1773}', GC_Extend), - ('\u{17b4}', '\u{17b5}', GC_Extend), ('\u{17b6}', '\u{17b6}', GC_SpacingMark), ('\u{17b7}', - '\u{17bd}', GC_Extend), ('\u{17be}', '\u{17c5}', GC_SpacingMark), ('\u{17c6}', '\u{17c6}', - GC_Extend), ('\u{17c7}', '\u{17c8}', GC_SpacingMark), ('\u{17c9}', '\u{17d3}', GC_Extend), - ('\u{17dd}', '\u{17dd}', GC_Extend), ('\u{180b}', '\u{180d}', GC_Extend), ('\u{180e}', - '\u{180e}', GC_Control), ('\u{180f}', '\u{180f}', GC_Extend), ('\u{1885}', '\u{1886}', - GC_Extend), ('\u{18a9}', '\u{18a9}', GC_Extend), ('\u{1920}', '\u{1922}', GC_Extend), - ('\u{1923}', '\u{1926}', GC_SpacingMark), ('\u{1927}', '\u{1928}', GC_Extend), ('\u{1929}', - '\u{192b}', GC_SpacingMark), ('\u{1930}', '\u{1931}', GC_SpacingMark), ('\u{1932}', - '\u{1932}', GC_Extend), ('\u{1933}', '\u{1938}', GC_SpacingMark), ('\u{1939}', '\u{193b}', - GC_Extend), ('\u{1a17}', '\u{1a18}', GC_Extend), ('\u{1a19}', '\u{1a1a}', GC_SpacingMark), - ('\u{1a1b}', '\u{1a1b}', GC_Extend), ('\u{1a55}', '\u{1a55}', GC_SpacingMark), ('\u{1a56}', - '\u{1a56}', GC_Extend), ('\u{1a57}', '\u{1a57}', GC_SpacingMark), ('\u{1a58}', '\u{1a5e}', - GC_Extend), ('\u{1a60}', '\u{1a60}', GC_Extend), ('\u{1a62}', '\u{1a62}', GC_Extend), - ('\u{1a65}', '\u{1a6c}', GC_Extend), ('\u{1a6d}', '\u{1a72}', GC_SpacingMark), ('\u{1a73}', - '\u{1a7c}', GC_Extend), ('\u{1a7f}', '\u{1a7f}', GC_Extend), ('\u{1ab0}', '\u{1ace}', - GC_Extend), ('\u{1b00}', '\u{1b03}', GC_Extend), ('\u{1b04}', '\u{1b04}', GC_SpacingMark), - ('\u{1b34}', '\u{1b3a}', GC_Extend), ('\u{1b3b}', '\u{1b3b}', GC_SpacingMark), ('\u{1b3c}', - '\u{1b3c}', GC_Extend), ('\u{1b3d}', '\u{1b41}', GC_SpacingMark), ('\u{1b42}', '\u{1b42}', - GC_Extend), ('\u{1b43}', '\u{1b44}', GC_SpacingMark), ('\u{1b6b}', '\u{1b73}', GC_Extend), - ('\u{1b80}', '\u{1b81}', GC_Extend), ('\u{1b82}', '\u{1b82}', GC_SpacingMark), ('\u{1ba1}', - '\u{1ba1}', GC_SpacingMark), ('\u{1ba2}', '\u{1ba5}', GC_Extend), ('\u{1ba6}', '\u{1ba7}', + ('\u{cf3}', '\u{cf3}', GC_SpacingMark), ('\u{d00}', '\u{d01}', GC_Extend), ('\u{d02}', + '\u{d03}', GC_SpacingMark), ('\u{d3b}', '\u{d3c}', GC_Extend), ('\u{d3e}', '\u{d3e}', + GC_Extend), ('\u{d3f}', '\u{d40}', GC_SpacingMark), ('\u{d41}', '\u{d44}', GC_Extend), + ('\u{d46}', '\u{d48}', GC_SpacingMark), ('\u{d4a}', '\u{d4c}', GC_SpacingMark), ('\u{d4d}', + '\u{d4d}', GC_Extend), ('\u{d4e}', '\u{d4e}', GC_Prepend), ('\u{d57}', '\u{d57}', + GC_Extend), ('\u{d62}', '\u{d63}', GC_Extend), ('\u{d81}', '\u{d81}', GC_Extend), + ('\u{d82}', '\u{d83}', GC_SpacingMark), ('\u{dca}', '\u{dca}', GC_Extend), ('\u{dcf}', + '\u{dcf}', GC_Extend), ('\u{dd0}', '\u{dd1}', GC_SpacingMark), ('\u{dd2}', '\u{dd4}', + GC_Extend), ('\u{dd6}', '\u{dd6}', GC_Extend), ('\u{dd8}', '\u{dde}', GC_SpacingMark), + ('\u{ddf}', '\u{ddf}', GC_Extend), ('\u{df2}', '\u{df3}', GC_SpacingMark), ('\u{e31}', + '\u{e31}', GC_Extend), ('\u{e33}', '\u{e33}', GC_SpacingMark), ('\u{e34}', '\u{e3a}', + GC_Extend), ('\u{e47}', '\u{e4e}', GC_Extend), ('\u{eb1}', '\u{eb1}', GC_Extend), + ('\u{eb3}', '\u{eb3}', GC_SpacingMark), ('\u{eb4}', '\u{ebc}', GC_Extend), ('\u{ec8}', + '\u{ece}', GC_Extend), ('\u{f18}', '\u{f19}', GC_Extend), ('\u{f35}', '\u{f35}', GC_Extend), + ('\u{f37}', '\u{f37}', GC_Extend), ('\u{f39}', '\u{f39}', GC_Extend), ('\u{f3e}', '\u{f3f}', + GC_SpacingMark), ('\u{f71}', '\u{f7e}', GC_Extend), ('\u{f7f}', '\u{f7f}', GC_SpacingMark), + ('\u{f80}', '\u{f84}', GC_Extend), ('\u{f86}', '\u{f87}', GC_Extend), ('\u{f8d}', '\u{f97}', + GC_Extend), ('\u{f99}', '\u{fbc}', GC_Extend), ('\u{fc6}', '\u{fc6}', GC_Extend), + ('\u{102d}', '\u{1030}', GC_Extend), ('\u{1031}', '\u{1031}', GC_SpacingMark), ('\u{1032}', + '\u{1037}', GC_Extend), ('\u{1039}', '\u{103a}', GC_Extend), ('\u{103b}', '\u{103c}', + GC_SpacingMark), ('\u{103d}', '\u{103e}', GC_Extend), ('\u{1056}', '\u{1057}', + GC_SpacingMark), ('\u{1058}', '\u{1059}', GC_Extend), ('\u{105e}', '\u{1060}', GC_Extend), + ('\u{1071}', '\u{1074}', GC_Extend), ('\u{1082}', '\u{1082}', GC_Extend), ('\u{1084}', + '\u{1084}', GC_SpacingMark), ('\u{1085}', '\u{1086}', GC_Extend), ('\u{108d}', '\u{108d}', + GC_Extend), ('\u{109d}', '\u{109d}', GC_Extend), ('\u{1100}', '\u{115f}', GC_L), + ('\u{1160}', '\u{11a7}', GC_V), ('\u{11a8}', '\u{11ff}', GC_T), ('\u{135d}', '\u{135f}', + GC_Extend), ('\u{1712}', '\u{1714}', GC_Extend), ('\u{1715}', '\u{1715}', GC_SpacingMark), + ('\u{1732}', '\u{1733}', GC_Extend), ('\u{1734}', '\u{1734}', GC_SpacingMark), ('\u{1752}', + '\u{1753}', GC_Extend), ('\u{1772}', '\u{1773}', GC_Extend), ('\u{17b4}', '\u{17b5}', + GC_Extend), ('\u{17b6}', '\u{17b6}', GC_SpacingMark), ('\u{17b7}', '\u{17bd}', GC_Extend), + ('\u{17be}', '\u{17c5}', GC_SpacingMark), ('\u{17c6}', '\u{17c6}', GC_Extend), ('\u{17c7}', + '\u{17c8}', GC_SpacingMark), ('\u{17c9}', '\u{17d3}', GC_Extend), ('\u{17dd}', '\u{17dd}', + GC_Extend), ('\u{180b}', '\u{180d}', GC_Extend), ('\u{180e}', '\u{180e}', GC_Control), + ('\u{180f}', '\u{180f}', GC_Extend), ('\u{1885}', '\u{1886}', GC_Extend), ('\u{18a9}', + '\u{18a9}', GC_Extend), ('\u{1920}', '\u{1922}', GC_Extend), ('\u{1923}', '\u{1926}', + GC_SpacingMark), ('\u{1927}', '\u{1928}', GC_Extend), ('\u{1929}', '\u{192b}', + GC_SpacingMark), ('\u{1930}', '\u{1931}', GC_SpacingMark), ('\u{1932}', '\u{1932}', + GC_Extend), ('\u{1933}', '\u{1938}', GC_SpacingMark), ('\u{1939}', '\u{193b}', GC_Extend), + ('\u{1a17}', '\u{1a18}', GC_Extend), ('\u{1a19}', '\u{1a1a}', GC_SpacingMark), ('\u{1a1b}', + '\u{1a1b}', GC_Extend), ('\u{1a55}', '\u{1a55}', GC_SpacingMark), ('\u{1a56}', '\u{1a56}', + GC_Extend), ('\u{1a57}', '\u{1a57}', GC_SpacingMark), ('\u{1a58}', '\u{1a5e}', GC_Extend), + ('\u{1a60}', '\u{1a60}', GC_Extend), ('\u{1a62}', '\u{1a62}', GC_Extend), ('\u{1a65}', + '\u{1a6c}', GC_Extend), ('\u{1a6d}', '\u{1a72}', GC_SpacingMark), ('\u{1a73}', '\u{1a7c}', + GC_Extend), ('\u{1a7f}', '\u{1a7f}', GC_Extend), ('\u{1ab0}', '\u{1ace}', GC_Extend), + ('\u{1b00}', '\u{1b03}', GC_Extend), ('\u{1b04}', '\u{1b04}', GC_SpacingMark), ('\u{1b34}', + '\u{1b3a}', GC_Extend), ('\u{1b3b}', '\u{1b3b}', GC_SpacingMark), ('\u{1b3c}', '\u{1b3c}', + GC_Extend), ('\u{1b3d}', '\u{1b41}', GC_SpacingMark), ('\u{1b42}', '\u{1b42}', GC_Extend), + ('\u{1b43}', '\u{1b44}', GC_SpacingMark), ('\u{1b6b}', '\u{1b73}', GC_Extend), ('\u{1b80}', + '\u{1b81}', GC_Extend), ('\u{1b82}', '\u{1b82}', GC_SpacingMark), ('\u{1ba1}', '\u{1ba1}', + GC_SpacingMark), ('\u{1ba2}', '\u{1ba5}', GC_Extend), ('\u{1ba6}', '\u{1ba7}', GC_SpacingMark), ('\u{1ba8}', '\u{1ba9}', GC_Extend), ('\u{1baa}', '\u{1baa}', GC_SpacingMark), ('\u{1bab}', '\u{1bad}', GC_Extend), ('\u{1be6}', '\u{1be6}', GC_Extend), ('\u{1be7}', '\u{1be7}', GC_SpacingMark), ('\u{1be8}', '\u{1be9}', GC_Extend), ('\u{1bea}', @@ -866,74 +871,75 @@ pub mod grapheme { ('\u{10a01}', '\u{10a03}', GC_Extend), ('\u{10a05}', '\u{10a06}', GC_Extend), ('\u{10a0c}', '\u{10a0f}', GC_Extend), ('\u{10a38}', '\u{10a3a}', GC_Extend), ('\u{10a3f}', '\u{10a3f}', GC_Extend), ('\u{10ae5}', '\u{10ae6}', GC_Extend), ('\u{10d24}', '\u{10d27}', GC_Extend), - ('\u{10eab}', '\u{10eac}', GC_Extend), ('\u{10f46}', '\u{10f50}', GC_Extend), ('\u{10f82}', - '\u{10f85}', GC_Extend), ('\u{11000}', '\u{11000}', GC_SpacingMark), ('\u{11001}', - '\u{11001}', GC_Extend), ('\u{11002}', '\u{11002}', GC_SpacingMark), ('\u{11038}', - '\u{11046}', GC_Extend), ('\u{11070}', '\u{11070}', GC_Extend), ('\u{11073}', '\u{11074}', - GC_Extend), ('\u{1107f}', '\u{11081}', GC_Extend), ('\u{11082}', '\u{11082}', - GC_SpacingMark), ('\u{110b0}', '\u{110b2}', GC_SpacingMark), ('\u{110b3}', '\u{110b6}', - GC_Extend), ('\u{110b7}', '\u{110b8}', GC_SpacingMark), ('\u{110b9}', '\u{110ba}', - GC_Extend), ('\u{110bd}', '\u{110bd}', GC_Prepend), ('\u{110c2}', '\u{110c2}', GC_Extend), - ('\u{110cd}', '\u{110cd}', GC_Prepend), ('\u{11100}', '\u{11102}', GC_Extend), ('\u{11127}', - '\u{1112b}', GC_Extend), ('\u{1112c}', '\u{1112c}', GC_SpacingMark), ('\u{1112d}', - '\u{11134}', GC_Extend), ('\u{11145}', '\u{11146}', GC_SpacingMark), ('\u{11173}', - '\u{11173}', GC_Extend), ('\u{11180}', '\u{11181}', GC_Extend), ('\u{11182}', '\u{11182}', - GC_SpacingMark), ('\u{111b3}', '\u{111b5}', GC_SpacingMark), ('\u{111b6}', '\u{111be}', - GC_Extend), ('\u{111bf}', '\u{111c0}', GC_SpacingMark), ('\u{111c2}', '\u{111c3}', - GC_Prepend), ('\u{111c9}', '\u{111cc}', GC_Extend), ('\u{111ce}', '\u{111ce}', - GC_SpacingMark), ('\u{111cf}', '\u{111cf}', GC_Extend), ('\u{1122c}', '\u{1122e}', - GC_SpacingMark), ('\u{1122f}', '\u{11231}', GC_Extend), ('\u{11232}', '\u{11233}', - GC_SpacingMark), ('\u{11234}', '\u{11234}', GC_Extend), ('\u{11235}', '\u{11235}', - GC_SpacingMark), ('\u{11236}', '\u{11237}', GC_Extend), ('\u{1123e}', '\u{1123e}', - GC_Extend), ('\u{112df}', '\u{112df}', GC_Extend), ('\u{112e0}', '\u{112e2}', - GC_SpacingMark), ('\u{112e3}', '\u{112ea}', GC_Extend), ('\u{11300}', '\u{11301}', - GC_Extend), ('\u{11302}', '\u{11303}', GC_SpacingMark), ('\u{1133b}', '\u{1133c}', - GC_Extend), ('\u{1133e}', '\u{1133e}', GC_Extend), ('\u{1133f}', '\u{1133f}', - GC_SpacingMark), ('\u{11340}', '\u{11340}', GC_Extend), ('\u{11341}', '\u{11344}', - GC_SpacingMark), ('\u{11347}', '\u{11348}', GC_SpacingMark), ('\u{1134b}', '\u{1134d}', - GC_SpacingMark), ('\u{11357}', '\u{11357}', GC_Extend), ('\u{11362}', '\u{11363}', - GC_SpacingMark), ('\u{11366}', '\u{1136c}', GC_Extend), ('\u{11370}', '\u{11374}', - GC_Extend), ('\u{11435}', '\u{11437}', GC_SpacingMark), ('\u{11438}', '\u{1143f}', - GC_Extend), ('\u{11440}', '\u{11441}', GC_SpacingMark), ('\u{11442}', '\u{11444}', - GC_Extend), ('\u{11445}', '\u{11445}', GC_SpacingMark), ('\u{11446}', '\u{11446}', - GC_Extend), ('\u{1145e}', '\u{1145e}', GC_Extend), ('\u{114b0}', '\u{114b0}', GC_Extend), - ('\u{114b1}', '\u{114b2}', GC_SpacingMark), ('\u{114b3}', '\u{114b8}', GC_Extend), - ('\u{114b9}', '\u{114b9}', GC_SpacingMark), ('\u{114ba}', '\u{114ba}', GC_Extend), - ('\u{114bb}', '\u{114bc}', GC_SpacingMark), ('\u{114bd}', '\u{114bd}', GC_Extend), - ('\u{114be}', '\u{114be}', GC_SpacingMark), ('\u{114bf}', '\u{114c0}', GC_Extend), - ('\u{114c1}', '\u{114c1}', GC_SpacingMark), ('\u{114c2}', '\u{114c3}', GC_Extend), - ('\u{115af}', '\u{115af}', GC_Extend), ('\u{115b0}', '\u{115b1}', GC_SpacingMark), - ('\u{115b2}', '\u{115b5}', GC_Extend), ('\u{115b8}', '\u{115bb}', GC_SpacingMark), - ('\u{115bc}', '\u{115bd}', GC_Extend), ('\u{115be}', '\u{115be}', GC_SpacingMark), - ('\u{115bf}', '\u{115c0}', GC_Extend), ('\u{115dc}', '\u{115dd}', GC_Extend), ('\u{11630}', - '\u{11632}', GC_SpacingMark), ('\u{11633}', '\u{1163a}', GC_Extend), ('\u{1163b}', - '\u{1163c}', GC_SpacingMark), ('\u{1163d}', '\u{1163d}', GC_Extend), ('\u{1163e}', - '\u{1163e}', GC_SpacingMark), ('\u{1163f}', '\u{11640}', GC_Extend), ('\u{116ab}', - '\u{116ab}', GC_Extend), ('\u{116ac}', '\u{116ac}', GC_SpacingMark), ('\u{116ad}', - '\u{116ad}', GC_Extend), ('\u{116ae}', '\u{116af}', GC_SpacingMark), ('\u{116b0}', - '\u{116b5}', GC_Extend), ('\u{116b6}', '\u{116b6}', GC_SpacingMark), ('\u{116b7}', - '\u{116b7}', GC_Extend), ('\u{1171d}', '\u{1171f}', GC_Extend), ('\u{11722}', '\u{11725}', - GC_Extend), ('\u{11726}', '\u{11726}', GC_SpacingMark), ('\u{11727}', '\u{1172b}', - GC_Extend), ('\u{1182c}', '\u{1182e}', GC_SpacingMark), ('\u{1182f}', '\u{11837}', - GC_Extend), ('\u{11838}', '\u{11838}', GC_SpacingMark), ('\u{11839}', '\u{1183a}', - GC_Extend), ('\u{11930}', '\u{11930}', GC_Extend), ('\u{11931}', '\u{11935}', - GC_SpacingMark), ('\u{11937}', '\u{11938}', GC_SpacingMark), ('\u{1193b}', '\u{1193c}', - GC_Extend), ('\u{1193d}', '\u{1193d}', GC_SpacingMark), ('\u{1193e}', '\u{1193e}', - GC_Extend), ('\u{1193f}', '\u{1193f}', GC_Prepend), ('\u{11940}', '\u{11940}', - GC_SpacingMark), ('\u{11941}', '\u{11941}', GC_Prepend), ('\u{11942}', '\u{11942}', - GC_SpacingMark), ('\u{11943}', '\u{11943}', GC_Extend), ('\u{119d1}', '\u{119d3}', - GC_SpacingMark), ('\u{119d4}', '\u{119d7}', GC_Extend), ('\u{119da}', '\u{119db}', - GC_Extend), ('\u{119dc}', '\u{119df}', GC_SpacingMark), ('\u{119e0}', '\u{119e0}', - GC_Extend), ('\u{119e4}', '\u{119e4}', GC_SpacingMark), ('\u{11a01}', '\u{11a0a}', - GC_Extend), ('\u{11a33}', '\u{11a38}', GC_Extend), ('\u{11a39}', '\u{11a39}', - GC_SpacingMark), ('\u{11a3a}', '\u{11a3a}', GC_Prepend), ('\u{11a3b}', '\u{11a3e}', - GC_Extend), ('\u{11a47}', '\u{11a47}', GC_Extend), ('\u{11a51}', '\u{11a56}', GC_Extend), - ('\u{11a57}', '\u{11a58}', GC_SpacingMark), ('\u{11a59}', '\u{11a5b}', GC_Extend), - ('\u{11a84}', '\u{11a89}', GC_Prepend), ('\u{11a8a}', '\u{11a96}', GC_Extend), ('\u{11a97}', - '\u{11a97}', GC_SpacingMark), ('\u{11a98}', '\u{11a99}', GC_Extend), ('\u{11c2f}', - '\u{11c2f}', GC_SpacingMark), ('\u{11c30}', '\u{11c36}', GC_Extend), ('\u{11c38}', - '\u{11c3d}', GC_Extend), ('\u{11c3e}', '\u{11c3e}', GC_SpacingMark), ('\u{11c3f}', - '\u{11c3f}', GC_Extend), ('\u{11c92}', '\u{11ca7}', GC_Extend), ('\u{11ca9}', '\u{11ca9}', + ('\u{10eab}', '\u{10eac}', GC_Extend), ('\u{10efd}', '\u{10eff}', GC_Extend), ('\u{10f46}', + '\u{10f50}', GC_Extend), ('\u{10f82}', '\u{10f85}', GC_Extend), ('\u{11000}', '\u{11000}', + GC_SpacingMark), ('\u{11001}', '\u{11001}', GC_Extend), ('\u{11002}', '\u{11002}', + GC_SpacingMark), ('\u{11038}', '\u{11046}', GC_Extend), ('\u{11070}', '\u{11070}', + GC_Extend), ('\u{11073}', '\u{11074}', GC_Extend), ('\u{1107f}', '\u{11081}', GC_Extend), + ('\u{11082}', '\u{11082}', GC_SpacingMark), ('\u{110b0}', '\u{110b2}', GC_SpacingMark), + ('\u{110b3}', '\u{110b6}', GC_Extend), ('\u{110b7}', '\u{110b8}', GC_SpacingMark), + ('\u{110b9}', '\u{110ba}', GC_Extend), ('\u{110bd}', '\u{110bd}', GC_Prepend), ('\u{110c2}', + '\u{110c2}', GC_Extend), ('\u{110cd}', '\u{110cd}', GC_Prepend), ('\u{11100}', '\u{11102}', + GC_Extend), ('\u{11127}', '\u{1112b}', GC_Extend), ('\u{1112c}', '\u{1112c}', + GC_SpacingMark), ('\u{1112d}', '\u{11134}', GC_Extend), ('\u{11145}', '\u{11146}', + GC_SpacingMark), ('\u{11173}', '\u{11173}', GC_Extend), ('\u{11180}', '\u{11181}', + GC_Extend), ('\u{11182}', '\u{11182}', GC_SpacingMark), ('\u{111b3}', '\u{111b5}', + GC_SpacingMark), ('\u{111b6}', '\u{111be}', GC_Extend), ('\u{111bf}', '\u{111c0}', + GC_SpacingMark), ('\u{111c2}', '\u{111c3}', GC_Prepend), ('\u{111c9}', '\u{111cc}', + GC_Extend), ('\u{111ce}', '\u{111ce}', GC_SpacingMark), ('\u{111cf}', '\u{111cf}', + GC_Extend), ('\u{1122c}', '\u{1122e}', GC_SpacingMark), ('\u{1122f}', '\u{11231}', + GC_Extend), ('\u{11232}', '\u{11233}', GC_SpacingMark), ('\u{11234}', '\u{11234}', + GC_Extend), ('\u{11235}', '\u{11235}', GC_SpacingMark), ('\u{11236}', '\u{11237}', + GC_Extend), ('\u{1123e}', '\u{1123e}', GC_Extend), ('\u{11241}', '\u{11241}', GC_Extend), + ('\u{112df}', '\u{112df}', GC_Extend), ('\u{112e0}', '\u{112e2}', GC_SpacingMark), + ('\u{112e3}', '\u{112ea}', GC_Extend), ('\u{11300}', '\u{11301}', GC_Extend), ('\u{11302}', + '\u{11303}', GC_SpacingMark), ('\u{1133b}', '\u{1133c}', GC_Extend), ('\u{1133e}', + '\u{1133e}', GC_Extend), ('\u{1133f}', '\u{1133f}', GC_SpacingMark), ('\u{11340}', + '\u{11340}', GC_Extend), ('\u{11341}', '\u{11344}', GC_SpacingMark), ('\u{11347}', + '\u{11348}', GC_SpacingMark), ('\u{1134b}', '\u{1134d}', GC_SpacingMark), ('\u{11357}', + '\u{11357}', GC_Extend), ('\u{11362}', '\u{11363}', GC_SpacingMark), ('\u{11366}', + '\u{1136c}', GC_Extend), ('\u{11370}', '\u{11374}', GC_Extend), ('\u{11435}', '\u{11437}', + GC_SpacingMark), ('\u{11438}', '\u{1143f}', GC_Extend), ('\u{11440}', '\u{11441}', + GC_SpacingMark), ('\u{11442}', '\u{11444}', GC_Extend), ('\u{11445}', '\u{11445}', + GC_SpacingMark), ('\u{11446}', '\u{11446}', GC_Extend), ('\u{1145e}', '\u{1145e}', + GC_Extend), ('\u{114b0}', '\u{114b0}', GC_Extend), ('\u{114b1}', '\u{114b2}', + GC_SpacingMark), ('\u{114b3}', '\u{114b8}', GC_Extend), ('\u{114b9}', '\u{114b9}', + GC_SpacingMark), ('\u{114ba}', '\u{114ba}', GC_Extend), ('\u{114bb}', '\u{114bc}', + GC_SpacingMark), ('\u{114bd}', '\u{114bd}', GC_Extend), ('\u{114be}', '\u{114be}', + GC_SpacingMark), ('\u{114bf}', '\u{114c0}', GC_Extend), ('\u{114c1}', '\u{114c1}', + GC_SpacingMark), ('\u{114c2}', '\u{114c3}', GC_Extend), ('\u{115af}', '\u{115af}', + GC_Extend), ('\u{115b0}', '\u{115b1}', GC_SpacingMark), ('\u{115b2}', '\u{115b5}', + GC_Extend), ('\u{115b8}', '\u{115bb}', GC_SpacingMark), ('\u{115bc}', '\u{115bd}', + GC_Extend), ('\u{115be}', '\u{115be}', GC_SpacingMark), ('\u{115bf}', '\u{115c0}', + GC_Extend), ('\u{115dc}', '\u{115dd}', GC_Extend), ('\u{11630}', '\u{11632}', + GC_SpacingMark), ('\u{11633}', '\u{1163a}', GC_Extend), ('\u{1163b}', '\u{1163c}', + GC_SpacingMark), ('\u{1163d}', '\u{1163d}', GC_Extend), ('\u{1163e}', '\u{1163e}', + GC_SpacingMark), ('\u{1163f}', '\u{11640}', GC_Extend), ('\u{116ab}', '\u{116ab}', + GC_Extend), ('\u{116ac}', '\u{116ac}', GC_SpacingMark), ('\u{116ad}', '\u{116ad}', + GC_Extend), ('\u{116ae}', '\u{116af}', GC_SpacingMark), ('\u{116b0}', '\u{116b5}', + GC_Extend), ('\u{116b6}', '\u{116b6}', GC_SpacingMark), ('\u{116b7}', '\u{116b7}', + GC_Extend), ('\u{1171d}', '\u{1171f}', GC_Extend), ('\u{11722}', '\u{11725}', GC_Extend), + ('\u{11726}', '\u{11726}', GC_SpacingMark), ('\u{11727}', '\u{1172b}', GC_Extend), + ('\u{1182c}', '\u{1182e}', GC_SpacingMark), ('\u{1182f}', '\u{11837}', GC_Extend), + ('\u{11838}', '\u{11838}', GC_SpacingMark), ('\u{11839}', '\u{1183a}', GC_Extend), + ('\u{11930}', '\u{11930}', GC_Extend), ('\u{11931}', '\u{11935}', GC_SpacingMark), + ('\u{11937}', '\u{11938}', GC_SpacingMark), ('\u{1193b}', '\u{1193c}', GC_Extend), + ('\u{1193d}', '\u{1193d}', GC_SpacingMark), ('\u{1193e}', '\u{1193e}', GC_Extend), + ('\u{1193f}', '\u{1193f}', GC_Prepend), ('\u{11940}', '\u{11940}', GC_SpacingMark), + ('\u{11941}', '\u{11941}', GC_Prepend), ('\u{11942}', '\u{11942}', GC_SpacingMark), + ('\u{11943}', '\u{11943}', GC_Extend), ('\u{119d1}', '\u{119d3}', GC_SpacingMark), + ('\u{119d4}', '\u{119d7}', GC_Extend), ('\u{119da}', '\u{119db}', GC_Extend), ('\u{119dc}', + '\u{119df}', GC_SpacingMark), ('\u{119e0}', '\u{119e0}', GC_Extend), ('\u{119e4}', + '\u{119e4}', GC_SpacingMark), ('\u{11a01}', '\u{11a0a}', GC_Extend), ('\u{11a33}', + '\u{11a38}', GC_Extend), ('\u{11a39}', '\u{11a39}', GC_SpacingMark), ('\u{11a3a}', + '\u{11a3a}', GC_Prepend), ('\u{11a3b}', '\u{11a3e}', GC_Extend), ('\u{11a47}', '\u{11a47}', + GC_Extend), ('\u{11a51}', '\u{11a56}', GC_Extend), ('\u{11a57}', '\u{11a58}', + GC_SpacingMark), ('\u{11a59}', '\u{11a5b}', GC_Extend), ('\u{11a84}', '\u{11a89}', + GC_Prepend), ('\u{11a8a}', '\u{11a96}', GC_Extend), ('\u{11a97}', '\u{11a97}', + GC_SpacingMark), ('\u{11a98}', '\u{11a99}', GC_Extend), ('\u{11c2f}', '\u{11c2f}', + GC_SpacingMark), ('\u{11c30}', '\u{11c36}', GC_Extend), ('\u{11c38}', '\u{11c3d}', + GC_Extend), ('\u{11c3e}', '\u{11c3e}', GC_SpacingMark), ('\u{11c3f}', '\u{11c3f}', + GC_Extend), ('\u{11c92}', '\u{11ca7}', GC_Extend), ('\u{11ca9}', '\u{11ca9}', GC_SpacingMark), ('\u{11caa}', '\u{11cb0}', GC_Extend), ('\u{11cb1}', '\u{11cb1}', GC_SpacingMark), ('\u{11cb2}', '\u{11cb3}', GC_Extend), ('\u{11cb4}', '\u{11cb4}', GC_SpacingMark), ('\u{11cb5}', '\u{11cb6}', GC_Extend), ('\u{11d31}', '\u{11d36}', @@ -943,45 +949,52 @@ pub mod grapheme { '\u{11d91}', GC_Extend), ('\u{11d93}', '\u{11d94}', GC_SpacingMark), ('\u{11d95}', '\u{11d95}', GC_Extend), ('\u{11d96}', '\u{11d96}', GC_SpacingMark), ('\u{11d97}', '\u{11d97}', GC_Extend), ('\u{11ef3}', '\u{11ef4}', GC_Extend), ('\u{11ef5}', '\u{11ef6}', - GC_SpacingMark), ('\u{13430}', '\u{13438}', GC_Control), ('\u{16af0}', '\u{16af4}', - GC_Extend), ('\u{16b30}', '\u{16b36}', GC_Extend), ('\u{16f4f}', '\u{16f4f}', GC_Extend), - ('\u{16f51}', '\u{16f87}', GC_SpacingMark), ('\u{16f8f}', '\u{16f92}', GC_Extend), - ('\u{16fe4}', '\u{16fe4}', GC_Extend), ('\u{16ff0}', '\u{16ff1}', GC_SpacingMark), - ('\u{1bc9d}', '\u{1bc9e}', GC_Extend), ('\u{1bca0}', '\u{1bca3}', GC_Control), ('\u{1cf00}', - '\u{1cf2d}', GC_Extend), ('\u{1cf30}', '\u{1cf46}', GC_Extend), ('\u{1d165}', '\u{1d165}', - GC_Extend), ('\u{1d166}', '\u{1d166}', GC_SpacingMark), ('\u{1d167}', '\u{1d169}', - GC_Extend), ('\u{1d16d}', '\u{1d16d}', GC_SpacingMark), ('\u{1d16e}', '\u{1d172}', - GC_Extend), ('\u{1d173}', '\u{1d17a}', GC_Control), ('\u{1d17b}', '\u{1d182}', GC_Extend), - ('\u{1d185}', '\u{1d18b}', GC_Extend), ('\u{1d1aa}', '\u{1d1ad}', GC_Extend), ('\u{1d242}', - '\u{1d244}', GC_Extend), ('\u{1da00}', '\u{1da36}', GC_Extend), ('\u{1da3b}', '\u{1da6c}', - GC_Extend), ('\u{1da75}', '\u{1da75}', GC_Extend), ('\u{1da84}', '\u{1da84}', GC_Extend), - ('\u{1da9b}', '\u{1da9f}', GC_Extend), ('\u{1daa1}', '\u{1daaf}', GC_Extend), ('\u{1e000}', - '\u{1e006}', GC_Extend), ('\u{1e008}', '\u{1e018}', GC_Extend), ('\u{1e01b}', '\u{1e021}', - GC_Extend), ('\u{1e023}', '\u{1e024}', GC_Extend), ('\u{1e026}', '\u{1e02a}', GC_Extend), - ('\u{1e130}', '\u{1e136}', GC_Extend), ('\u{1e2ae}', '\u{1e2ae}', GC_Extend), ('\u{1e2ec}', - '\u{1e2ef}', GC_Extend), ('\u{1e8d0}', '\u{1e8d6}', GC_Extend), ('\u{1e944}', '\u{1e94a}', - GC_Extend), ('\u{1f000}', '\u{1f0ff}', GC_Extended_Pictographic), ('\u{1f10d}', '\u{1f10f}', - GC_Extended_Pictographic), ('\u{1f12f}', '\u{1f12f}', GC_Extended_Pictographic), - ('\u{1f16c}', '\u{1f171}', GC_Extended_Pictographic), ('\u{1f17e}', '\u{1f17f}', - GC_Extended_Pictographic), ('\u{1f18e}', '\u{1f18e}', GC_Extended_Pictographic), - ('\u{1f191}', '\u{1f19a}', GC_Extended_Pictographic), ('\u{1f1ad}', '\u{1f1e5}', - GC_Extended_Pictographic), ('\u{1f1e6}', '\u{1f1ff}', GC_Regional_Indicator), ('\u{1f201}', - '\u{1f20f}', GC_Extended_Pictographic), ('\u{1f21a}', '\u{1f21a}', - GC_Extended_Pictographic), ('\u{1f22f}', '\u{1f22f}', GC_Extended_Pictographic), - ('\u{1f232}', '\u{1f23a}', GC_Extended_Pictographic), ('\u{1f23c}', '\u{1f23f}', - GC_Extended_Pictographic), ('\u{1f249}', '\u{1f3fa}', GC_Extended_Pictographic), - ('\u{1f3fb}', '\u{1f3ff}', GC_Extend), ('\u{1f400}', '\u{1f53d}', GC_Extended_Pictographic), - ('\u{1f546}', '\u{1f64f}', GC_Extended_Pictographic), ('\u{1f680}', '\u{1f6ff}', - GC_Extended_Pictographic), ('\u{1f774}', '\u{1f77f}', GC_Extended_Pictographic), - ('\u{1f7d5}', '\u{1f7ff}', GC_Extended_Pictographic), ('\u{1f80c}', '\u{1f80f}', - GC_Extended_Pictographic), ('\u{1f848}', '\u{1f84f}', GC_Extended_Pictographic), - ('\u{1f85a}', '\u{1f85f}', GC_Extended_Pictographic), ('\u{1f888}', '\u{1f88f}', - GC_Extended_Pictographic), ('\u{1f8ae}', '\u{1f8ff}', GC_Extended_Pictographic), - ('\u{1f90c}', '\u{1f93a}', GC_Extended_Pictographic), ('\u{1f93c}', '\u{1f945}', - GC_Extended_Pictographic), ('\u{1f947}', '\u{1faff}', GC_Extended_Pictographic), - ('\u{1fc00}', '\u{1fffd}', GC_Extended_Pictographic), ('\u{e0000}', '\u{e001f}', - GC_Control), ('\u{e0020}', '\u{e007f}', GC_Extend), ('\u{e0080}', '\u{e00ff}', GC_Control), - ('\u{e0100}', '\u{e01ef}', GC_Extend), ('\u{e01f0}', '\u{e0fff}', GC_Control) + GC_SpacingMark), ('\u{11f00}', '\u{11f01}', GC_Extend), ('\u{11f02}', '\u{11f02}', + GC_Prepend), ('\u{11f03}', '\u{11f03}', GC_SpacingMark), ('\u{11f34}', '\u{11f35}', + GC_SpacingMark), ('\u{11f36}', '\u{11f3a}', GC_Extend), ('\u{11f3e}', '\u{11f3f}', + GC_SpacingMark), ('\u{11f40}', '\u{11f40}', GC_Extend), ('\u{11f41}', '\u{11f41}', + GC_SpacingMark), ('\u{11f42}', '\u{11f42}', GC_Extend), ('\u{13430}', '\u{1343f}', + GC_Control), ('\u{13440}', '\u{13440}', GC_Extend), ('\u{13447}', '\u{13455}', GC_Extend), + ('\u{16af0}', '\u{16af4}', GC_Extend), ('\u{16b30}', '\u{16b36}', GC_Extend), ('\u{16f4f}', + '\u{16f4f}', GC_Extend), ('\u{16f51}', '\u{16f87}', GC_SpacingMark), ('\u{16f8f}', + '\u{16f92}', GC_Extend), ('\u{16fe4}', '\u{16fe4}', GC_Extend), ('\u{16ff0}', '\u{16ff1}', + GC_SpacingMark), ('\u{1bc9d}', '\u{1bc9e}', GC_Extend), ('\u{1bca0}', '\u{1bca3}', + GC_Control), ('\u{1cf00}', '\u{1cf2d}', GC_Extend), ('\u{1cf30}', '\u{1cf46}', GC_Extend), + ('\u{1d165}', '\u{1d165}', GC_Extend), ('\u{1d166}', '\u{1d166}', GC_SpacingMark), + ('\u{1d167}', '\u{1d169}', GC_Extend), ('\u{1d16d}', '\u{1d16d}', GC_SpacingMark), + ('\u{1d16e}', '\u{1d172}', GC_Extend), ('\u{1d173}', '\u{1d17a}', GC_Control), ('\u{1d17b}', + '\u{1d182}', GC_Extend), ('\u{1d185}', '\u{1d18b}', GC_Extend), ('\u{1d1aa}', '\u{1d1ad}', + GC_Extend), ('\u{1d242}', '\u{1d244}', GC_Extend), ('\u{1da00}', '\u{1da36}', GC_Extend), + ('\u{1da3b}', '\u{1da6c}', GC_Extend), ('\u{1da75}', '\u{1da75}', GC_Extend), ('\u{1da84}', + '\u{1da84}', GC_Extend), ('\u{1da9b}', '\u{1da9f}', GC_Extend), ('\u{1daa1}', '\u{1daaf}', + GC_Extend), ('\u{1e000}', '\u{1e006}', GC_Extend), ('\u{1e008}', '\u{1e018}', GC_Extend), + ('\u{1e01b}', '\u{1e021}', GC_Extend), ('\u{1e023}', '\u{1e024}', GC_Extend), ('\u{1e026}', + '\u{1e02a}', GC_Extend), ('\u{1e08f}', '\u{1e08f}', GC_Extend), ('\u{1e130}', '\u{1e136}', + GC_Extend), ('\u{1e2ae}', '\u{1e2ae}', GC_Extend), ('\u{1e2ec}', '\u{1e2ef}', GC_Extend), + ('\u{1e4ec}', '\u{1e4ef}', GC_Extend), ('\u{1e8d0}', '\u{1e8d6}', GC_Extend), ('\u{1e944}', + '\u{1e94a}', GC_Extend), ('\u{1f000}', '\u{1f0ff}', GC_Extended_Pictographic), ('\u{1f10d}', + '\u{1f10f}', GC_Extended_Pictographic), ('\u{1f12f}', '\u{1f12f}', + GC_Extended_Pictographic), ('\u{1f16c}', '\u{1f171}', GC_Extended_Pictographic), + ('\u{1f17e}', '\u{1f17f}', GC_Extended_Pictographic), ('\u{1f18e}', '\u{1f18e}', + GC_Extended_Pictographic), ('\u{1f191}', '\u{1f19a}', GC_Extended_Pictographic), + ('\u{1f1ad}', '\u{1f1e5}', GC_Extended_Pictographic), ('\u{1f1e6}', '\u{1f1ff}', + GC_Regional_Indicator), ('\u{1f201}', '\u{1f20f}', GC_Extended_Pictographic), ('\u{1f21a}', + '\u{1f21a}', GC_Extended_Pictographic), ('\u{1f22f}', '\u{1f22f}', + GC_Extended_Pictographic), ('\u{1f232}', '\u{1f23a}', GC_Extended_Pictographic), + ('\u{1f23c}', '\u{1f23f}', GC_Extended_Pictographic), ('\u{1f249}', '\u{1f3fa}', + GC_Extended_Pictographic), ('\u{1f3fb}', '\u{1f3ff}', GC_Extend), ('\u{1f400}', '\u{1f53d}', + GC_Extended_Pictographic), ('\u{1f546}', '\u{1f64f}', GC_Extended_Pictographic), + ('\u{1f680}', '\u{1f6ff}', GC_Extended_Pictographic), ('\u{1f774}', '\u{1f77f}', + GC_Extended_Pictographic), ('\u{1f7d5}', '\u{1f7ff}', GC_Extended_Pictographic), + ('\u{1f80c}', '\u{1f80f}', GC_Extended_Pictographic), ('\u{1f848}', '\u{1f84f}', + GC_Extended_Pictographic), ('\u{1f85a}', '\u{1f85f}', GC_Extended_Pictographic), + ('\u{1f888}', '\u{1f88f}', GC_Extended_Pictographic), ('\u{1f8ae}', '\u{1f8ff}', + GC_Extended_Pictographic), ('\u{1f90c}', '\u{1f93a}', GC_Extended_Pictographic), + ('\u{1f93c}', '\u{1f945}', GC_Extended_Pictographic), ('\u{1f947}', '\u{1faff}', + GC_Extended_Pictographic), ('\u{1fc00}', '\u{1fffd}', GC_Extended_Pictographic), + ('\u{e0000}', '\u{e001f}', GC_Control), ('\u{e0020}', '\u{e007f}', GC_Extend), ('\u{e0080}', + '\u{e00ff}', GC_Control), ('\u{e0100}', '\u{e01ef}', GC_Extend), ('\u{e01f0}', '\u{e0fff}', + GC_Control) ]; } @@ -1146,171 +1159,171 @@ pub mod word { '\u{cc8}', WC_Extend), ('\u{cca}', '\u{ccd}', WC_Extend), ('\u{cd5}', '\u{cd6}', WC_Extend), ('\u{cdd}', '\u{cde}', WC_ALetter), ('\u{ce0}', '\u{ce1}', WC_ALetter), ('\u{ce2}', '\u{ce3}', WC_Extend), ('\u{ce6}', '\u{cef}', WC_Numeric), ('\u{cf1}', '\u{cf2}', - WC_ALetter), ('\u{d00}', '\u{d03}', WC_Extend), ('\u{d04}', '\u{d0c}', WC_ALetter), - ('\u{d0e}', '\u{d10}', WC_ALetter), ('\u{d12}', '\u{d3a}', WC_ALetter), ('\u{d3b}', - '\u{d3c}', WC_Extend), ('\u{d3d}', '\u{d3d}', WC_ALetter), ('\u{d3e}', '\u{d44}', - WC_Extend), ('\u{d46}', '\u{d48}', WC_Extend), ('\u{d4a}', '\u{d4d}', WC_Extend), - ('\u{d4e}', '\u{d4e}', WC_ALetter), ('\u{d54}', '\u{d56}', WC_ALetter), ('\u{d57}', - '\u{d57}', WC_Extend), ('\u{d5f}', '\u{d61}', WC_ALetter), ('\u{d62}', '\u{d63}', - WC_Extend), ('\u{d66}', '\u{d6f}', WC_Numeric), ('\u{d7a}', '\u{d7f}', WC_ALetter), - ('\u{d81}', '\u{d83}', WC_Extend), ('\u{d85}', '\u{d96}', WC_ALetter), ('\u{d9a}', - '\u{db1}', WC_ALetter), ('\u{db3}', '\u{dbb}', WC_ALetter), ('\u{dbd}', '\u{dbd}', - WC_ALetter), ('\u{dc0}', '\u{dc6}', WC_ALetter), ('\u{dca}', '\u{dca}', WC_Extend), - ('\u{dcf}', '\u{dd4}', WC_Extend), ('\u{dd6}', '\u{dd6}', WC_Extend), ('\u{dd8}', '\u{ddf}', - WC_Extend), ('\u{de6}', '\u{def}', WC_Numeric), ('\u{df2}', '\u{df3}', WC_Extend), - ('\u{e31}', '\u{e31}', WC_Extend), ('\u{e34}', '\u{e3a}', WC_Extend), ('\u{e47}', '\u{e4e}', - WC_Extend), ('\u{e50}', '\u{e59}', WC_Numeric), ('\u{eb1}', '\u{eb1}', WC_Extend), - ('\u{eb4}', '\u{ebc}', WC_Extend), ('\u{ec8}', '\u{ecd}', WC_Extend), ('\u{ed0}', '\u{ed9}', - WC_Numeric), ('\u{f00}', '\u{f00}', WC_ALetter), ('\u{f18}', '\u{f19}', WC_Extend), - ('\u{f20}', '\u{f29}', WC_Numeric), ('\u{f35}', '\u{f35}', WC_Extend), ('\u{f37}', - '\u{f37}', WC_Extend), ('\u{f39}', '\u{f39}', WC_Extend), ('\u{f3e}', '\u{f3f}', WC_Extend), - ('\u{f40}', '\u{f47}', WC_ALetter), ('\u{f49}', '\u{f6c}', WC_ALetter), ('\u{f71}', - '\u{f84}', WC_Extend), ('\u{f86}', '\u{f87}', WC_Extend), ('\u{f88}', '\u{f8c}', - WC_ALetter), ('\u{f8d}', '\u{f97}', WC_Extend), ('\u{f99}', '\u{fbc}', WC_Extend), - ('\u{fc6}', '\u{fc6}', WC_Extend), ('\u{102b}', '\u{103e}', WC_Extend), ('\u{1040}', - '\u{1049}', WC_Numeric), ('\u{1056}', '\u{1059}', WC_Extend), ('\u{105e}', '\u{1060}', - WC_Extend), ('\u{1062}', '\u{1064}', WC_Extend), ('\u{1067}', '\u{106d}', WC_Extend), - ('\u{1071}', '\u{1074}', WC_Extend), ('\u{1082}', '\u{108d}', WC_Extend), ('\u{108f}', - '\u{108f}', WC_Extend), ('\u{1090}', '\u{1099}', WC_Numeric), ('\u{109a}', '\u{109d}', - WC_Extend), ('\u{10a0}', '\u{10c5}', WC_ALetter), ('\u{10c7}', '\u{10c7}', WC_ALetter), - ('\u{10cd}', '\u{10cd}', WC_ALetter), ('\u{10d0}', '\u{10fa}', WC_ALetter), ('\u{10fc}', - '\u{1248}', WC_ALetter), ('\u{124a}', '\u{124d}', WC_ALetter), ('\u{1250}', '\u{1256}', - WC_ALetter), ('\u{1258}', '\u{1258}', WC_ALetter), ('\u{125a}', '\u{125d}', WC_ALetter), - ('\u{1260}', '\u{1288}', WC_ALetter), ('\u{128a}', '\u{128d}', WC_ALetter), ('\u{1290}', - '\u{12b0}', WC_ALetter), ('\u{12b2}', '\u{12b5}', WC_ALetter), ('\u{12b8}', '\u{12be}', - WC_ALetter), ('\u{12c0}', '\u{12c0}', WC_ALetter), ('\u{12c2}', '\u{12c5}', WC_ALetter), - ('\u{12c8}', '\u{12d6}', WC_ALetter), ('\u{12d8}', '\u{1310}', WC_ALetter), ('\u{1312}', - '\u{1315}', WC_ALetter), ('\u{1318}', '\u{135a}', WC_ALetter), ('\u{135d}', '\u{135f}', - WC_Extend), ('\u{1380}', '\u{138f}', WC_ALetter), ('\u{13a0}', '\u{13f5}', WC_ALetter), - ('\u{13f8}', '\u{13fd}', WC_ALetter), ('\u{1401}', '\u{166c}', WC_ALetter), ('\u{166f}', - '\u{167f}', WC_ALetter), ('\u{1680}', '\u{1680}', WC_WSegSpace), ('\u{1681}', '\u{169a}', - WC_ALetter), ('\u{16a0}', '\u{16ea}', WC_ALetter), ('\u{16ee}', '\u{16f8}', WC_ALetter), - ('\u{1700}', '\u{1711}', WC_ALetter), ('\u{1712}', '\u{1715}', WC_Extend), ('\u{171f}', - '\u{1731}', WC_ALetter), ('\u{1732}', '\u{1734}', WC_Extend), ('\u{1740}', '\u{1751}', - WC_ALetter), ('\u{1752}', '\u{1753}', WC_Extend), ('\u{1760}', '\u{176c}', WC_ALetter), - ('\u{176e}', '\u{1770}', WC_ALetter), ('\u{1772}', '\u{1773}', WC_Extend), ('\u{17b4}', - '\u{17d3}', WC_Extend), ('\u{17dd}', '\u{17dd}', WC_Extend), ('\u{17e0}', '\u{17e9}', - WC_Numeric), ('\u{180b}', '\u{180d}', WC_Extend), ('\u{180e}', '\u{180e}', WC_Format), - ('\u{180f}', '\u{180f}', WC_Extend), ('\u{1810}', '\u{1819}', WC_Numeric), ('\u{1820}', - '\u{1878}', WC_ALetter), ('\u{1880}', '\u{1884}', WC_ALetter), ('\u{1885}', '\u{1886}', - WC_Extend), ('\u{1887}', '\u{18a8}', WC_ALetter), ('\u{18a9}', '\u{18a9}', WC_Extend), - ('\u{18aa}', '\u{18aa}', WC_ALetter), ('\u{18b0}', '\u{18f5}', WC_ALetter), ('\u{1900}', - '\u{191e}', WC_ALetter), ('\u{1920}', '\u{192b}', WC_Extend), ('\u{1930}', '\u{193b}', - WC_Extend), ('\u{1946}', '\u{194f}', WC_Numeric), ('\u{19d0}', '\u{19d9}', WC_Numeric), - ('\u{1a00}', '\u{1a16}', WC_ALetter), ('\u{1a17}', '\u{1a1b}', WC_Extend), ('\u{1a55}', - '\u{1a5e}', WC_Extend), ('\u{1a60}', '\u{1a7c}', WC_Extend), ('\u{1a7f}', '\u{1a7f}', - WC_Extend), ('\u{1a80}', '\u{1a89}', WC_Numeric), ('\u{1a90}', '\u{1a99}', WC_Numeric), - ('\u{1ab0}', '\u{1ace}', WC_Extend), ('\u{1b00}', '\u{1b04}', WC_Extend), ('\u{1b05}', - '\u{1b33}', WC_ALetter), ('\u{1b34}', '\u{1b44}', WC_Extend), ('\u{1b45}', '\u{1b4c}', - WC_ALetter), ('\u{1b50}', '\u{1b59}', WC_Numeric), ('\u{1b6b}', '\u{1b73}', WC_Extend), - ('\u{1b80}', '\u{1b82}', WC_Extend), ('\u{1b83}', '\u{1ba0}', WC_ALetter), ('\u{1ba1}', - '\u{1bad}', WC_Extend), ('\u{1bae}', '\u{1baf}', WC_ALetter), ('\u{1bb0}', '\u{1bb9}', - WC_Numeric), ('\u{1bba}', '\u{1be5}', WC_ALetter), ('\u{1be6}', '\u{1bf3}', WC_Extend), - ('\u{1c00}', '\u{1c23}', WC_ALetter), ('\u{1c24}', '\u{1c37}', WC_Extend), ('\u{1c40}', - '\u{1c49}', WC_Numeric), ('\u{1c4d}', '\u{1c4f}', WC_ALetter), ('\u{1c50}', '\u{1c59}', - WC_Numeric), ('\u{1c5a}', '\u{1c7d}', WC_ALetter), ('\u{1c80}', '\u{1c88}', WC_ALetter), - ('\u{1c90}', '\u{1cba}', WC_ALetter), ('\u{1cbd}', '\u{1cbf}', WC_ALetter), ('\u{1cd0}', - '\u{1cd2}', WC_Extend), ('\u{1cd4}', '\u{1ce8}', WC_Extend), ('\u{1ce9}', '\u{1cec}', - WC_ALetter), ('\u{1ced}', '\u{1ced}', WC_Extend), ('\u{1cee}', '\u{1cf3}', WC_ALetter), - ('\u{1cf4}', '\u{1cf4}', WC_Extend), ('\u{1cf5}', '\u{1cf6}', WC_ALetter), ('\u{1cf7}', - '\u{1cf9}', WC_Extend), ('\u{1cfa}', '\u{1cfa}', WC_ALetter), ('\u{1d00}', '\u{1dbf}', - WC_ALetter), ('\u{1dc0}', '\u{1dff}', WC_Extend), ('\u{1e00}', '\u{1f15}', WC_ALetter), - ('\u{1f18}', '\u{1f1d}', WC_ALetter), ('\u{1f20}', '\u{1f45}', WC_ALetter), ('\u{1f48}', - '\u{1f4d}', WC_ALetter), ('\u{1f50}', '\u{1f57}', WC_ALetter), ('\u{1f59}', '\u{1f59}', - WC_ALetter), ('\u{1f5b}', '\u{1f5b}', WC_ALetter), ('\u{1f5d}', '\u{1f5d}', WC_ALetter), - ('\u{1f5f}', '\u{1f7d}', WC_ALetter), ('\u{1f80}', '\u{1fb4}', WC_ALetter), ('\u{1fb6}', - '\u{1fbc}', WC_ALetter), ('\u{1fbe}', '\u{1fbe}', WC_ALetter), ('\u{1fc2}', '\u{1fc4}', - WC_ALetter), ('\u{1fc6}', '\u{1fcc}', WC_ALetter), ('\u{1fd0}', '\u{1fd3}', WC_ALetter), - ('\u{1fd6}', '\u{1fdb}', WC_ALetter), ('\u{1fe0}', '\u{1fec}', WC_ALetter), ('\u{1ff2}', - '\u{1ff4}', WC_ALetter), ('\u{1ff6}', '\u{1ffc}', WC_ALetter), ('\u{2000}', '\u{2006}', - WC_WSegSpace), ('\u{2008}', '\u{200a}', WC_WSegSpace), ('\u{200c}', '\u{200c}', WC_Extend), - ('\u{200d}', '\u{200d}', WC_ZWJ), ('\u{200e}', '\u{200f}', WC_Format), ('\u{2018}', - '\u{2019}', WC_MidNumLet), ('\u{2024}', '\u{2024}', WC_MidNumLet), ('\u{2027}', '\u{2027}', - WC_MidLetter), ('\u{2028}', '\u{2029}', WC_Newline), ('\u{202a}', '\u{202e}', WC_Format), - ('\u{202f}', '\u{202f}', WC_ExtendNumLet), ('\u{203f}', '\u{2040}', WC_ExtendNumLet), - ('\u{2044}', '\u{2044}', WC_MidNum), ('\u{2054}', '\u{2054}', WC_ExtendNumLet), ('\u{205f}', - '\u{205f}', WC_WSegSpace), ('\u{2060}', '\u{2064}', WC_Format), ('\u{2066}', '\u{206f}', - WC_Format), ('\u{2071}', '\u{2071}', WC_ALetter), ('\u{207f}', '\u{207f}', WC_ALetter), - ('\u{2090}', '\u{209c}', WC_ALetter), ('\u{20d0}', '\u{20f0}', WC_Extend), ('\u{2102}', - '\u{2102}', WC_ALetter), ('\u{2107}', '\u{2107}', WC_ALetter), ('\u{210a}', '\u{2113}', - WC_ALetter), ('\u{2115}', '\u{2115}', WC_ALetter), ('\u{2119}', '\u{211d}', WC_ALetter), - ('\u{2124}', '\u{2124}', WC_ALetter), ('\u{2126}', '\u{2126}', WC_ALetter), ('\u{2128}', - '\u{2128}', WC_ALetter), ('\u{212a}', '\u{212d}', WC_ALetter), ('\u{212f}', '\u{2139}', - WC_ALetter), ('\u{213c}', '\u{213f}', WC_ALetter), ('\u{2145}', '\u{2149}', WC_ALetter), - ('\u{214e}', '\u{214e}', WC_ALetter), ('\u{2160}', '\u{2188}', WC_ALetter), ('\u{24b6}', - '\u{24e9}', WC_ALetter), ('\u{2c00}', '\u{2ce4}', WC_ALetter), ('\u{2ceb}', '\u{2cee}', - WC_ALetter), ('\u{2cef}', '\u{2cf1}', WC_Extend), ('\u{2cf2}', '\u{2cf3}', WC_ALetter), - ('\u{2d00}', '\u{2d25}', WC_ALetter), ('\u{2d27}', '\u{2d27}', WC_ALetter), ('\u{2d2d}', - '\u{2d2d}', WC_ALetter), ('\u{2d30}', '\u{2d67}', WC_ALetter), ('\u{2d6f}', '\u{2d6f}', - WC_ALetter), ('\u{2d7f}', '\u{2d7f}', WC_Extend), ('\u{2d80}', '\u{2d96}', WC_ALetter), - ('\u{2da0}', '\u{2da6}', WC_ALetter), ('\u{2da8}', '\u{2dae}', WC_ALetter), ('\u{2db0}', - '\u{2db6}', WC_ALetter), ('\u{2db8}', '\u{2dbe}', WC_ALetter), ('\u{2dc0}', '\u{2dc6}', - WC_ALetter), ('\u{2dc8}', '\u{2dce}', WC_ALetter), ('\u{2dd0}', '\u{2dd6}', WC_ALetter), - ('\u{2dd8}', '\u{2dde}', WC_ALetter), ('\u{2de0}', '\u{2dff}', WC_Extend), ('\u{2e2f}', - '\u{2e2f}', WC_ALetter), ('\u{3000}', '\u{3000}', WC_WSegSpace), ('\u{3005}', '\u{3005}', - WC_ALetter), ('\u{302a}', '\u{302f}', WC_Extend), ('\u{3031}', '\u{3035}', WC_Katakana), - ('\u{303b}', '\u{303c}', WC_ALetter), ('\u{3099}', '\u{309a}', WC_Extend), ('\u{309b}', - '\u{309c}', WC_Katakana), ('\u{30a0}', '\u{30fa}', WC_Katakana), ('\u{30fc}', '\u{30ff}', - WC_Katakana), ('\u{3105}', '\u{312f}', WC_ALetter), ('\u{3131}', '\u{318e}', WC_ALetter), - ('\u{31a0}', '\u{31bf}', WC_ALetter), ('\u{31f0}', '\u{31ff}', WC_Katakana), ('\u{32d0}', - '\u{32fe}', WC_Katakana), ('\u{3300}', '\u{3357}', WC_Katakana), ('\u{a000}', '\u{a48c}', - WC_ALetter), ('\u{a4d0}', '\u{a4fd}', WC_ALetter), ('\u{a500}', '\u{a60c}', WC_ALetter), - ('\u{a610}', '\u{a61f}', WC_ALetter), ('\u{a620}', '\u{a629}', WC_Numeric), ('\u{a62a}', - '\u{a62b}', WC_ALetter), ('\u{a640}', '\u{a66e}', WC_ALetter), ('\u{a66f}', '\u{a672}', - WC_Extend), ('\u{a674}', '\u{a67d}', WC_Extend), ('\u{a67f}', '\u{a69d}', WC_ALetter), - ('\u{a69e}', '\u{a69f}', WC_Extend), ('\u{a6a0}', '\u{a6ef}', WC_ALetter), ('\u{a6f0}', - '\u{a6f1}', WC_Extend), ('\u{a708}', '\u{a7ca}', WC_ALetter), ('\u{a7d0}', '\u{a7d1}', - WC_ALetter), ('\u{a7d3}', '\u{a7d3}', WC_ALetter), ('\u{a7d5}', '\u{a7d9}', WC_ALetter), - ('\u{a7f2}', '\u{a801}', WC_ALetter), ('\u{a802}', '\u{a802}', WC_Extend), ('\u{a803}', - '\u{a805}', WC_ALetter), ('\u{a806}', '\u{a806}', WC_Extend), ('\u{a807}', '\u{a80a}', - WC_ALetter), ('\u{a80b}', '\u{a80b}', WC_Extend), ('\u{a80c}', '\u{a822}', WC_ALetter), - ('\u{a823}', '\u{a827}', WC_Extend), ('\u{a82c}', '\u{a82c}', WC_Extend), ('\u{a840}', - '\u{a873}', WC_ALetter), ('\u{a880}', '\u{a881}', WC_Extend), ('\u{a882}', '\u{a8b3}', - WC_ALetter), ('\u{a8b4}', '\u{a8c5}', WC_Extend), ('\u{a8d0}', '\u{a8d9}', WC_Numeric), - ('\u{a8e0}', '\u{a8f1}', WC_Extend), ('\u{a8f2}', '\u{a8f7}', WC_ALetter), ('\u{a8fb}', - '\u{a8fb}', WC_ALetter), ('\u{a8fd}', '\u{a8fe}', WC_ALetter), ('\u{a8ff}', '\u{a8ff}', - WC_Extend), ('\u{a900}', '\u{a909}', WC_Numeric), ('\u{a90a}', '\u{a925}', WC_ALetter), - ('\u{a926}', '\u{a92d}', WC_Extend), ('\u{a930}', '\u{a946}', WC_ALetter), ('\u{a947}', - '\u{a953}', WC_Extend), ('\u{a960}', '\u{a97c}', WC_ALetter), ('\u{a980}', '\u{a983}', - WC_Extend), ('\u{a984}', '\u{a9b2}', WC_ALetter), ('\u{a9b3}', '\u{a9c0}', WC_Extend), - ('\u{a9cf}', '\u{a9cf}', WC_ALetter), ('\u{a9d0}', '\u{a9d9}', WC_Numeric), ('\u{a9e5}', - '\u{a9e5}', WC_Extend), ('\u{a9f0}', '\u{a9f9}', WC_Numeric), ('\u{aa00}', '\u{aa28}', - WC_ALetter), ('\u{aa29}', '\u{aa36}', WC_Extend), ('\u{aa40}', '\u{aa42}', WC_ALetter), - ('\u{aa43}', '\u{aa43}', WC_Extend), ('\u{aa44}', '\u{aa4b}', WC_ALetter), ('\u{aa4c}', - '\u{aa4d}', WC_Extend), ('\u{aa50}', '\u{aa59}', WC_Numeric), ('\u{aa7b}', '\u{aa7d}', - WC_Extend), ('\u{aab0}', '\u{aab0}', WC_Extend), ('\u{aab2}', '\u{aab4}', WC_Extend), - ('\u{aab7}', '\u{aab8}', WC_Extend), ('\u{aabe}', '\u{aabf}', WC_Extend), ('\u{aac1}', - '\u{aac1}', WC_Extend), ('\u{aae0}', '\u{aaea}', WC_ALetter), ('\u{aaeb}', '\u{aaef}', - WC_Extend), ('\u{aaf2}', '\u{aaf4}', WC_ALetter), ('\u{aaf5}', '\u{aaf6}', WC_Extend), - ('\u{ab01}', '\u{ab06}', WC_ALetter), ('\u{ab09}', '\u{ab0e}', WC_ALetter), ('\u{ab11}', - '\u{ab16}', WC_ALetter), ('\u{ab20}', '\u{ab26}', WC_ALetter), ('\u{ab28}', '\u{ab2e}', - WC_ALetter), ('\u{ab30}', '\u{ab69}', WC_ALetter), ('\u{ab70}', '\u{abe2}', WC_ALetter), - ('\u{abe3}', '\u{abea}', WC_Extend), ('\u{abec}', '\u{abed}', WC_Extend), ('\u{abf0}', - '\u{abf9}', WC_Numeric), ('\u{ac00}', '\u{d7a3}', WC_ALetter), ('\u{d7b0}', '\u{d7c6}', - WC_ALetter), ('\u{d7cb}', '\u{d7fb}', WC_ALetter), ('\u{fb00}', '\u{fb06}', WC_ALetter), - ('\u{fb13}', '\u{fb17}', WC_ALetter), ('\u{fb1d}', '\u{fb1d}', WC_Hebrew_Letter), - ('\u{fb1e}', '\u{fb1e}', WC_Extend), ('\u{fb1f}', '\u{fb28}', WC_Hebrew_Letter), - ('\u{fb2a}', '\u{fb36}', WC_Hebrew_Letter), ('\u{fb38}', '\u{fb3c}', WC_Hebrew_Letter), - ('\u{fb3e}', '\u{fb3e}', WC_Hebrew_Letter), ('\u{fb40}', '\u{fb41}', WC_Hebrew_Letter), - ('\u{fb43}', '\u{fb44}', WC_Hebrew_Letter), ('\u{fb46}', '\u{fb4f}', WC_Hebrew_Letter), - ('\u{fb50}', '\u{fbb1}', WC_ALetter), ('\u{fbd3}', '\u{fd3d}', WC_ALetter), ('\u{fd50}', - '\u{fd8f}', WC_ALetter), ('\u{fd92}', '\u{fdc7}', WC_ALetter), ('\u{fdf0}', '\u{fdfb}', - WC_ALetter), ('\u{fe00}', '\u{fe0f}', WC_Extend), ('\u{fe10}', '\u{fe10}', WC_MidNum), - ('\u{fe13}', '\u{fe13}', WC_MidLetter), ('\u{fe14}', '\u{fe14}', WC_MidNum), ('\u{fe20}', - '\u{fe2f}', WC_Extend), ('\u{fe33}', '\u{fe34}', WC_ExtendNumLet), ('\u{fe4d}', '\u{fe4f}', - WC_ExtendNumLet), ('\u{fe50}', '\u{fe50}', WC_MidNum), ('\u{fe52}', '\u{fe52}', - WC_MidNumLet), ('\u{fe54}', '\u{fe54}', WC_MidNum), ('\u{fe55}', '\u{fe55}', WC_MidLetter), - ('\u{fe70}', '\u{fe74}', WC_ALetter), ('\u{fe76}', '\u{fefc}', WC_ALetter), ('\u{feff}', - '\u{feff}', WC_Format), ('\u{ff07}', '\u{ff07}', WC_MidNumLet), ('\u{ff0c}', '\u{ff0c}', - WC_MidNum), ('\u{ff0e}', '\u{ff0e}', WC_MidNumLet), ('\u{ff10}', '\u{ff19}', WC_Numeric), - ('\u{ff1a}', '\u{ff1a}', WC_MidLetter), ('\u{ff1b}', '\u{ff1b}', WC_MidNum), ('\u{ff21}', - '\u{ff3a}', WC_ALetter), ('\u{ff3f}', '\u{ff3f}', WC_ExtendNumLet), ('\u{ff41}', '\u{ff5a}', - WC_ALetter), ('\u{ff66}', '\u{ff9d}', WC_Katakana), ('\u{ff9e}', '\u{ff9f}', WC_Extend), - ('\u{ffa0}', '\u{ffbe}', WC_ALetter), ('\u{ffc2}', '\u{ffc7}', WC_ALetter), ('\u{ffca}', - '\u{ffcf}', WC_ALetter), ('\u{ffd2}', '\u{ffd7}', WC_ALetter), ('\u{ffda}', '\u{ffdc}', - WC_ALetter), ('\u{fff9}', '\u{fffb}', WC_Format), ('\u{10000}', '\u{1000b}', WC_ALetter), - ('\u{1000d}', '\u{10026}', WC_ALetter), ('\u{10028}', '\u{1003a}', WC_ALetter), - ('\u{1003c}', '\u{1003d}', WC_ALetter), ('\u{1003f}', '\u{1004d}', WC_ALetter), + WC_ALetter), ('\u{cf3}', '\u{cf3}', WC_Extend), ('\u{d00}', '\u{d03}', WC_Extend), + ('\u{d04}', '\u{d0c}', WC_ALetter), ('\u{d0e}', '\u{d10}', WC_ALetter), ('\u{d12}', + '\u{d3a}', WC_ALetter), ('\u{d3b}', '\u{d3c}', WC_Extend), ('\u{d3d}', '\u{d3d}', + WC_ALetter), ('\u{d3e}', '\u{d44}', WC_Extend), ('\u{d46}', '\u{d48}', WC_Extend), + ('\u{d4a}', '\u{d4d}', WC_Extend), ('\u{d4e}', '\u{d4e}', WC_ALetter), ('\u{d54}', + '\u{d56}', WC_ALetter), ('\u{d57}', '\u{d57}', WC_Extend), ('\u{d5f}', '\u{d61}', + WC_ALetter), ('\u{d62}', '\u{d63}', WC_Extend), ('\u{d66}', '\u{d6f}', WC_Numeric), + ('\u{d7a}', '\u{d7f}', WC_ALetter), ('\u{d81}', '\u{d83}', WC_Extend), ('\u{d85}', + '\u{d96}', WC_ALetter), ('\u{d9a}', '\u{db1}', WC_ALetter), ('\u{db3}', '\u{dbb}', + WC_ALetter), ('\u{dbd}', '\u{dbd}', WC_ALetter), ('\u{dc0}', '\u{dc6}', WC_ALetter), + ('\u{dca}', '\u{dca}', WC_Extend), ('\u{dcf}', '\u{dd4}', WC_Extend), ('\u{dd6}', '\u{dd6}', + WC_Extend), ('\u{dd8}', '\u{ddf}', WC_Extend), ('\u{de6}', '\u{def}', WC_Numeric), + ('\u{df2}', '\u{df3}', WC_Extend), ('\u{e31}', '\u{e31}', WC_Extend), ('\u{e34}', '\u{e3a}', + WC_Extend), ('\u{e47}', '\u{e4e}', WC_Extend), ('\u{e50}', '\u{e59}', WC_Numeric), + ('\u{eb1}', '\u{eb1}', WC_Extend), ('\u{eb4}', '\u{ebc}', WC_Extend), ('\u{ec8}', '\u{ece}', + WC_Extend), ('\u{ed0}', '\u{ed9}', WC_Numeric), ('\u{f00}', '\u{f00}', WC_ALetter), + ('\u{f18}', '\u{f19}', WC_Extend), ('\u{f20}', '\u{f29}', WC_Numeric), ('\u{f35}', + '\u{f35}', WC_Extend), ('\u{f37}', '\u{f37}', WC_Extend), ('\u{f39}', '\u{f39}', WC_Extend), + ('\u{f3e}', '\u{f3f}', WC_Extend), ('\u{f40}', '\u{f47}', WC_ALetter), ('\u{f49}', + '\u{f6c}', WC_ALetter), ('\u{f71}', '\u{f84}', WC_Extend), ('\u{f86}', '\u{f87}', + WC_Extend), ('\u{f88}', '\u{f8c}', WC_ALetter), ('\u{f8d}', '\u{f97}', WC_Extend), + ('\u{f99}', '\u{fbc}', WC_Extend), ('\u{fc6}', '\u{fc6}', WC_Extend), ('\u{102b}', + '\u{103e}', WC_Extend), ('\u{1040}', '\u{1049}', WC_Numeric), ('\u{1056}', '\u{1059}', + WC_Extend), ('\u{105e}', '\u{1060}', WC_Extend), ('\u{1062}', '\u{1064}', WC_Extend), + ('\u{1067}', '\u{106d}', WC_Extend), ('\u{1071}', '\u{1074}', WC_Extend), ('\u{1082}', + '\u{108d}', WC_Extend), ('\u{108f}', '\u{108f}', WC_Extend), ('\u{1090}', '\u{1099}', + WC_Numeric), ('\u{109a}', '\u{109d}', WC_Extend), ('\u{10a0}', '\u{10c5}', WC_ALetter), + ('\u{10c7}', '\u{10c7}', WC_ALetter), ('\u{10cd}', '\u{10cd}', WC_ALetter), ('\u{10d0}', + '\u{10fa}', WC_ALetter), ('\u{10fc}', '\u{1248}', WC_ALetter), ('\u{124a}', '\u{124d}', + WC_ALetter), ('\u{1250}', '\u{1256}', WC_ALetter), ('\u{1258}', '\u{1258}', WC_ALetter), + ('\u{125a}', '\u{125d}', WC_ALetter), ('\u{1260}', '\u{1288}', WC_ALetter), ('\u{128a}', + '\u{128d}', WC_ALetter), ('\u{1290}', '\u{12b0}', WC_ALetter), ('\u{12b2}', '\u{12b5}', + WC_ALetter), ('\u{12b8}', '\u{12be}', WC_ALetter), ('\u{12c0}', '\u{12c0}', WC_ALetter), + ('\u{12c2}', '\u{12c5}', WC_ALetter), ('\u{12c8}', '\u{12d6}', WC_ALetter), ('\u{12d8}', + '\u{1310}', WC_ALetter), ('\u{1312}', '\u{1315}', WC_ALetter), ('\u{1318}', '\u{135a}', + WC_ALetter), ('\u{135d}', '\u{135f}', WC_Extend), ('\u{1380}', '\u{138f}', WC_ALetter), + ('\u{13a0}', '\u{13f5}', WC_ALetter), ('\u{13f8}', '\u{13fd}', WC_ALetter), ('\u{1401}', + '\u{166c}', WC_ALetter), ('\u{166f}', '\u{167f}', WC_ALetter), ('\u{1680}', '\u{1680}', + WC_WSegSpace), ('\u{1681}', '\u{169a}', WC_ALetter), ('\u{16a0}', '\u{16ea}', WC_ALetter), + ('\u{16ee}', '\u{16f8}', WC_ALetter), ('\u{1700}', '\u{1711}', WC_ALetter), ('\u{1712}', + '\u{1715}', WC_Extend), ('\u{171f}', '\u{1731}', WC_ALetter), ('\u{1732}', '\u{1734}', + WC_Extend), ('\u{1740}', '\u{1751}', WC_ALetter), ('\u{1752}', '\u{1753}', WC_Extend), + ('\u{1760}', '\u{176c}', WC_ALetter), ('\u{176e}', '\u{1770}', WC_ALetter), ('\u{1772}', + '\u{1773}', WC_Extend), ('\u{17b4}', '\u{17d3}', WC_Extend), ('\u{17dd}', '\u{17dd}', + WC_Extend), ('\u{17e0}', '\u{17e9}', WC_Numeric), ('\u{180b}', '\u{180d}', WC_Extend), + ('\u{180e}', '\u{180e}', WC_Format), ('\u{180f}', '\u{180f}', WC_Extend), ('\u{1810}', + '\u{1819}', WC_Numeric), ('\u{1820}', '\u{1878}', WC_ALetter), ('\u{1880}', '\u{1884}', + WC_ALetter), ('\u{1885}', '\u{1886}', WC_Extend), ('\u{1887}', '\u{18a8}', WC_ALetter), + ('\u{18a9}', '\u{18a9}', WC_Extend), ('\u{18aa}', '\u{18aa}', WC_ALetter), ('\u{18b0}', + '\u{18f5}', WC_ALetter), ('\u{1900}', '\u{191e}', WC_ALetter), ('\u{1920}', '\u{192b}', + WC_Extend), ('\u{1930}', '\u{193b}', WC_Extend), ('\u{1946}', '\u{194f}', WC_Numeric), + ('\u{19d0}', '\u{19d9}', WC_Numeric), ('\u{1a00}', '\u{1a16}', WC_ALetter), ('\u{1a17}', + '\u{1a1b}', WC_Extend), ('\u{1a55}', '\u{1a5e}', WC_Extend), ('\u{1a60}', '\u{1a7c}', + WC_Extend), ('\u{1a7f}', '\u{1a7f}', WC_Extend), ('\u{1a80}', '\u{1a89}', WC_Numeric), + ('\u{1a90}', '\u{1a99}', WC_Numeric), ('\u{1ab0}', '\u{1ace}', WC_Extend), ('\u{1b00}', + '\u{1b04}', WC_Extend), ('\u{1b05}', '\u{1b33}', WC_ALetter), ('\u{1b34}', '\u{1b44}', + WC_Extend), ('\u{1b45}', '\u{1b4c}', WC_ALetter), ('\u{1b50}', '\u{1b59}', WC_Numeric), + ('\u{1b6b}', '\u{1b73}', WC_Extend), ('\u{1b80}', '\u{1b82}', WC_Extend), ('\u{1b83}', + '\u{1ba0}', WC_ALetter), ('\u{1ba1}', '\u{1bad}', WC_Extend), ('\u{1bae}', '\u{1baf}', + WC_ALetter), ('\u{1bb0}', '\u{1bb9}', WC_Numeric), ('\u{1bba}', '\u{1be5}', WC_ALetter), + ('\u{1be6}', '\u{1bf3}', WC_Extend), ('\u{1c00}', '\u{1c23}', WC_ALetter), ('\u{1c24}', + '\u{1c37}', WC_Extend), ('\u{1c40}', '\u{1c49}', WC_Numeric), ('\u{1c4d}', '\u{1c4f}', + WC_ALetter), ('\u{1c50}', '\u{1c59}', WC_Numeric), ('\u{1c5a}', '\u{1c7d}', WC_ALetter), + ('\u{1c80}', '\u{1c88}', WC_ALetter), ('\u{1c90}', '\u{1cba}', WC_ALetter), ('\u{1cbd}', + '\u{1cbf}', WC_ALetter), ('\u{1cd0}', '\u{1cd2}', WC_Extend), ('\u{1cd4}', '\u{1ce8}', + WC_Extend), ('\u{1ce9}', '\u{1cec}', WC_ALetter), ('\u{1ced}', '\u{1ced}', WC_Extend), + ('\u{1cee}', '\u{1cf3}', WC_ALetter), ('\u{1cf4}', '\u{1cf4}', WC_Extend), ('\u{1cf5}', + '\u{1cf6}', WC_ALetter), ('\u{1cf7}', '\u{1cf9}', WC_Extend), ('\u{1cfa}', '\u{1cfa}', + WC_ALetter), ('\u{1d00}', '\u{1dbf}', WC_ALetter), ('\u{1dc0}', '\u{1dff}', WC_Extend), + ('\u{1e00}', '\u{1f15}', WC_ALetter), ('\u{1f18}', '\u{1f1d}', WC_ALetter), ('\u{1f20}', + '\u{1f45}', WC_ALetter), ('\u{1f48}', '\u{1f4d}', WC_ALetter), ('\u{1f50}', '\u{1f57}', + WC_ALetter), ('\u{1f59}', '\u{1f59}', WC_ALetter), ('\u{1f5b}', '\u{1f5b}', WC_ALetter), + ('\u{1f5d}', '\u{1f5d}', WC_ALetter), ('\u{1f5f}', '\u{1f7d}', WC_ALetter), ('\u{1f80}', + '\u{1fb4}', WC_ALetter), ('\u{1fb6}', '\u{1fbc}', WC_ALetter), ('\u{1fbe}', '\u{1fbe}', + WC_ALetter), ('\u{1fc2}', '\u{1fc4}', WC_ALetter), ('\u{1fc6}', '\u{1fcc}', WC_ALetter), + ('\u{1fd0}', '\u{1fd3}', WC_ALetter), ('\u{1fd6}', '\u{1fdb}', WC_ALetter), ('\u{1fe0}', + '\u{1fec}', WC_ALetter), ('\u{1ff2}', '\u{1ff4}', WC_ALetter), ('\u{1ff6}', '\u{1ffc}', + WC_ALetter), ('\u{2000}', '\u{2006}', WC_WSegSpace), ('\u{2008}', '\u{200a}', WC_WSegSpace), + ('\u{200c}', '\u{200c}', WC_Extend), ('\u{200d}', '\u{200d}', WC_ZWJ), ('\u{200e}', + '\u{200f}', WC_Format), ('\u{2018}', '\u{2019}', WC_MidNumLet), ('\u{2024}', '\u{2024}', + WC_MidNumLet), ('\u{2027}', '\u{2027}', WC_MidLetter), ('\u{2028}', '\u{2029}', WC_Newline), + ('\u{202a}', '\u{202e}', WC_Format), ('\u{202f}', '\u{202f}', WC_ExtendNumLet), ('\u{203f}', + '\u{2040}', WC_ExtendNumLet), ('\u{2044}', '\u{2044}', WC_MidNum), ('\u{2054}', '\u{2054}', + WC_ExtendNumLet), ('\u{205f}', '\u{205f}', WC_WSegSpace), ('\u{2060}', '\u{2064}', + WC_Format), ('\u{2066}', '\u{206f}', WC_Format), ('\u{2071}', '\u{2071}', WC_ALetter), + ('\u{207f}', '\u{207f}', WC_ALetter), ('\u{2090}', '\u{209c}', WC_ALetter), ('\u{20d0}', + '\u{20f0}', WC_Extend), ('\u{2102}', '\u{2102}', WC_ALetter), ('\u{2107}', '\u{2107}', + WC_ALetter), ('\u{210a}', '\u{2113}', WC_ALetter), ('\u{2115}', '\u{2115}', WC_ALetter), + ('\u{2119}', '\u{211d}', WC_ALetter), ('\u{2124}', '\u{2124}', WC_ALetter), ('\u{2126}', + '\u{2126}', WC_ALetter), ('\u{2128}', '\u{2128}', WC_ALetter), ('\u{212a}', '\u{212d}', + WC_ALetter), ('\u{212f}', '\u{2139}', WC_ALetter), ('\u{213c}', '\u{213f}', WC_ALetter), + ('\u{2145}', '\u{2149}', WC_ALetter), ('\u{214e}', '\u{214e}', WC_ALetter), ('\u{2160}', + '\u{2188}', WC_ALetter), ('\u{24b6}', '\u{24e9}', WC_ALetter), ('\u{2c00}', '\u{2ce4}', + WC_ALetter), ('\u{2ceb}', '\u{2cee}', WC_ALetter), ('\u{2cef}', '\u{2cf1}', WC_Extend), + ('\u{2cf2}', '\u{2cf3}', WC_ALetter), ('\u{2d00}', '\u{2d25}', WC_ALetter), ('\u{2d27}', + '\u{2d27}', WC_ALetter), ('\u{2d2d}', '\u{2d2d}', WC_ALetter), ('\u{2d30}', '\u{2d67}', + WC_ALetter), ('\u{2d6f}', '\u{2d6f}', WC_ALetter), ('\u{2d7f}', '\u{2d7f}', WC_Extend), + ('\u{2d80}', '\u{2d96}', WC_ALetter), ('\u{2da0}', '\u{2da6}', WC_ALetter), ('\u{2da8}', + '\u{2dae}', WC_ALetter), ('\u{2db0}', '\u{2db6}', WC_ALetter), ('\u{2db8}', '\u{2dbe}', + WC_ALetter), ('\u{2dc0}', '\u{2dc6}', WC_ALetter), ('\u{2dc8}', '\u{2dce}', WC_ALetter), + ('\u{2dd0}', '\u{2dd6}', WC_ALetter), ('\u{2dd8}', '\u{2dde}', WC_ALetter), ('\u{2de0}', + '\u{2dff}', WC_Extend), ('\u{2e2f}', '\u{2e2f}', WC_ALetter), ('\u{3000}', '\u{3000}', + WC_WSegSpace), ('\u{3005}', '\u{3005}', WC_ALetter), ('\u{302a}', '\u{302f}', WC_Extend), + ('\u{3031}', '\u{3035}', WC_Katakana), ('\u{303b}', '\u{303c}', WC_ALetter), ('\u{3099}', + '\u{309a}', WC_Extend), ('\u{309b}', '\u{309c}', WC_Katakana), ('\u{30a0}', '\u{30fa}', + WC_Katakana), ('\u{30fc}', '\u{30ff}', WC_Katakana), ('\u{3105}', '\u{312f}', WC_ALetter), + ('\u{3131}', '\u{318e}', WC_ALetter), ('\u{31a0}', '\u{31bf}', WC_ALetter), ('\u{31f0}', + '\u{31ff}', WC_Katakana), ('\u{32d0}', '\u{32fe}', WC_Katakana), ('\u{3300}', '\u{3357}', + WC_Katakana), ('\u{a000}', '\u{a48c}', WC_ALetter), ('\u{a4d0}', '\u{a4fd}', WC_ALetter), + ('\u{a500}', '\u{a60c}', WC_ALetter), ('\u{a610}', '\u{a61f}', WC_ALetter), ('\u{a620}', + '\u{a629}', WC_Numeric), ('\u{a62a}', '\u{a62b}', WC_ALetter), ('\u{a640}', '\u{a66e}', + WC_ALetter), ('\u{a66f}', '\u{a672}', WC_Extend), ('\u{a674}', '\u{a67d}', WC_Extend), + ('\u{a67f}', '\u{a69d}', WC_ALetter), ('\u{a69e}', '\u{a69f}', WC_Extend), ('\u{a6a0}', + '\u{a6ef}', WC_ALetter), ('\u{a6f0}', '\u{a6f1}', WC_Extend), ('\u{a708}', '\u{a7ca}', + WC_ALetter), ('\u{a7d0}', '\u{a7d1}', WC_ALetter), ('\u{a7d3}', '\u{a7d3}', WC_ALetter), + ('\u{a7d5}', '\u{a7d9}', WC_ALetter), ('\u{a7f2}', '\u{a801}', WC_ALetter), ('\u{a802}', + '\u{a802}', WC_Extend), ('\u{a803}', '\u{a805}', WC_ALetter), ('\u{a806}', '\u{a806}', + WC_Extend), ('\u{a807}', '\u{a80a}', WC_ALetter), ('\u{a80b}', '\u{a80b}', WC_Extend), + ('\u{a80c}', '\u{a822}', WC_ALetter), ('\u{a823}', '\u{a827}', WC_Extend), ('\u{a82c}', + '\u{a82c}', WC_Extend), ('\u{a840}', '\u{a873}', WC_ALetter), ('\u{a880}', '\u{a881}', + WC_Extend), ('\u{a882}', '\u{a8b3}', WC_ALetter), ('\u{a8b4}', '\u{a8c5}', WC_Extend), + ('\u{a8d0}', '\u{a8d9}', WC_Numeric), ('\u{a8e0}', '\u{a8f1}', WC_Extend), ('\u{a8f2}', + '\u{a8f7}', WC_ALetter), ('\u{a8fb}', '\u{a8fb}', WC_ALetter), ('\u{a8fd}', '\u{a8fe}', + WC_ALetter), ('\u{a8ff}', '\u{a8ff}', WC_Extend), ('\u{a900}', '\u{a909}', WC_Numeric), + ('\u{a90a}', '\u{a925}', WC_ALetter), ('\u{a926}', '\u{a92d}', WC_Extend), ('\u{a930}', + '\u{a946}', WC_ALetter), ('\u{a947}', '\u{a953}', WC_Extend), ('\u{a960}', '\u{a97c}', + WC_ALetter), ('\u{a980}', '\u{a983}', WC_Extend), ('\u{a984}', '\u{a9b2}', WC_ALetter), + ('\u{a9b3}', '\u{a9c0}', WC_Extend), ('\u{a9cf}', '\u{a9cf}', WC_ALetter), ('\u{a9d0}', + '\u{a9d9}', WC_Numeric), ('\u{a9e5}', '\u{a9e5}', WC_Extend), ('\u{a9f0}', '\u{a9f9}', + WC_Numeric), ('\u{aa00}', '\u{aa28}', WC_ALetter), ('\u{aa29}', '\u{aa36}', WC_Extend), + ('\u{aa40}', '\u{aa42}', WC_ALetter), ('\u{aa43}', '\u{aa43}', WC_Extend), ('\u{aa44}', + '\u{aa4b}', WC_ALetter), ('\u{aa4c}', '\u{aa4d}', WC_Extend), ('\u{aa50}', '\u{aa59}', + WC_Numeric), ('\u{aa7b}', '\u{aa7d}', WC_Extend), ('\u{aab0}', '\u{aab0}', WC_Extend), + ('\u{aab2}', '\u{aab4}', WC_Extend), ('\u{aab7}', '\u{aab8}', WC_Extend), ('\u{aabe}', + '\u{aabf}', WC_Extend), ('\u{aac1}', '\u{aac1}', WC_Extend), ('\u{aae0}', '\u{aaea}', + WC_ALetter), ('\u{aaeb}', '\u{aaef}', WC_Extend), ('\u{aaf2}', '\u{aaf4}', WC_ALetter), + ('\u{aaf5}', '\u{aaf6}', WC_Extend), ('\u{ab01}', '\u{ab06}', WC_ALetter), ('\u{ab09}', + '\u{ab0e}', WC_ALetter), ('\u{ab11}', '\u{ab16}', WC_ALetter), ('\u{ab20}', '\u{ab26}', + WC_ALetter), ('\u{ab28}', '\u{ab2e}', WC_ALetter), ('\u{ab30}', '\u{ab69}', WC_ALetter), + ('\u{ab70}', '\u{abe2}', WC_ALetter), ('\u{abe3}', '\u{abea}', WC_Extend), ('\u{abec}', + '\u{abed}', WC_Extend), ('\u{abf0}', '\u{abf9}', WC_Numeric), ('\u{ac00}', '\u{d7a3}', + WC_ALetter), ('\u{d7b0}', '\u{d7c6}', WC_ALetter), ('\u{d7cb}', '\u{d7fb}', WC_ALetter), + ('\u{fb00}', '\u{fb06}', WC_ALetter), ('\u{fb13}', '\u{fb17}', WC_ALetter), ('\u{fb1d}', + '\u{fb1d}', WC_Hebrew_Letter), ('\u{fb1e}', '\u{fb1e}', WC_Extend), ('\u{fb1f}', '\u{fb28}', + WC_Hebrew_Letter), ('\u{fb2a}', '\u{fb36}', WC_Hebrew_Letter), ('\u{fb38}', '\u{fb3c}', + WC_Hebrew_Letter), ('\u{fb3e}', '\u{fb3e}', WC_Hebrew_Letter), ('\u{fb40}', '\u{fb41}', + WC_Hebrew_Letter), ('\u{fb43}', '\u{fb44}', WC_Hebrew_Letter), ('\u{fb46}', '\u{fb4f}', + WC_Hebrew_Letter), ('\u{fb50}', '\u{fbb1}', WC_ALetter), ('\u{fbd3}', '\u{fd3d}', + WC_ALetter), ('\u{fd50}', '\u{fd8f}', WC_ALetter), ('\u{fd92}', '\u{fdc7}', WC_ALetter), + ('\u{fdf0}', '\u{fdfb}', WC_ALetter), ('\u{fe00}', '\u{fe0f}', WC_Extend), ('\u{fe10}', + '\u{fe10}', WC_MidNum), ('\u{fe13}', '\u{fe13}', WC_MidLetter), ('\u{fe14}', '\u{fe14}', + WC_MidNum), ('\u{fe20}', '\u{fe2f}', WC_Extend), ('\u{fe33}', '\u{fe34}', WC_ExtendNumLet), + ('\u{fe4d}', '\u{fe4f}', WC_ExtendNumLet), ('\u{fe50}', '\u{fe50}', WC_MidNum), ('\u{fe52}', + '\u{fe52}', WC_MidNumLet), ('\u{fe54}', '\u{fe54}', WC_MidNum), ('\u{fe55}', '\u{fe55}', + WC_MidLetter), ('\u{fe70}', '\u{fe74}', WC_ALetter), ('\u{fe76}', '\u{fefc}', WC_ALetter), + ('\u{feff}', '\u{feff}', WC_Format), ('\u{ff07}', '\u{ff07}', WC_MidNumLet), ('\u{ff0c}', + '\u{ff0c}', WC_MidNum), ('\u{ff0e}', '\u{ff0e}', WC_MidNumLet), ('\u{ff10}', '\u{ff19}', + WC_Numeric), ('\u{ff1a}', '\u{ff1a}', WC_MidLetter), ('\u{ff1b}', '\u{ff1b}', WC_MidNum), + ('\u{ff21}', '\u{ff3a}', WC_ALetter), ('\u{ff3f}', '\u{ff3f}', WC_ExtendNumLet), + ('\u{ff41}', '\u{ff5a}', WC_ALetter), ('\u{ff66}', '\u{ff9d}', WC_Katakana), ('\u{ff9e}', + '\u{ff9f}', WC_Extend), ('\u{ffa0}', '\u{ffbe}', WC_ALetter), ('\u{ffc2}', '\u{ffc7}', + WC_ALetter), ('\u{ffca}', '\u{ffcf}', WC_ALetter), ('\u{ffd2}', '\u{ffd7}', WC_ALetter), + ('\u{ffda}', '\u{ffdc}', WC_ALetter), ('\u{fff9}', '\u{fffb}', WC_Format), ('\u{10000}', + '\u{1000b}', WC_ALetter), ('\u{1000d}', '\u{10026}', WC_ALetter), ('\u{10028}', '\u{1003a}', + WC_ALetter), ('\u{1003c}', '\u{1003d}', WC_ALetter), ('\u{1003f}', '\u{1004d}', WC_ALetter), ('\u{10050}', '\u{1005d}', WC_ALetter), ('\u{10080}', '\u{100fa}', WC_ALetter), ('\u{10140}', '\u{10174}', WC_ALetter), ('\u{101fd}', '\u{101fd}', WC_Extend), ('\u{10280}', '\u{1029c}', WC_ALetter), ('\u{102a0}', '\u{102d0}', WC_ALetter), ('\u{102e0}', '\u{102e0}', @@ -1346,53 +1359,55 @@ pub mod word { ('\u{10c80}', '\u{10cb2}', WC_ALetter), ('\u{10cc0}', '\u{10cf2}', WC_ALetter), ('\u{10d00}', '\u{10d23}', WC_ALetter), ('\u{10d24}', '\u{10d27}', WC_Extend), ('\u{10d30}', '\u{10d39}', WC_Numeric), ('\u{10e80}', '\u{10ea9}', WC_ALetter), ('\u{10eab}', '\u{10eac}', - WC_Extend), ('\u{10eb0}', '\u{10eb1}', WC_ALetter), ('\u{10f00}', '\u{10f1c}', WC_ALetter), - ('\u{10f27}', '\u{10f27}', WC_ALetter), ('\u{10f30}', '\u{10f45}', WC_ALetter), - ('\u{10f46}', '\u{10f50}', WC_Extend), ('\u{10f70}', '\u{10f81}', WC_ALetter), ('\u{10f82}', - '\u{10f85}', WC_Extend), ('\u{10fb0}', '\u{10fc4}', WC_ALetter), ('\u{10fe0}', '\u{10ff6}', - WC_ALetter), ('\u{11000}', '\u{11002}', WC_Extend), ('\u{11003}', '\u{11037}', WC_ALetter), - ('\u{11038}', '\u{11046}', WC_Extend), ('\u{11066}', '\u{1106f}', WC_Numeric), ('\u{11070}', - '\u{11070}', WC_Extend), ('\u{11071}', '\u{11072}', WC_ALetter), ('\u{11073}', '\u{11074}', - WC_Extend), ('\u{11075}', '\u{11075}', WC_ALetter), ('\u{1107f}', '\u{11082}', WC_Extend), - ('\u{11083}', '\u{110af}', WC_ALetter), ('\u{110b0}', '\u{110ba}', WC_Extend), ('\u{110bd}', - '\u{110bd}', WC_Format), ('\u{110c2}', '\u{110c2}', WC_Extend), ('\u{110cd}', '\u{110cd}', - WC_Format), ('\u{110d0}', '\u{110e8}', WC_ALetter), ('\u{110f0}', '\u{110f9}', WC_Numeric), - ('\u{11100}', '\u{11102}', WC_Extend), ('\u{11103}', '\u{11126}', WC_ALetter), ('\u{11127}', - '\u{11134}', WC_Extend), ('\u{11136}', '\u{1113f}', WC_Numeric), ('\u{11144}', '\u{11144}', - WC_ALetter), ('\u{11145}', '\u{11146}', WC_Extend), ('\u{11147}', '\u{11147}', WC_ALetter), - ('\u{11150}', '\u{11172}', WC_ALetter), ('\u{11173}', '\u{11173}', WC_Extend), ('\u{11176}', - '\u{11176}', WC_ALetter), ('\u{11180}', '\u{11182}', WC_Extend), ('\u{11183}', '\u{111b2}', - WC_ALetter), ('\u{111b3}', '\u{111c0}', WC_Extend), ('\u{111c1}', '\u{111c4}', WC_ALetter), - ('\u{111c9}', '\u{111cc}', WC_Extend), ('\u{111ce}', '\u{111cf}', WC_Extend), ('\u{111d0}', - '\u{111d9}', WC_Numeric), ('\u{111da}', '\u{111da}', WC_ALetter), ('\u{111dc}', '\u{111dc}', - WC_ALetter), ('\u{11200}', '\u{11211}', WC_ALetter), ('\u{11213}', '\u{1122b}', WC_ALetter), - ('\u{1122c}', '\u{11237}', WC_Extend), ('\u{1123e}', '\u{1123e}', WC_Extend), ('\u{11280}', - '\u{11286}', WC_ALetter), ('\u{11288}', '\u{11288}', WC_ALetter), ('\u{1128a}', '\u{1128d}', - WC_ALetter), ('\u{1128f}', '\u{1129d}', WC_ALetter), ('\u{1129f}', '\u{112a8}', WC_ALetter), - ('\u{112b0}', '\u{112de}', WC_ALetter), ('\u{112df}', '\u{112ea}', WC_Extend), ('\u{112f0}', - '\u{112f9}', WC_Numeric), ('\u{11300}', '\u{11303}', WC_Extend), ('\u{11305}', '\u{1130c}', - WC_ALetter), ('\u{1130f}', '\u{11310}', WC_ALetter), ('\u{11313}', '\u{11328}', WC_ALetter), - ('\u{1132a}', '\u{11330}', WC_ALetter), ('\u{11332}', '\u{11333}', WC_ALetter), - ('\u{11335}', '\u{11339}', WC_ALetter), ('\u{1133b}', '\u{1133c}', WC_Extend), ('\u{1133d}', - '\u{1133d}', WC_ALetter), ('\u{1133e}', '\u{11344}', WC_Extend), ('\u{11347}', '\u{11348}', - WC_Extend), ('\u{1134b}', '\u{1134d}', WC_Extend), ('\u{11350}', '\u{11350}', WC_ALetter), - ('\u{11357}', '\u{11357}', WC_Extend), ('\u{1135d}', '\u{11361}', WC_ALetter), ('\u{11362}', - '\u{11363}', WC_Extend), ('\u{11366}', '\u{1136c}', WC_Extend), ('\u{11370}', '\u{11374}', - WC_Extend), ('\u{11400}', '\u{11434}', WC_ALetter), ('\u{11435}', '\u{11446}', WC_Extend), - ('\u{11447}', '\u{1144a}', WC_ALetter), ('\u{11450}', '\u{11459}', WC_Numeric), - ('\u{1145e}', '\u{1145e}', WC_Extend), ('\u{1145f}', '\u{11461}', WC_ALetter), ('\u{11480}', - '\u{114af}', WC_ALetter), ('\u{114b0}', '\u{114c3}', WC_Extend), ('\u{114c4}', '\u{114c5}', - WC_ALetter), ('\u{114c7}', '\u{114c7}', WC_ALetter), ('\u{114d0}', '\u{114d9}', WC_Numeric), - ('\u{11580}', '\u{115ae}', WC_ALetter), ('\u{115af}', '\u{115b5}', WC_Extend), ('\u{115b8}', - '\u{115c0}', WC_Extend), ('\u{115d8}', '\u{115db}', WC_ALetter), ('\u{115dc}', '\u{115dd}', - WC_Extend), ('\u{11600}', '\u{1162f}', WC_ALetter), ('\u{11630}', '\u{11640}', WC_Extend), - ('\u{11644}', '\u{11644}', WC_ALetter), ('\u{11650}', '\u{11659}', WC_Numeric), - ('\u{11680}', '\u{116aa}', WC_ALetter), ('\u{116ab}', '\u{116b7}', WC_Extend), ('\u{116b8}', - '\u{116b8}', WC_ALetter), ('\u{116c0}', '\u{116c9}', WC_Numeric), ('\u{1171d}', '\u{1172b}', - WC_Extend), ('\u{11730}', '\u{11739}', WC_Numeric), ('\u{11800}', '\u{1182b}', WC_ALetter), - ('\u{1182c}', '\u{1183a}', WC_Extend), ('\u{118a0}', '\u{118df}', WC_ALetter), ('\u{118e0}', - '\u{118e9}', WC_Numeric), ('\u{118ff}', '\u{11906}', WC_ALetter), ('\u{11909}', '\u{11909}', - WC_ALetter), ('\u{1190c}', '\u{11913}', WC_ALetter), ('\u{11915}', '\u{11916}', WC_ALetter), + WC_Extend), ('\u{10eb0}', '\u{10eb1}', WC_ALetter), ('\u{10efd}', '\u{10eff}', WC_Extend), + ('\u{10f00}', '\u{10f1c}', WC_ALetter), ('\u{10f27}', '\u{10f27}', WC_ALetter), + ('\u{10f30}', '\u{10f45}', WC_ALetter), ('\u{10f46}', '\u{10f50}', WC_Extend), ('\u{10f70}', + '\u{10f81}', WC_ALetter), ('\u{10f82}', '\u{10f85}', WC_Extend), ('\u{10fb0}', '\u{10fc4}', + WC_ALetter), ('\u{10fe0}', '\u{10ff6}', WC_ALetter), ('\u{11000}', '\u{11002}', WC_Extend), + ('\u{11003}', '\u{11037}', WC_ALetter), ('\u{11038}', '\u{11046}', WC_Extend), ('\u{11066}', + '\u{1106f}', WC_Numeric), ('\u{11070}', '\u{11070}', WC_Extend), ('\u{11071}', '\u{11072}', + WC_ALetter), ('\u{11073}', '\u{11074}', WC_Extend), ('\u{11075}', '\u{11075}', WC_ALetter), + ('\u{1107f}', '\u{11082}', WC_Extend), ('\u{11083}', '\u{110af}', WC_ALetter), ('\u{110b0}', + '\u{110ba}', WC_Extend), ('\u{110bd}', '\u{110bd}', WC_Format), ('\u{110c2}', '\u{110c2}', + WC_Extend), ('\u{110cd}', '\u{110cd}', WC_Format), ('\u{110d0}', '\u{110e8}', WC_ALetter), + ('\u{110f0}', '\u{110f9}', WC_Numeric), ('\u{11100}', '\u{11102}', WC_Extend), ('\u{11103}', + '\u{11126}', WC_ALetter), ('\u{11127}', '\u{11134}', WC_Extend), ('\u{11136}', '\u{1113f}', + WC_Numeric), ('\u{11144}', '\u{11144}', WC_ALetter), ('\u{11145}', '\u{11146}', WC_Extend), + ('\u{11147}', '\u{11147}', WC_ALetter), ('\u{11150}', '\u{11172}', WC_ALetter), + ('\u{11173}', '\u{11173}', WC_Extend), ('\u{11176}', '\u{11176}', WC_ALetter), ('\u{11180}', + '\u{11182}', WC_Extend), ('\u{11183}', '\u{111b2}', WC_ALetter), ('\u{111b3}', '\u{111c0}', + WC_Extend), ('\u{111c1}', '\u{111c4}', WC_ALetter), ('\u{111c9}', '\u{111cc}', WC_Extend), + ('\u{111ce}', '\u{111cf}', WC_Extend), ('\u{111d0}', '\u{111d9}', WC_Numeric), ('\u{111da}', + '\u{111da}', WC_ALetter), ('\u{111dc}', '\u{111dc}', WC_ALetter), ('\u{11200}', '\u{11211}', + WC_ALetter), ('\u{11213}', '\u{1122b}', WC_ALetter), ('\u{1122c}', '\u{11237}', WC_Extend), + ('\u{1123e}', '\u{1123e}', WC_Extend), ('\u{1123f}', '\u{11240}', WC_ALetter), ('\u{11241}', + '\u{11241}', WC_Extend), ('\u{11280}', '\u{11286}', WC_ALetter), ('\u{11288}', '\u{11288}', + WC_ALetter), ('\u{1128a}', '\u{1128d}', WC_ALetter), ('\u{1128f}', '\u{1129d}', WC_ALetter), + ('\u{1129f}', '\u{112a8}', WC_ALetter), ('\u{112b0}', '\u{112de}', WC_ALetter), + ('\u{112df}', '\u{112ea}', WC_Extend), ('\u{112f0}', '\u{112f9}', WC_Numeric), ('\u{11300}', + '\u{11303}', WC_Extend), ('\u{11305}', '\u{1130c}', WC_ALetter), ('\u{1130f}', '\u{11310}', + WC_ALetter), ('\u{11313}', '\u{11328}', WC_ALetter), ('\u{1132a}', '\u{11330}', WC_ALetter), + ('\u{11332}', '\u{11333}', WC_ALetter), ('\u{11335}', '\u{11339}', WC_ALetter), + ('\u{1133b}', '\u{1133c}', WC_Extend), ('\u{1133d}', '\u{1133d}', WC_ALetter), ('\u{1133e}', + '\u{11344}', WC_Extend), ('\u{11347}', '\u{11348}', WC_Extend), ('\u{1134b}', '\u{1134d}', + WC_Extend), ('\u{11350}', '\u{11350}', WC_ALetter), ('\u{11357}', '\u{11357}', WC_Extend), + ('\u{1135d}', '\u{11361}', WC_ALetter), ('\u{11362}', '\u{11363}', WC_Extend), ('\u{11366}', + '\u{1136c}', WC_Extend), ('\u{11370}', '\u{11374}', WC_Extend), ('\u{11400}', '\u{11434}', + WC_ALetter), ('\u{11435}', '\u{11446}', WC_Extend), ('\u{11447}', '\u{1144a}', WC_ALetter), + ('\u{11450}', '\u{11459}', WC_Numeric), ('\u{1145e}', '\u{1145e}', WC_Extend), ('\u{1145f}', + '\u{11461}', WC_ALetter), ('\u{11480}', '\u{114af}', WC_ALetter), ('\u{114b0}', '\u{114c3}', + WC_Extend), ('\u{114c4}', '\u{114c5}', WC_ALetter), ('\u{114c7}', '\u{114c7}', WC_ALetter), + ('\u{114d0}', '\u{114d9}', WC_Numeric), ('\u{11580}', '\u{115ae}', WC_ALetter), + ('\u{115af}', '\u{115b5}', WC_Extend), ('\u{115b8}', '\u{115c0}', WC_Extend), ('\u{115d8}', + '\u{115db}', WC_ALetter), ('\u{115dc}', '\u{115dd}', WC_Extend), ('\u{11600}', '\u{1162f}', + WC_ALetter), ('\u{11630}', '\u{11640}', WC_Extend), ('\u{11644}', '\u{11644}', WC_ALetter), + ('\u{11650}', '\u{11659}', WC_Numeric), ('\u{11680}', '\u{116aa}', WC_ALetter), + ('\u{116ab}', '\u{116b7}', WC_Extend), ('\u{116b8}', '\u{116b8}', WC_ALetter), ('\u{116c0}', + '\u{116c9}', WC_Numeric), ('\u{1171d}', '\u{1172b}', WC_Extend), ('\u{11730}', '\u{11739}', + WC_Numeric), ('\u{11800}', '\u{1182b}', WC_ALetter), ('\u{1182c}', '\u{1183a}', WC_Extend), + ('\u{118a0}', '\u{118df}', WC_ALetter), ('\u{118e0}', '\u{118e9}', WC_Numeric), + ('\u{118ff}', '\u{11906}', WC_ALetter), ('\u{11909}', '\u{11909}', WC_ALetter), + ('\u{1190c}', '\u{11913}', WC_ALetter), ('\u{11915}', '\u{11916}', WC_ALetter), ('\u{11918}', '\u{1192f}', WC_ALetter), ('\u{11930}', '\u{11935}', WC_Extend), ('\u{11937}', '\u{11938}', WC_Extend), ('\u{1193b}', '\u{1193e}', WC_Extend), ('\u{1193f}', '\u{1193f}', WC_ALetter), ('\u{11940}', '\u{11940}', WC_Extend), ('\u{11941}', '\u{11941}', WC_ALetter), @@ -1418,12 +1433,17 @@ pub mod word { ('\u{11d8a}', '\u{11d8e}', WC_Extend), ('\u{11d90}', '\u{11d91}', WC_Extend), ('\u{11d93}', '\u{11d97}', WC_Extend), ('\u{11d98}', '\u{11d98}', WC_ALetter), ('\u{11da0}', '\u{11da9}', WC_Numeric), ('\u{11ee0}', '\u{11ef2}', WC_ALetter), ('\u{11ef3}', '\u{11ef6}', WC_Extend), - ('\u{11fb0}', '\u{11fb0}', WC_ALetter), ('\u{12000}', '\u{12399}', WC_ALetter), - ('\u{12400}', '\u{1246e}', WC_ALetter), ('\u{12480}', '\u{12543}', WC_ALetter), - ('\u{12f90}', '\u{12ff0}', WC_ALetter), ('\u{13000}', '\u{1342e}', WC_ALetter), - ('\u{13430}', '\u{13438}', WC_Format), ('\u{14400}', '\u{14646}', WC_ALetter), ('\u{16800}', - '\u{16a38}', WC_ALetter), ('\u{16a40}', '\u{16a5e}', WC_ALetter), ('\u{16a60}', '\u{16a69}', - WC_Numeric), ('\u{16a70}', '\u{16abe}', WC_ALetter), ('\u{16ac0}', '\u{16ac9}', WC_Numeric), + ('\u{11f00}', '\u{11f01}', WC_Extend), ('\u{11f02}', '\u{11f02}', WC_ALetter), ('\u{11f03}', + '\u{11f03}', WC_Extend), ('\u{11f04}', '\u{11f10}', WC_ALetter), ('\u{11f12}', '\u{11f33}', + WC_ALetter), ('\u{11f34}', '\u{11f3a}', WC_Extend), ('\u{11f3e}', '\u{11f42}', WC_Extend), + ('\u{11f50}', '\u{11f59}', WC_Numeric), ('\u{11fb0}', '\u{11fb0}', WC_ALetter), + ('\u{12000}', '\u{12399}', WC_ALetter), ('\u{12400}', '\u{1246e}', WC_ALetter), + ('\u{12480}', '\u{12543}', WC_ALetter), ('\u{12f90}', '\u{12ff0}', WC_ALetter), + ('\u{13000}', '\u{1342f}', WC_ALetter), ('\u{13430}', '\u{1343f}', WC_Format), ('\u{13440}', + '\u{13440}', WC_Extend), ('\u{13441}', '\u{13446}', WC_ALetter), ('\u{13447}', '\u{13455}', + WC_Extend), ('\u{14400}', '\u{14646}', WC_ALetter), ('\u{16800}', '\u{16a38}', WC_ALetter), + ('\u{16a40}', '\u{16a5e}', WC_ALetter), ('\u{16a60}', '\u{16a69}', WC_Numeric), + ('\u{16a70}', '\u{16abe}', WC_ALetter), ('\u{16ac0}', '\u{16ac9}', WC_Numeric), ('\u{16ad0}', '\u{16aed}', WC_ALetter), ('\u{16af0}', '\u{16af4}', WC_Extend), ('\u{16b00}', '\u{16b2f}', WC_ALetter), ('\u{16b30}', '\u{16b36}', WC_Extend), ('\u{16b40}', '\u{16b43}', WC_ALetter), ('\u{16b50}', '\u{16b59}', WC_Numeric), ('\u{16b63}', '\u{16b77}', WC_ALetter), @@ -1434,40 +1454,43 @@ pub mod word { ('\u{16fe3}', '\u{16fe3}', WC_ALetter), ('\u{16fe4}', '\u{16fe4}', WC_Extend), ('\u{16ff0}', '\u{16ff1}', WC_Extend), ('\u{1aff0}', '\u{1aff3}', WC_Katakana), ('\u{1aff5}', '\u{1affb}', WC_Katakana), ('\u{1affd}', '\u{1affe}', WC_Katakana), ('\u{1b000}', '\u{1b000}', - WC_Katakana), ('\u{1b120}', '\u{1b122}', WC_Katakana), ('\u{1b164}', '\u{1b167}', - WC_Katakana), ('\u{1bc00}', '\u{1bc6a}', WC_ALetter), ('\u{1bc70}', '\u{1bc7c}', - WC_ALetter), ('\u{1bc80}', '\u{1bc88}', WC_ALetter), ('\u{1bc90}', '\u{1bc99}', WC_ALetter), - ('\u{1bc9d}', '\u{1bc9e}', WC_Extend), ('\u{1bca0}', '\u{1bca3}', WC_Format), ('\u{1cf00}', - '\u{1cf2d}', WC_Extend), ('\u{1cf30}', '\u{1cf46}', WC_Extend), ('\u{1d165}', '\u{1d169}', - WC_Extend), ('\u{1d16d}', '\u{1d172}', WC_Extend), ('\u{1d173}', '\u{1d17a}', WC_Format), - ('\u{1d17b}', '\u{1d182}', WC_Extend), ('\u{1d185}', '\u{1d18b}', WC_Extend), ('\u{1d1aa}', - '\u{1d1ad}', WC_Extend), ('\u{1d242}', '\u{1d244}', WC_Extend), ('\u{1d400}', '\u{1d454}', - WC_ALetter), ('\u{1d456}', '\u{1d49c}', WC_ALetter), ('\u{1d49e}', '\u{1d49f}', WC_ALetter), - ('\u{1d4a2}', '\u{1d4a2}', WC_ALetter), ('\u{1d4a5}', '\u{1d4a6}', WC_ALetter), - ('\u{1d4a9}', '\u{1d4ac}', WC_ALetter), ('\u{1d4ae}', '\u{1d4b9}', WC_ALetter), - ('\u{1d4bb}', '\u{1d4bb}', WC_ALetter), ('\u{1d4bd}', '\u{1d4c3}', WC_ALetter), - ('\u{1d4c5}', '\u{1d505}', WC_ALetter), ('\u{1d507}', '\u{1d50a}', WC_ALetter), - ('\u{1d50d}', '\u{1d514}', WC_ALetter), ('\u{1d516}', '\u{1d51c}', WC_ALetter), - ('\u{1d51e}', '\u{1d539}', WC_ALetter), ('\u{1d53b}', '\u{1d53e}', WC_ALetter), - ('\u{1d540}', '\u{1d544}', WC_ALetter), ('\u{1d546}', '\u{1d546}', WC_ALetter), - ('\u{1d54a}', '\u{1d550}', WC_ALetter), ('\u{1d552}', '\u{1d6a5}', WC_ALetter), - ('\u{1d6a8}', '\u{1d6c0}', WC_ALetter), ('\u{1d6c2}', '\u{1d6da}', WC_ALetter), - ('\u{1d6dc}', '\u{1d6fa}', WC_ALetter), ('\u{1d6fc}', '\u{1d714}', WC_ALetter), - ('\u{1d716}', '\u{1d734}', WC_ALetter), ('\u{1d736}', '\u{1d74e}', WC_ALetter), - ('\u{1d750}', '\u{1d76e}', WC_ALetter), ('\u{1d770}', '\u{1d788}', WC_ALetter), - ('\u{1d78a}', '\u{1d7a8}', WC_ALetter), ('\u{1d7aa}', '\u{1d7c2}', WC_ALetter), - ('\u{1d7c4}', '\u{1d7cb}', WC_ALetter), ('\u{1d7ce}', '\u{1d7ff}', WC_Numeric), - ('\u{1da00}', '\u{1da36}', WC_Extend), ('\u{1da3b}', '\u{1da6c}', WC_Extend), ('\u{1da75}', - '\u{1da75}', WC_Extend), ('\u{1da84}', '\u{1da84}', WC_Extend), ('\u{1da9b}', '\u{1da9f}', - WC_Extend), ('\u{1daa1}', '\u{1daaf}', WC_Extend), ('\u{1df00}', '\u{1df1e}', WC_ALetter), + WC_Katakana), ('\u{1b120}', '\u{1b122}', WC_Katakana), ('\u{1b155}', '\u{1b155}', + WC_Katakana), ('\u{1b164}', '\u{1b167}', WC_Katakana), ('\u{1bc00}', '\u{1bc6a}', + WC_ALetter), ('\u{1bc70}', '\u{1bc7c}', WC_ALetter), ('\u{1bc80}', '\u{1bc88}', WC_ALetter), + ('\u{1bc90}', '\u{1bc99}', WC_ALetter), ('\u{1bc9d}', '\u{1bc9e}', WC_Extend), ('\u{1bca0}', + '\u{1bca3}', WC_Format), ('\u{1cf00}', '\u{1cf2d}', WC_Extend), ('\u{1cf30}', '\u{1cf46}', + WC_Extend), ('\u{1d165}', '\u{1d169}', WC_Extend), ('\u{1d16d}', '\u{1d172}', WC_Extend), + ('\u{1d173}', '\u{1d17a}', WC_Format), ('\u{1d17b}', '\u{1d182}', WC_Extend), ('\u{1d185}', + '\u{1d18b}', WC_Extend), ('\u{1d1aa}', '\u{1d1ad}', WC_Extend), ('\u{1d242}', '\u{1d244}', + WC_Extend), ('\u{1d400}', '\u{1d454}', WC_ALetter), ('\u{1d456}', '\u{1d49c}', WC_ALetter), + ('\u{1d49e}', '\u{1d49f}', WC_ALetter), ('\u{1d4a2}', '\u{1d4a2}', WC_ALetter), + ('\u{1d4a5}', '\u{1d4a6}', WC_ALetter), ('\u{1d4a9}', '\u{1d4ac}', WC_ALetter), + ('\u{1d4ae}', '\u{1d4b9}', WC_ALetter), ('\u{1d4bb}', '\u{1d4bb}', WC_ALetter), + ('\u{1d4bd}', '\u{1d4c3}', WC_ALetter), ('\u{1d4c5}', '\u{1d505}', WC_ALetter), + ('\u{1d507}', '\u{1d50a}', WC_ALetter), ('\u{1d50d}', '\u{1d514}', WC_ALetter), + ('\u{1d516}', '\u{1d51c}', WC_ALetter), ('\u{1d51e}', '\u{1d539}', WC_ALetter), + ('\u{1d53b}', '\u{1d53e}', WC_ALetter), ('\u{1d540}', '\u{1d544}', WC_ALetter), + ('\u{1d546}', '\u{1d546}', WC_ALetter), ('\u{1d54a}', '\u{1d550}', WC_ALetter), + ('\u{1d552}', '\u{1d6a5}', WC_ALetter), ('\u{1d6a8}', '\u{1d6c0}', WC_ALetter), + ('\u{1d6c2}', '\u{1d6da}', WC_ALetter), ('\u{1d6dc}', '\u{1d6fa}', WC_ALetter), + ('\u{1d6fc}', '\u{1d714}', WC_ALetter), ('\u{1d716}', '\u{1d734}', WC_ALetter), + ('\u{1d736}', '\u{1d74e}', WC_ALetter), ('\u{1d750}', '\u{1d76e}', WC_ALetter), + ('\u{1d770}', '\u{1d788}', WC_ALetter), ('\u{1d78a}', '\u{1d7a8}', WC_ALetter), + ('\u{1d7aa}', '\u{1d7c2}', WC_ALetter), ('\u{1d7c4}', '\u{1d7cb}', WC_ALetter), + ('\u{1d7ce}', '\u{1d7ff}', WC_Numeric), ('\u{1da00}', '\u{1da36}', WC_Extend), ('\u{1da3b}', + '\u{1da6c}', WC_Extend), ('\u{1da75}', '\u{1da75}', WC_Extend), ('\u{1da84}', '\u{1da84}', + WC_Extend), ('\u{1da9b}', '\u{1da9f}', WC_Extend), ('\u{1daa1}', '\u{1daaf}', WC_Extend), + ('\u{1df00}', '\u{1df1e}', WC_ALetter), ('\u{1df25}', '\u{1df2a}', WC_ALetter), ('\u{1e000}', '\u{1e006}', WC_Extend), ('\u{1e008}', '\u{1e018}', WC_Extend), ('\u{1e01b}', '\u{1e021}', WC_Extend), ('\u{1e023}', '\u{1e024}', WC_Extend), ('\u{1e026}', '\u{1e02a}', - WC_Extend), ('\u{1e100}', '\u{1e12c}', WC_ALetter), ('\u{1e130}', '\u{1e136}', WC_Extend), - ('\u{1e137}', '\u{1e13d}', WC_ALetter), ('\u{1e140}', '\u{1e149}', WC_Numeric), - ('\u{1e14e}', '\u{1e14e}', WC_ALetter), ('\u{1e290}', '\u{1e2ad}', WC_ALetter), - ('\u{1e2ae}', '\u{1e2ae}', WC_Extend), ('\u{1e2c0}', '\u{1e2eb}', WC_ALetter), ('\u{1e2ec}', - '\u{1e2ef}', WC_Extend), ('\u{1e2f0}', '\u{1e2f9}', WC_Numeric), ('\u{1e7e0}', '\u{1e7e6}', - WC_ALetter), ('\u{1e7e8}', '\u{1e7eb}', WC_ALetter), ('\u{1e7ed}', '\u{1e7ee}', WC_ALetter), + WC_Extend), ('\u{1e030}', '\u{1e06d}', WC_ALetter), ('\u{1e08f}', '\u{1e08f}', WC_Extend), + ('\u{1e100}', '\u{1e12c}', WC_ALetter), ('\u{1e130}', '\u{1e136}', WC_Extend), ('\u{1e137}', + '\u{1e13d}', WC_ALetter), ('\u{1e140}', '\u{1e149}', WC_Numeric), ('\u{1e14e}', '\u{1e14e}', + WC_ALetter), ('\u{1e290}', '\u{1e2ad}', WC_ALetter), ('\u{1e2ae}', '\u{1e2ae}', WC_Extend), + ('\u{1e2c0}', '\u{1e2eb}', WC_ALetter), ('\u{1e2ec}', '\u{1e2ef}', WC_Extend), ('\u{1e2f0}', + '\u{1e2f9}', WC_Numeric), ('\u{1e4d0}', '\u{1e4eb}', WC_ALetter), ('\u{1e4ec}', '\u{1e4ef}', + WC_Extend), ('\u{1e4f0}', '\u{1e4f9}', WC_Numeric), ('\u{1e7e0}', '\u{1e7e6}', WC_ALetter), + ('\u{1e7e8}', '\u{1e7eb}', WC_ALetter), ('\u{1e7ed}', '\u{1e7ee}', WC_ALetter), ('\u{1e7f0}', '\u{1e7fe}', WC_ALetter), ('\u{1e800}', '\u{1e8c4}', WC_ALetter), ('\u{1e8d0}', '\u{1e8d6}', WC_Extend), ('\u{1e900}', '\u{1e943}', WC_ALetter), ('\u{1e944}', '\u{1e94a}', WC_Extend), ('\u{1e94b}', '\u{1e94b}', WC_ALetter), ('\u{1e950}', '\u{1e959}', @@ -1941,508 +1964,509 @@ pub mod sentence { ('\u{cc6}', '\u{cc8}', SC_Extend), ('\u{cca}', '\u{ccd}', SC_Extend), ('\u{cd5}', '\u{cd6}', SC_Extend), ('\u{cdd}', '\u{cde}', SC_OLetter), ('\u{ce0}', '\u{ce1}', SC_OLetter), ('\u{ce2}', '\u{ce3}', SC_Extend), ('\u{ce6}', '\u{cef}', SC_Numeric), ('\u{cf1}', - '\u{cf2}', SC_OLetter), ('\u{d00}', '\u{d03}', SC_Extend), ('\u{d04}', '\u{d0c}', - SC_OLetter), ('\u{d0e}', '\u{d10}', SC_OLetter), ('\u{d12}', '\u{d3a}', SC_OLetter), - ('\u{d3b}', '\u{d3c}', SC_Extend), ('\u{d3d}', '\u{d3d}', SC_OLetter), ('\u{d3e}', - '\u{d44}', SC_Extend), ('\u{d46}', '\u{d48}', SC_Extend), ('\u{d4a}', '\u{d4d}', SC_Extend), - ('\u{d4e}', '\u{d4e}', SC_OLetter), ('\u{d54}', '\u{d56}', SC_OLetter), ('\u{d57}', - '\u{d57}', SC_Extend), ('\u{d5f}', '\u{d61}', SC_OLetter), ('\u{d62}', '\u{d63}', - SC_Extend), ('\u{d66}', '\u{d6f}', SC_Numeric), ('\u{d7a}', '\u{d7f}', SC_OLetter), - ('\u{d81}', '\u{d83}', SC_Extend), ('\u{d85}', '\u{d96}', SC_OLetter), ('\u{d9a}', - '\u{db1}', SC_OLetter), ('\u{db3}', '\u{dbb}', SC_OLetter), ('\u{dbd}', '\u{dbd}', - SC_OLetter), ('\u{dc0}', '\u{dc6}', SC_OLetter), ('\u{dca}', '\u{dca}', SC_Extend), - ('\u{dcf}', '\u{dd4}', SC_Extend), ('\u{dd6}', '\u{dd6}', SC_Extend), ('\u{dd8}', '\u{ddf}', - SC_Extend), ('\u{de6}', '\u{def}', SC_Numeric), ('\u{df2}', '\u{df3}', SC_Extend), - ('\u{e01}', '\u{e30}', SC_OLetter), ('\u{e31}', '\u{e31}', SC_Extend), ('\u{e32}', - '\u{e33}', SC_OLetter), ('\u{e34}', '\u{e3a}', SC_Extend), ('\u{e40}', '\u{e46}', - SC_OLetter), ('\u{e47}', '\u{e4e}', SC_Extend), ('\u{e50}', '\u{e59}', SC_Numeric), - ('\u{e81}', '\u{e82}', SC_OLetter), ('\u{e84}', '\u{e84}', SC_OLetter), ('\u{e86}', - '\u{e8a}', SC_OLetter), ('\u{e8c}', '\u{ea3}', SC_OLetter), ('\u{ea5}', '\u{ea5}', - SC_OLetter), ('\u{ea7}', '\u{eb0}', SC_OLetter), ('\u{eb1}', '\u{eb1}', SC_Extend), - ('\u{eb2}', '\u{eb3}', SC_OLetter), ('\u{eb4}', '\u{ebc}', SC_Extend), ('\u{ebd}', - '\u{ebd}', SC_OLetter), ('\u{ec0}', '\u{ec4}', SC_OLetter), ('\u{ec6}', '\u{ec6}', - SC_OLetter), ('\u{ec8}', '\u{ecd}', SC_Extend), ('\u{ed0}', '\u{ed9}', SC_Numeric), - ('\u{edc}', '\u{edf}', SC_OLetter), ('\u{f00}', '\u{f00}', SC_OLetter), ('\u{f18}', - '\u{f19}', SC_Extend), ('\u{f20}', '\u{f29}', SC_Numeric), ('\u{f35}', '\u{f35}', - SC_Extend), ('\u{f37}', '\u{f37}', SC_Extend), ('\u{f39}', '\u{f39}', SC_Extend), - ('\u{f3a}', '\u{f3d}', SC_Close), ('\u{f3e}', '\u{f3f}', SC_Extend), ('\u{f40}', '\u{f47}', - SC_OLetter), ('\u{f49}', '\u{f6c}', SC_OLetter), ('\u{f71}', '\u{f84}', SC_Extend), - ('\u{f86}', '\u{f87}', SC_Extend), ('\u{f88}', '\u{f8c}', SC_OLetter), ('\u{f8d}', - '\u{f97}', SC_Extend), ('\u{f99}', '\u{fbc}', SC_Extend), ('\u{fc6}', '\u{fc6}', SC_Extend), - ('\u{1000}', '\u{102a}', SC_OLetter), ('\u{102b}', '\u{103e}', SC_Extend), ('\u{103f}', - '\u{103f}', SC_OLetter), ('\u{1040}', '\u{1049}', SC_Numeric), ('\u{104a}', '\u{104b}', - SC_STerm), ('\u{1050}', '\u{1055}', SC_OLetter), ('\u{1056}', '\u{1059}', SC_Extend), - ('\u{105a}', '\u{105d}', SC_OLetter), ('\u{105e}', '\u{1060}', SC_Extend), ('\u{1061}', - '\u{1061}', SC_OLetter), ('\u{1062}', '\u{1064}', SC_Extend), ('\u{1065}', '\u{1066}', - SC_OLetter), ('\u{1067}', '\u{106d}', SC_Extend), ('\u{106e}', '\u{1070}', SC_OLetter), - ('\u{1071}', '\u{1074}', SC_Extend), ('\u{1075}', '\u{1081}', SC_OLetter), ('\u{1082}', - '\u{108d}', SC_Extend), ('\u{108e}', '\u{108e}', SC_OLetter), ('\u{108f}', '\u{108f}', - SC_Extend), ('\u{1090}', '\u{1099}', SC_Numeric), ('\u{109a}', '\u{109d}', SC_Extend), - ('\u{10a0}', '\u{10c5}', SC_Upper), ('\u{10c7}', '\u{10c7}', SC_Upper), ('\u{10cd}', - '\u{10cd}', SC_Upper), ('\u{10d0}', '\u{10fa}', SC_OLetter), ('\u{10fc}', '\u{1248}', - SC_OLetter), ('\u{124a}', '\u{124d}', SC_OLetter), ('\u{1250}', '\u{1256}', SC_OLetter), - ('\u{1258}', '\u{1258}', SC_OLetter), ('\u{125a}', '\u{125d}', SC_OLetter), ('\u{1260}', - '\u{1288}', SC_OLetter), ('\u{128a}', '\u{128d}', SC_OLetter), ('\u{1290}', '\u{12b0}', - SC_OLetter), ('\u{12b2}', '\u{12b5}', SC_OLetter), ('\u{12b8}', '\u{12be}', SC_OLetter), - ('\u{12c0}', '\u{12c0}', SC_OLetter), ('\u{12c2}', '\u{12c5}', SC_OLetter), ('\u{12c8}', - '\u{12d6}', SC_OLetter), ('\u{12d8}', '\u{1310}', SC_OLetter), ('\u{1312}', '\u{1315}', - SC_OLetter), ('\u{1318}', '\u{135a}', SC_OLetter), ('\u{135d}', '\u{135f}', SC_Extend), - ('\u{1362}', '\u{1362}', SC_STerm), ('\u{1367}', '\u{1368}', SC_STerm), ('\u{1380}', - '\u{138f}', SC_OLetter), ('\u{13a0}', '\u{13f5}', SC_Upper), ('\u{13f8}', '\u{13fd}', - SC_Lower), ('\u{1401}', '\u{166c}', SC_OLetter), ('\u{166e}', '\u{166e}', SC_STerm), - ('\u{166f}', '\u{167f}', SC_OLetter), ('\u{1680}', '\u{1680}', SC_Sp), ('\u{1681}', - '\u{169a}', SC_OLetter), ('\u{169b}', '\u{169c}', SC_Close), ('\u{16a0}', '\u{16ea}', - SC_OLetter), ('\u{16ee}', '\u{16f8}', SC_OLetter), ('\u{1700}', '\u{1711}', SC_OLetter), - ('\u{1712}', '\u{1715}', SC_Extend), ('\u{171f}', '\u{1731}', SC_OLetter), ('\u{1732}', - '\u{1734}', SC_Extend), ('\u{1735}', '\u{1736}', SC_STerm), ('\u{1740}', '\u{1751}', - SC_OLetter), ('\u{1752}', '\u{1753}', SC_Extend), ('\u{1760}', '\u{176c}', SC_OLetter), - ('\u{176e}', '\u{1770}', SC_OLetter), ('\u{1772}', '\u{1773}', SC_Extend), ('\u{1780}', - '\u{17b3}', SC_OLetter), ('\u{17b4}', '\u{17d3}', SC_Extend), ('\u{17d7}', '\u{17d7}', - SC_OLetter), ('\u{17dc}', '\u{17dc}', SC_OLetter), ('\u{17dd}', '\u{17dd}', SC_Extend), - ('\u{17e0}', '\u{17e9}', SC_Numeric), ('\u{1802}', '\u{1802}', SC_SContinue), ('\u{1803}', - '\u{1803}', SC_STerm), ('\u{1808}', '\u{1808}', SC_SContinue), ('\u{1809}', '\u{1809}', - SC_STerm), ('\u{180b}', '\u{180d}', SC_Extend), ('\u{180e}', '\u{180e}', SC_Format), - ('\u{180f}', '\u{180f}', SC_Extend), ('\u{1810}', '\u{1819}', SC_Numeric), ('\u{1820}', - '\u{1878}', SC_OLetter), ('\u{1880}', '\u{1884}', SC_OLetter), ('\u{1885}', '\u{1886}', - SC_Extend), ('\u{1887}', '\u{18a8}', SC_OLetter), ('\u{18a9}', '\u{18a9}', SC_Extend), - ('\u{18aa}', '\u{18aa}', SC_OLetter), ('\u{18b0}', '\u{18f5}', SC_OLetter), ('\u{1900}', - '\u{191e}', SC_OLetter), ('\u{1920}', '\u{192b}', SC_Extend), ('\u{1930}', '\u{193b}', - SC_Extend), ('\u{1944}', '\u{1945}', SC_STerm), ('\u{1946}', '\u{194f}', SC_Numeric), - ('\u{1950}', '\u{196d}', SC_OLetter), ('\u{1970}', '\u{1974}', SC_OLetter), ('\u{1980}', - '\u{19ab}', SC_OLetter), ('\u{19b0}', '\u{19c9}', SC_OLetter), ('\u{19d0}', '\u{19d9}', - SC_Numeric), ('\u{1a00}', '\u{1a16}', SC_OLetter), ('\u{1a17}', '\u{1a1b}', SC_Extend), - ('\u{1a20}', '\u{1a54}', SC_OLetter), ('\u{1a55}', '\u{1a5e}', SC_Extend), ('\u{1a60}', - '\u{1a7c}', SC_Extend), ('\u{1a7f}', '\u{1a7f}', SC_Extend), ('\u{1a80}', '\u{1a89}', - SC_Numeric), ('\u{1a90}', '\u{1a99}', SC_Numeric), ('\u{1aa7}', '\u{1aa7}', SC_OLetter), - ('\u{1aa8}', '\u{1aab}', SC_STerm), ('\u{1ab0}', '\u{1ace}', SC_Extend), ('\u{1b00}', - '\u{1b04}', SC_Extend), ('\u{1b05}', '\u{1b33}', SC_OLetter), ('\u{1b34}', '\u{1b44}', - SC_Extend), ('\u{1b45}', '\u{1b4c}', SC_OLetter), ('\u{1b50}', '\u{1b59}', SC_Numeric), - ('\u{1b5a}', '\u{1b5b}', SC_STerm), ('\u{1b5e}', '\u{1b5f}', SC_STerm), ('\u{1b6b}', - '\u{1b73}', SC_Extend), ('\u{1b7d}', '\u{1b7e}', SC_STerm), ('\u{1b80}', '\u{1b82}', - SC_Extend), ('\u{1b83}', '\u{1ba0}', SC_OLetter), ('\u{1ba1}', '\u{1bad}', SC_Extend), - ('\u{1bae}', '\u{1baf}', SC_OLetter), ('\u{1bb0}', '\u{1bb9}', SC_Numeric), ('\u{1bba}', - '\u{1be5}', SC_OLetter), ('\u{1be6}', '\u{1bf3}', SC_Extend), ('\u{1c00}', '\u{1c23}', - SC_OLetter), ('\u{1c24}', '\u{1c37}', SC_Extend), ('\u{1c3b}', '\u{1c3c}', SC_STerm), - ('\u{1c40}', '\u{1c49}', SC_Numeric), ('\u{1c4d}', '\u{1c4f}', SC_OLetter), ('\u{1c50}', - '\u{1c59}', SC_Numeric), ('\u{1c5a}', '\u{1c7d}', SC_OLetter), ('\u{1c7e}', '\u{1c7f}', - SC_STerm), ('\u{1c80}', '\u{1c88}', SC_Lower), ('\u{1c90}', '\u{1cba}', SC_OLetter), - ('\u{1cbd}', '\u{1cbf}', SC_OLetter), ('\u{1cd0}', '\u{1cd2}', SC_Extend), ('\u{1cd4}', - '\u{1ce8}', SC_Extend), ('\u{1ce9}', '\u{1cec}', SC_OLetter), ('\u{1ced}', '\u{1ced}', - SC_Extend), ('\u{1cee}', '\u{1cf3}', SC_OLetter), ('\u{1cf4}', '\u{1cf4}', SC_Extend), - ('\u{1cf5}', '\u{1cf6}', SC_OLetter), ('\u{1cf7}', '\u{1cf9}', SC_Extend), ('\u{1cfa}', - '\u{1cfa}', SC_OLetter), ('\u{1d00}', '\u{1dbf}', SC_Lower), ('\u{1dc0}', '\u{1dff}', - SC_Extend), ('\u{1e00}', '\u{1e00}', SC_Upper), ('\u{1e01}', '\u{1e01}', SC_Lower), - ('\u{1e02}', '\u{1e02}', SC_Upper), ('\u{1e03}', '\u{1e03}', SC_Lower), ('\u{1e04}', - '\u{1e04}', SC_Upper), ('\u{1e05}', '\u{1e05}', SC_Lower), ('\u{1e06}', '\u{1e06}', - SC_Upper), ('\u{1e07}', '\u{1e07}', SC_Lower), ('\u{1e08}', '\u{1e08}', SC_Upper), - ('\u{1e09}', '\u{1e09}', SC_Lower), ('\u{1e0a}', '\u{1e0a}', SC_Upper), ('\u{1e0b}', - '\u{1e0b}', SC_Lower), ('\u{1e0c}', '\u{1e0c}', SC_Upper), ('\u{1e0d}', '\u{1e0d}', - SC_Lower), ('\u{1e0e}', '\u{1e0e}', SC_Upper), ('\u{1e0f}', '\u{1e0f}', SC_Lower), - ('\u{1e10}', '\u{1e10}', SC_Upper), ('\u{1e11}', '\u{1e11}', SC_Lower), ('\u{1e12}', - '\u{1e12}', SC_Upper), ('\u{1e13}', '\u{1e13}', SC_Lower), ('\u{1e14}', '\u{1e14}', - SC_Upper), ('\u{1e15}', '\u{1e15}', SC_Lower), ('\u{1e16}', '\u{1e16}', SC_Upper), - ('\u{1e17}', '\u{1e17}', SC_Lower), ('\u{1e18}', '\u{1e18}', SC_Upper), ('\u{1e19}', - '\u{1e19}', SC_Lower), ('\u{1e1a}', '\u{1e1a}', SC_Upper), ('\u{1e1b}', '\u{1e1b}', - SC_Lower), ('\u{1e1c}', '\u{1e1c}', SC_Upper), ('\u{1e1d}', '\u{1e1d}', SC_Lower), - ('\u{1e1e}', '\u{1e1e}', SC_Upper), ('\u{1e1f}', '\u{1e1f}', SC_Lower), ('\u{1e20}', - '\u{1e20}', SC_Upper), ('\u{1e21}', '\u{1e21}', SC_Lower), ('\u{1e22}', '\u{1e22}', - SC_Upper), ('\u{1e23}', '\u{1e23}', SC_Lower), ('\u{1e24}', '\u{1e24}', SC_Upper), - ('\u{1e25}', '\u{1e25}', SC_Lower), ('\u{1e26}', '\u{1e26}', SC_Upper), ('\u{1e27}', - '\u{1e27}', SC_Lower), ('\u{1e28}', '\u{1e28}', SC_Upper), ('\u{1e29}', '\u{1e29}', - SC_Lower), ('\u{1e2a}', '\u{1e2a}', SC_Upper), ('\u{1e2b}', '\u{1e2b}', SC_Lower), - ('\u{1e2c}', '\u{1e2c}', SC_Upper), ('\u{1e2d}', '\u{1e2d}', SC_Lower), ('\u{1e2e}', - '\u{1e2e}', SC_Upper), ('\u{1e2f}', '\u{1e2f}', SC_Lower), ('\u{1e30}', '\u{1e30}', - SC_Upper), ('\u{1e31}', '\u{1e31}', SC_Lower), ('\u{1e32}', '\u{1e32}', SC_Upper), - ('\u{1e33}', '\u{1e33}', SC_Lower), ('\u{1e34}', '\u{1e34}', SC_Upper), ('\u{1e35}', - '\u{1e35}', SC_Lower), ('\u{1e36}', '\u{1e36}', SC_Upper), ('\u{1e37}', '\u{1e37}', - SC_Lower), ('\u{1e38}', '\u{1e38}', SC_Upper), ('\u{1e39}', '\u{1e39}', SC_Lower), - ('\u{1e3a}', '\u{1e3a}', SC_Upper), ('\u{1e3b}', '\u{1e3b}', SC_Lower), ('\u{1e3c}', - '\u{1e3c}', SC_Upper), ('\u{1e3d}', '\u{1e3d}', SC_Lower), ('\u{1e3e}', '\u{1e3e}', - SC_Upper), ('\u{1e3f}', '\u{1e3f}', SC_Lower), ('\u{1e40}', '\u{1e40}', SC_Upper), - ('\u{1e41}', '\u{1e41}', SC_Lower), ('\u{1e42}', '\u{1e42}', SC_Upper), ('\u{1e43}', - '\u{1e43}', SC_Lower), ('\u{1e44}', '\u{1e44}', SC_Upper), ('\u{1e45}', '\u{1e45}', - SC_Lower), ('\u{1e46}', '\u{1e46}', SC_Upper), ('\u{1e47}', '\u{1e47}', SC_Lower), - ('\u{1e48}', '\u{1e48}', SC_Upper), ('\u{1e49}', '\u{1e49}', SC_Lower), ('\u{1e4a}', - '\u{1e4a}', SC_Upper), ('\u{1e4b}', '\u{1e4b}', SC_Lower), ('\u{1e4c}', '\u{1e4c}', - SC_Upper), ('\u{1e4d}', '\u{1e4d}', SC_Lower), ('\u{1e4e}', '\u{1e4e}', SC_Upper), - ('\u{1e4f}', '\u{1e4f}', SC_Lower), ('\u{1e50}', '\u{1e50}', SC_Upper), ('\u{1e51}', - '\u{1e51}', SC_Lower), ('\u{1e52}', '\u{1e52}', SC_Upper), ('\u{1e53}', '\u{1e53}', - SC_Lower), ('\u{1e54}', '\u{1e54}', SC_Upper), ('\u{1e55}', '\u{1e55}', SC_Lower), - ('\u{1e56}', '\u{1e56}', SC_Upper), ('\u{1e57}', '\u{1e57}', SC_Lower), ('\u{1e58}', - '\u{1e58}', SC_Upper), ('\u{1e59}', '\u{1e59}', SC_Lower), ('\u{1e5a}', '\u{1e5a}', - SC_Upper), ('\u{1e5b}', '\u{1e5b}', SC_Lower), ('\u{1e5c}', '\u{1e5c}', SC_Upper), - ('\u{1e5d}', '\u{1e5d}', SC_Lower), ('\u{1e5e}', '\u{1e5e}', SC_Upper), ('\u{1e5f}', - '\u{1e5f}', SC_Lower), ('\u{1e60}', '\u{1e60}', SC_Upper), ('\u{1e61}', '\u{1e61}', - SC_Lower), ('\u{1e62}', '\u{1e62}', SC_Upper), ('\u{1e63}', '\u{1e63}', SC_Lower), - ('\u{1e64}', '\u{1e64}', SC_Upper), ('\u{1e65}', '\u{1e65}', SC_Lower), ('\u{1e66}', - '\u{1e66}', SC_Upper), ('\u{1e67}', '\u{1e67}', SC_Lower), ('\u{1e68}', '\u{1e68}', - SC_Upper), ('\u{1e69}', '\u{1e69}', SC_Lower), ('\u{1e6a}', '\u{1e6a}', SC_Upper), - ('\u{1e6b}', '\u{1e6b}', SC_Lower), ('\u{1e6c}', '\u{1e6c}', SC_Upper), ('\u{1e6d}', - '\u{1e6d}', SC_Lower), ('\u{1e6e}', '\u{1e6e}', SC_Upper), ('\u{1e6f}', '\u{1e6f}', - SC_Lower), ('\u{1e70}', '\u{1e70}', SC_Upper), ('\u{1e71}', '\u{1e71}', SC_Lower), - ('\u{1e72}', '\u{1e72}', SC_Upper), ('\u{1e73}', '\u{1e73}', SC_Lower), ('\u{1e74}', - '\u{1e74}', SC_Upper), ('\u{1e75}', '\u{1e75}', SC_Lower), ('\u{1e76}', '\u{1e76}', - SC_Upper), ('\u{1e77}', '\u{1e77}', SC_Lower), ('\u{1e78}', '\u{1e78}', SC_Upper), - ('\u{1e79}', '\u{1e79}', SC_Lower), ('\u{1e7a}', '\u{1e7a}', SC_Upper), ('\u{1e7b}', - '\u{1e7b}', SC_Lower), ('\u{1e7c}', '\u{1e7c}', SC_Upper), ('\u{1e7d}', '\u{1e7d}', - SC_Lower), ('\u{1e7e}', '\u{1e7e}', SC_Upper), ('\u{1e7f}', '\u{1e7f}', SC_Lower), - ('\u{1e80}', '\u{1e80}', SC_Upper), ('\u{1e81}', '\u{1e81}', SC_Lower), ('\u{1e82}', - '\u{1e82}', SC_Upper), ('\u{1e83}', '\u{1e83}', SC_Lower), ('\u{1e84}', '\u{1e84}', - SC_Upper), ('\u{1e85}', '\u{1e85}', SC_Lower), ('\u{1e86}', '\u{1e86}', SC_Upper), - ('\u{1e87}', '\u{1e87}', SC_Lower), ('\u{1e88}', '\u{1e88}', SC_Upper), ('\u{1e89}', - '\u{1e89}', SC_Lower), ('\u{1e8a}', '\u{1e8a}', SC_Upper), ('\u{1e8b}', '\u{1e8b}', - SC_Lower), ('\u{1e8c}', '\u{1e8c}', SC_Upper), ('\u{1e8d}', '\u{1e8d}', SC_Lower), - ('\u{1e8e}', '\u{1e8e}', SC_Upper), ('\u{1e8f}', '\u{1e8f}', SC_Lower), ('\u{1e90}', - '\u{1e90}', SC_Upper), ('\u{1e91}', '\u{1e91}', SC_Lower), ('\u{1e92}', '\u{1e92}', - SC_Upper), ('\u{1e93}', '\u{1e93}', SC_Lower), ('\u{1e94}', '\u{1e94}', SC_Upper), - ('\u{1e95}', '\u{1e9d}', SC_Lower), ('\u{1e9e}', '\u{1e9e}', SC_Upper), ('\u{1e9f}', - '\u{1e9f}', SC_Lower), ('\u{1ea0}', '\u{1ea0}', SC_Upper), ('\u{1ea1}', '\u{1ea1}', - SC_Lower), ('\u{1ea2}', '\u{1ea2}', SC_Upper), ('\u{1ea3}', '\u{1ea3}', SC_Lower), - ('\u{1ea4}', '\u{1ea4}', SC_Upper), ('\u{1ea5}', '\u{1ea5}', SC_Lower), ('\u{1ea6}', - '\u{1ea6}', SC_Upper), ('\u{1ea7}', '\u{1ea7}', SC_Lower), ('\u{1ea8}', '\u{1ea8}', - SC_Upper), ('\u{1ea9}', '\u{1ea9}', SC_Lower), ('\u{1eaa}', '\u{1eaa}', SC_Upper), - ('\u{1eab}', '\u{1eab}', SC_Lower), ('\u{1eac}', '\u{1eac}', SC_Upper), ('\u{1ead}', - '\u{1ead}', SC_Lower), ('\u{1eae}', '\u{1eae}', SC_Upper), ('\u{1eaf}', '\u{1eaf}', - SC_Lower), ('\u{1eb0}', '\u{1eb0}', SC_Upper), ('\u{1eb1}', '\u{1eb1}', SC_Lower), - ('\u{1eb2}', '\u{1eb2}', SC_Upper), ('\u{1eb3}', '\u{1eb3}', SC_Lower), ('\u{1eb4}', - '\u{1eb4}', SC_Upper), ('\u{1eb5}', '\u{1eb5}', SC_Lower), ('\u{1eb6}', '\u{1eb6}', - SC_Upper), ('\u{1eb7}', '\u{1eb7}', SC_Lower), ('\u{1eb8}', '\u{1eb8}', SC_Upper), - ('\u{1eb9}', '\u{1eb9}', SC_Lower), ('\u{1eba}', '\u{1eba}', SC_Upper), ('\u{1ebb}', - '\u{1ebb}', SC_Lower), ('\u{1ebc}', '\u{1ebc}', SC_Upper), ('\u{1ebd}', '\u{1ebd}', - SC_Lower), ('\u{1ebe}', '\u{1ebe}', SC_Upper), ('\u{1ebf}', '\u{1ebf}', SC_Lower), - ('\u{1ec0}', '\u{1ec0}', SC_Upper), ('\u{1ec1}', '\u{1ec1}', SC_Lower), ('\u{1ec2}', - '\u{1ec2}', SC_Upper), ('\u{1ec3}', '\u{1ec3}', SC_Lower), ('\u{1ec4}', '\u{1ec4}', - SC_Upper), ('\u{1ec5}', '\u{1ec5}', SC_Lower), ('\u{1ec6}', '\u{1ec6}', SC_Upper), - ('\u{1ec7}', '\u{1ec7}', SC_Lower), ('\u{1ec8}', '\u{1ec8}', SC_Upper), ('\u{1ec9}', - '\u{1ec9}', SC_Lower), ('\u{1eca}', '\u{1eca}', SC_Upper), ('\u{1ecb}', '\u{1ecb}', - SC_Lower), ('\u{1ecc}', '\u{1ecc}', SC_Upper), ('\u{1ecd}', '\u{1ecd}', SC_Lower), - ('\u{1ece}', '\u{1ece}', SC_Upper), ('\u{1ecf}', '\u{1ecf}', SC_Lower), ('\u{1ed0}', - '\u{1ed0}', SC_Upper), ('\u{1ed1}', '\u{1ed1}', SC_Lower), ('\u{1ed2}', '\u{1ed2}', - SC_Upper), ('\u{1ed3}', '\u{1ed3}', SC_Lower), ('\u{1ed4}', '\u{1ed4}', SC_Upper), - ('\u{1ed5}', '\u{1ed5}', SC_Lower), ('\u{1ed6}', '\u{1ed6}', SC_Upper), ('\u{1ed7}', - '\u{1ed7}', SC_Lower), ('\u{1ed8}', '\u{1ed8}', SC_Upper), ('\u{1ed9}', '\u{1ed9}', - SC_Lower), ('\u{1eda}', '\u{1eda}', SC_Upper), ('\u{1edb}', '\u{1edb}', SC_Lower), - ('\u{1edc}', '\u{1edc}', SC_Upper), ('\u{1edd}', '\u{1edd}', SC_Lower), ('\u{1ede}', - '\u{1ede}', SC_Upper), ('\u{1edf}', '\u{1edf}', SC_Lower), ('\u{1ee0}', '\u{1ee0}', - SC_Upper), ('\u{1ee1}', '\u{1ee1}', SC_Lower), ('\u{1ee2}', '\u{1ee2}', SC_Upper), - ('\u{1ee3}', '\u{1ee3}', SC_Lower), ('\u{1ee4}', '\u{1ee4}', SC_Upper), ('\u{1ee5}', - '\u{1ee5}', SC_Lower), ('\u{1ee6}', '\u{1ee6}', SC_Upper), ('\u{1ee7}', '\u{1ee7}', - SC_Lower), ('\u{1ee8}', '\u{1ee8}', SC_Upper), ('\u{1ee9}', '\u{1ee9}', SC_Lower), - ('\u{1eea}', '\u{1eea}', SC_Upper), ('\u{1eeb}', '\u{1eeb}', SC_Lower), ('\u{1eec}', - '\u{1eec}', SC_Upper), ('\u{1eed}', '\u{1eed}', SC_Lower), ('\u{1eee}', '\u{1eee}', - SC_Upper), ('\u{1eef}', '\u{1eef}', SC_Lower), ('\u{1ef0}', '\u{1ef0}', SC_Upper), - ('\u{1ef1}', '\u{1ef1}', SC_Lower), ('\u{1ef2}', '\u{1ef2}', SC_Upper), ('\u{1ef3}', - '\u{1ef3}', SC_Lower), ('\u{1ef4}', '\u{1ef4}', SC_Upper), ('\u{1ef5}', '\u{1ef5}', - SC_Lower), ('\u{1ef6}', '\u{1ef6}', SC_Upper), ('\u{1ef7}', '\u{1ef7}', SC_Lower), - ('\u{1ef8}', '\u{1ef8}', SC_Upper), ('\u{1ef9}', '\u{1ef9}', SC_Lower), ('\u{1efa}', - '\u{1efa}', SC_Upper), ('\u{1efb}', '\u{1efb}', SC_Lower), ('\u{1efc}', '\u{1efc}', - SC_Upper), ('\u{1efd}', '\u{1efd}', SC_Lower), ('\u{1efe}', '\u{1efe}', SC_Upper), - ('\u{1eff}', '\u{1f07}', SC_Lower), ('\u{1f08}', '\u{1f0f}', SC_Upper), ('\u{1f10}', - '\u{1f15}', SC_Lower), ('\u{1f18}', '\u{1f1d}', SC_Upper), ('\u{1f20}', '\u{1f27}', - SC_Lower), ('\u{1f28}', '\u{1f2f}', SC_Upper), ('\u{1f30}', '\u{1f37}', SC_Lower), - ('\u{1f38}', '\u{1f3f}', SC_Upper), ('\u{1f40}', '\u{1f45}', SC_Lower), ('\u{1f48}', - '\u{1f4d}', SC_Upper), ('\u{1f50}', '\u{1f57}', SC_Lower), ('\u{1f59}', '\u{1f59}', - SC_Upper), ('\u{1f5b}', '\u{1f5b}', SC_Upper), ('\u{1f5d}', '\u{1f5d}', SC_Upper), - ('\u{1f5f}', '\u{1f5f}', SC_Upper), ('\u{1f60}', '\u{1f67}', SC_Lower), ('\u{1f68}', - '\u{1f6f}', SC_Upper), ('\u{1f70}', '\u{1f7d}', SC_Lower), ('\u{1f80}', '\u{1f87}', - SC_Lower), ('\u{1f88}', '\u{1f8f}', SC_Upper), ('\u{1f90}', '\u{1f97}', SC_Lower), - ('\u{1f98}', '\u{1f9f}', SC_Upper), ('\u{1fa0}', '\u{1fa7}', SC_Lower), ('\u{1fa8}', - '\u{1faf}', SC_Upper), ('\u{1fb0}', '\u{1fb4}', SC_Lower), ('\u{1fb6}', '\u{1fb7}', - SC_Lower), ('\u{1fb8}', '\u{1fbc}', SC_Upper), ('\u{1fbe}', '\u{1fbe}', SC_Lower), - ('\u{1fc2}', '\u{1fc4}', SC_Lower), ('\u{1fc6}', '\u{1fc7}', SC_Lower), ('\u{1fc8}', - '\u{1fcc}', SC_Upper), ('\u{1fd0}', '\u{1fd3}', SC_Lower), ('\u{1fd6}', '\u{1fd7}', - SC_Lower), ('\u{1fd8}', '\u{1fdb}', SC_Upper), ('\u{1fe0}', '\u{1fe7}', SC_Lower), - ('\u{1fe8}', '\u{1fec}', SC_Upper), ('\u{1ff2}', '\u{1ff4}', SC_Lower), ('\u{1ff6}', - '\u{1ff7}', SC_Lower), ('\u{1ff8}', '\u{1ffc}', SC_Upper), ('\u{2000}', '\u{200a}', SC_Sp), - ('\u{200b}', '\u{200b}', SC_Format), ('\u{200c}', '\u{200d}', SC_Extend), ('\u{200e}', - '\u{200f}', SC_Format), ('\u{2013}', '\u{2014}', SC_SContinue), ('\u{2018}', '\u{201f}', - SC_Close), ('\u{2024}', '\u{2024}', SC_ATerm), ('\u{2028}', '\u{2029}', SC_Sep), - ('\u{202a}', '\u{202e}', SC_Format), ('\u{202f}', '\u{202f}', SC_Sp), ('\u{2039}', - '\u{203a}', SC_Close), ('\u{203c}', '\u{203d}', SC_STerm), ('\u{2045}', '\u{2046}', - SC_Close), ('\u{2047}', '\u{2049}', SC_STerm), ('\u{205f}', '\u{205f}', SC_Sp), ('\u{2060}', - '\u{2064}', SC_Format), ('\u{2066}', '\u{206f}', SC_Format), ('\u{2071}', '\u{2071}', - SC_Lower), ('\u{207d}', '\u{207e}', SC_Close), ('\u{207f}', '\u{207f}', SC_Lower), - ('\u{208d}', '\u{208e}', SC_Close), ('\u{2090}', '\u{209c}', SC_Lower), ('\u{20d0}', - '\u{20f0}', SC_Extend), ('\u{2102}', '\u{2102}', SC_Upper), ('\u{2107}', '\u{2107}', - SC_Upper), ('\u{210a}', '\u{210a}', SC_Lower), ('\u{210b}', '\u{210d}', SC_Upper), - ('\u{210e}', '\u{210f}', SC_Lower), ('\u{2110}', '\u{2112}', SC_Upper), ('\u{2113}', - '\u{2113}', SC_Lower), ('\u{2115}', '\u{2115}', SC_Upper), ('\u{2119}', '\u{211d}', - SC_Upper), ('\u{2124}', '\u{2124}', SC_Upper), ('\u{2126}', '\u{2126}', SC_Upper), - ('\u{2128}', '\u{2128}', SC_Upper), ('\u{212a}', '\u{212d}', SC_Upper), ('\u{212f}', - '\u{212f}', SC_Lower), ('\u{2130}', '\u{2133}', SC_Upper), ('\u{2134}', '\u{2134}', - SC_Lower), ('\u{2135}', '\u{2138}', SC_OLetter), ('\u{2139}', '\u{2139}', SC_Lower), - ('\u{213c}', '\u{213d}', SC_Lower), ('\u{213e}', '\u{213f}', SC_Upper), ('\u{2145}', - '\u{2145}', SC_Upper), ('\u{2146}', '\u{2149}', SC_Lower), ('\u{214e}', '\u{214e}', - SC_Lower), ('\u{2160}', '\u{216f}', SC_Upper), ('\u{2170}', '\u{217f}', SC_Lower), - ('\u{2180}', '\u{2182}', SC_OLetter), ('\u{2183}', '\u{2183}', SC_Upper), ('\u{2184}', - '\u{2184}', SC_Lower), ('\u{2185}', '\u{2188}', SC_OLetter), ('\u{2308}', '\u{230b}', - SC_Close), ('\u{2329}', '\u{232a}', SC_Close), ('\u{24b6}', '\u{24cf}', SC_Upper), - ('\u{24d0}', '\u{24e9}', SC_Lower), ('\u{275b}', '\u{2760}', SC_Close), ('\u{2768}', - '\u{2775}', SC_Close), ('\u{27c5}', '\u{27c6}', SC_Close), ('\u{27e6}', '\u{27ef}', - SC_Close), ('\u{2983}', '\u{2998}', SC_Close), ('\u{29d8}', '\u{29db}', SC_Close), - ('\u{29fc}', '\u{29fd}', SC_Close), ('\u{2c00}', '\u{2c2f}', SC_Upper), ('\u{2c30}', - '\u{2c5f}', SC_Lower), ('\u{2c60}', '\u{2c60}', SC_Upper), ('\u{2c61}', '\u{2c61}', - SC_Lower), ('\u{2c62}', '\u{2c64}', SC_Upper), ('\u{2c65}', '\u{2c66}', SC_Lower), - ('\u{2c67}', '\u{2c67}', SC_Upper), ('\u{2c68}', '\u{2c68}', SC_Lower), ('\u{2c69}', - '\u{2c69}', SC_Upper), ('\u{2c6a}', '\u{2c6a}', SC_Lower), ('\u{2c6b}', '\u{2c6b}', - SC_Upper), ('\u{2c6c}', '\u{2c6c}', SC_Lower), ('\u{2c6d}', '\u{2c70}', SC_Upper), - ('\u{2c71}', '\u{2c71}', SC_Lower), ('\u{2c72}', '\u{2c72}', SC_Upper), ('\u{2c73}', - '\u{2c74}', SC_Lower), ('\u{2c75}', '\u{2c75}', SC_Upper), ('\u{2c76}', '\u{2c7d}', - SC_Lower), ('\u{2c7e}', '\u{2c80}', SC_Upper), ('\u{2c81}', '\u{2c81}', SC_Lower), - ('\u{2c82}', '\u{2c82}', SC_Upper), ('\u{2c83}', '\u{2c83}', SC_Lower), ('\u{2c84}', - '\u{2c84}', SC_Upper), ('\u{2c85}', '\u{2c85}', SC_Lower), ('\u{2c86}', '\u{2c86}', - SC_Upper), ('\u{2c87}', '\u{2c87}', SC_Lower), ('\u{2c88}', '\u{2c88}', SC_Upper), - ('\u{2c89}', '\u{2c89}', SC_Lower), ('\u{2c8a}', '\u{2c8a}', SC_Upper), ('\u{2c8b}', - '\u{2c8b}', SC_Lower), ('\u{2c8c}', '\u{2c8c}', SC_Upper), ('\u{2c8d}', '\u{2c8d}', - SC_Lower), ('\u{2c8e}', '\u{2c8e}', SC_Upper), ('\u{2c8f}', '\u{2c8f}', SC_Lower), - ('\u{2c90}', '\u{2c90}', SC_Upper), ('\u{2c91}', '\u{2c91}', SC_Lower), ('\u{2c92}', - '\u{2c92}', SC_Upper), ('\u{2c93}', '\u{2c93}', SC_Lower), ('\u{2c94}', '\u{2c94}', - SC_Upper), ('\u{2c95}', '\u{2c95}', SC_Lower), ('\u{2c96}', '\u{2c96}', SC_Upper), - ('\u{2c97}', '\u{2c97}', SC_Lower), ('\u{2c98}', '\u{2c98}', SC_Upper), ('\u{2c99}', - '\u{2c99}', SC_Lower), ('\u{2c9a}', '\u{2c9a}', SC_Upper), ('\u{2c9b}', '\u{2c9b}', - SC_Lower), ('\u{2c9c}', '\u{2c9c}', SC_Upper), ('\u{2c9d}', '\u{2c9d}', SC_Lower), - ('\u{2c9e}', '\u{2c9e}', SC_Upper), ('\u{2c9f}', '\u{2c9f}', SC_Lower), ('\u{2ca0}', - '\u{2ca0}', SC_Upper), ('\u{2ca1}', '\u{2ca1}', SC_Lower), ('\u{2ca2}', '\u{2ca2}', - SC_Upper), ('\u{2ca3}', '\u{2ca3}', SC_Lower), ('\u{2ca4}', '\u{2ca4}', SC_Upper), - ('\u{2ca5}', '\u{2ca5}', SC_Lower), ('\u{2ca6}', '\u{2ca6}', SC_Upper), ('\u{2ca7}', - '\u{2ca7}', SC_Lower), ('\u{2ca8}', '\u{2ca8}', SC_Upper), ('\u{2ca9}', '\u{2ca9}', - SC_Lower), ('\u{2caa}', '\u{2caa}', SC_Upper), ('\u{2cab}', '\u{2cab}', SC_Lower), - ('\u{2cac}', '\u{2cac}', SC_Upper), ('\u{2cad}', '\u{2cad}', SC_Lower), ('\u{2cae}', - '\u{2cae}', SC_Upper), ('\u{2caf}', '\u{2caf}', SC_Lower), ('\u{2cb0}', '\u{2cb0}', - SC_Upper), ('\u{2cb1}', '\u{2cb1}', SC_Lower), ('\u{2cb2}', '\u{2cb2}', SC_Upper), - ('\u{2cb3}', '\u{2cb3}', SC_Lower), ('\u{2cb4}', '\u{2cb4}', SC_Upper), ('\u{2cb5}', - '\u{2cb5}', SC_Lower), ('\u{2cb6}', '\u{2cb6}', SC_Upper), ('\u{2cb7}', '\u{2cb7}', - SC_Lower), ('\u{2cb8}', '\u{2cb8}', SC_Upper), ('\u{2cb9}', '\u{2cb9}', SC_Lower), - ('\u{2cba}', '\u{2cba}', SC_Upper), ('\u{2cbb}', '\u{2cbb}', SC_Lower), ('\u{2cbc}', - '\u{2cbc}', SC_Upper), ('\u{2cbd}', '\u{2cbd}', SC_Lower), ('\u{2cbe}', '\u{2cbe}', - SC_Upper), ('\u{2cbf}', '\u{2cbf}', SC_Lower), ('\u{2cc0}', '\u{2cc0}', SC_Upper), - ('\u{2cc1}', '\u{2cc1}', SC_Lower), ('\u{2cc2}', '\u{2cc2}', SC_Upper), ('\u{2cc3}', - '\u{2cc3}', SC_Lower), ('\u{2cc4}', '\u{2cc4}', SC_Upper), ('\u{2cc5}', '\u{2cc5}', - SC_Lower), ('\u{2cc6}', '\u{2cc6}', SC_Upper), ('\u{2cc7}', '\u{2cc7}', SC_Lower), - ('\u{2cc8}', '\u{2cc8}', SC_Upper), ('\u{2cc9}', '\u{2cc9}', SC_Lower), ('\u{2cca}', - '\u{2cca}', SC_Upper), ('\u{2ccb}', '\u{2ccb}', SC_Lower), ('\u{2ccc}', '\u{2ccc}', - SC_Upper), ('\u{2ccd}', '\u{2ccd}', SC_Lower), ('\u{2cce}', '\u{2cce}', SC_Upper), - ('\u{2ccf}', '\u{2ccf}', SC_Lower), ('\u{2cd0}', '\u{2cd0}', SC_Upper), ('\u{2cd1}', - '\u{2cd1}', SC_Lower), ('\u{2cd2}', '\u{2cd2}', SC_Upper), ('\u{2cd3}', '\u{2cd3}', - SC_Lower), ('\u{2cd4}', '\u{2cd4}', SC_Upper), ('\u{2cd5}', '\u{2cd5}', SC_Lower), - ('\u{2cd6}', '\u{2cd6}', SC_Upper), ('\u{2cd7}', '\u{2cd7}', SC_Lower), ('\u{2cd8}', - '\u{2cd8}', SC_Upper), ('\u{2cd9}', '\u{2cd9}', SC_Lower), ('\u{2cda}', '\u{2cda}', - SC_Upper), ('\u{2cdb}', '\u{2cdb}', SC_Lower), ('\u{2cdc}', '\u{2cdc}', SC_Upper), - ('\u{2cdd}', '\u{2cdd}', SC_Lower), ('\u{2cde}', '\u{2cde}', SC_Upper), ('\u{2cdf}', - '\u{2cdf}', SC_Lower), ('\u{2ce0}', '\u{2ce0}', SC_Upper), ('\u{2ce1}', '\u{2ce1}', - SC_Lower), ('\u{2ce2}', '\u{2ce2}', SC_Upper), ('\u{2ce3}', '\u{2ce4}', SC_Lower), - ('\u{2ceb}', '\u{2ceb}', SC_Upper), ('\u{2cec}', '\u{2cec}', SC_Lower), ('\u{2ced}', - '\u{2ced}', SC_Upper), ('\u{2cee}', '\u{2cee}', SC_Lower), ('\u{2cef}', '\u{2cf1}', - SC_Extend), ('\u{2cf2}', '\u{2cf2}', SC_Upper), ('\u{2cf3}', '\u{2cf3}', SC_Lower), - ('\u{2d00}', '\u{2d25}', SC_Lower), ('\u{2d27}', '\u{2d27}', SC_Lower), ('\u{2d2d}', - '\u{2d2d}', SC_Lower), ('\u{2d30}', '\u{2d67}', SC_OLetter), ('\u{2d6f}', '\u{2d6f}', - SC_OLetter), ('\u{2d7f}', '\u{2d7f}', SC_Extend), ('\u{2d80}', '\u{2d96}', SC_OLetter), - ('\u{2da0}', '\u{2da6}', SC_OLetter), ('\u{2da8}', '\u{2dae}', SC_OLetter), ('\u{2db0}', - '\u{2db6}', SC_OLetter), ('\u{2db8}', '\u{2dbe}', SC_OLetter), ('\u{2dc0}', '\u{2dc6}', - SC_OLetter), ('\u{2dc8}', '\u{2dce}', SC_OLetter), ('\u{2dd0}', '\u{2dd6}', SC_OLetter), - ('\u{2dd8}', '\u{2dde}', SC_OLetter), ('\u{2de0}', '\u{2dff}', SC_Extend), ('\u{2e00}', - '\u{2e0d}', SC_Close), ('\u{2e1c}', '\u{2e1d}', SC_Close), ('\u{2e20}', '\u{2e29}', - SC_Close), ('\u{2e2e}', '\u{2e2e}', SC_STerm), ('\u{2e2f}', '\u{2e2f}', SC_OLetter), - ('\u{2e3c}', '\u{2e3c}', SC_STerm), ('\u{2e42}', '\u{2e42}', SC_Close), ('\u{2e53}', - '\u{2e54}', SC_STerm), ('\u{2e55}', '\u{2e5c}', SC_Close), ('\u{3000}', '\u{3000}', SC_Sp), - ('\u{3001}', '\u{3001}', SC_SContinue), ('\u{3002}', '\u{3002}', SC_STerm), ('\u{3005}', - '\u{3007}', SC_OLetter), ('\u{3008}', '\u{3011}', SC_Close), ('\u{3014}', '\u{301b}', - SC_Close), ('\u{301d}', '\u{301f}', SC_Close), ('\u{3021}', '\u{3029}', SC_OLetter), - ('\u{302a}', '\u{302f}', SC_Extend), ('\u{3031}', '\u{3035}', SC_OLetter), ('\u{3038}', - '\u{303c}', SC_OLetter), ('\u{3041}', '\u{3096}', SC_OLetter), ('\u{3099}', '\u{309a}', - SC_Extend), ('\u{309d}', '\u{309f}', SC_OLetter), ('\u{30a1}', '\u{30fa}', SC_OLetter), - ('\u{30fc}', '\u{30ff}', SC_OLetter), ('\u{3105}', '\u{312f}', SC_OLetter), ('\u{3131}', - '\u{318e}', SC_OLetter), ('\u{31a0}', '\u{31bf}', SC_OLetter), ('\u{31f0}', '\u{31ff}', - SC_OLetter), ('\u{3400}', '\u{4dbf}', SC_OLetter), ('\u{4e00}', '\u{a48c}', SC_OLetter), - ('\u{a4d0}', '\u{a4fd}', SC_OLetter), ('\u{a4ff}', '\u{a4ff}', SC_STerm), ('\u{a500}', - '\u{a60c}', SC_OLetter), ('\u{a60e}', '\u{a60f}', SC_STerm), ('\u{a610}', '\u{a61f}', - SC_OLetter), ('\u{a620}', '\u{a629}', SC_Numeric), ('\u{a62a}', '\u{a62b}', SC_OLetter), - ('\u{a640}', '\u{a640}', SC_Upper), ('\u{a641}', '\u{a641}', SC_Lower), ('\u{a642}', - '\u{a642}', SC_Upper), ('\u{a643}', '\u{a643}', SC_Lower), ('\u{a644}', '\u{a644}', - SC_Upper), ('\u{a645}', '\u{a645}', SC_Lower), ('\u{a646}', '\u{a646}', SC_Upper), - ('\u{a647}', '\u{a647}', SC_Lower), ('\u{a648}', '\u{a648}', SC_Upper), ('\u{a649}', - '\u{a649}', SC_Lower), ('\u{a64a}', '\u{a64a}', SC_Upper), ('\u{a64b}', '\u{a64b}', - SC_Lower), ('\u{a64c}', '\u{a64c}', SC_Upper), ('\u{a64d}', '\u{a64d}', SC_Lower), - ('\u{a64e}', '\u{a64e}', SC_Upper), ('\u{a64f}', '\u{a64f}', SC_Lower), ('\u{a650}', - '\u{a650}', SC_Upper), ('\u{a651}', '\u{a651}', SC_Lower), ('\u{a652}', '\u{a652}', - SC_Upper), ('\u{a653}', '\u{a653}', SC_Lower), ('\u{a654}', '\u{a654}', SC_Upper), - ('\u{a655}', '\u{a655}', SC_Lower), ('\u{a656}', '\u{a656}', SC_Upper), ('\u{a657}', - '\u{a657}', SC_Lower), ('\u{a658}', '\u{a658}', SC_Upper), ('\u{a659}', '\u{a659}', - SC_Lower), ('\u{a65a}', '\u{a65a}', SC_Upper), ('\u{a65b}', '\u{a65b}', SC_Lower), - ('\u{a65c}', '\u{a65c}', SC_Upper), ('\u{a65d}', '\u{a65d}', SC_Lower), ('\u{a65e}', - '\u{a65e}', SC_Upper), ('\u{a65f}', '\u{a65f}', SC_Lower), ('\u{a660}', '\u{a660}', - SC_Upper), ('\u{a661}', '\u{a661}', SC_Lower), ('\u{a662}', '\u{a662}', SC_Upper), - ('\u{a663}', '\u{a663}', SC_Lower), ('\u{a664}', '\u{a664}', SC_Upper), ('\u{a665}', - '\u{a665}', SC_Lower), ('\u{a666}', '\u{a666}', SC_Upper), ('\u{a667}', '\u{a667}', - SC_Lower), ('\u{a668}', '\u{a668}', SC_Upper), ('\u{a669}', '\u{a669}', SC_Lower), - ('\u{a66a}', '\u{a66a}', SC_Upper), ('\u{a66b}', '\u{a66b}', SC_Lower), ('\u{a66c}', - '\u{a66c}', SC_Upper), ('\u{a66d}', '\u{a66d}', SC_Lower), ('\u{a66e}', '\u{a66e}', - SC_OLetter), ('\u{a66f}', '\u{a672}', SC_Extend), ('\u{a674}', '\u{a67d}', SC_Extend), - ('\u{a67f}', '\u{a67f}', SC_OLetter), ('\u{a680}', '\u{a680}', SC_Upper), ('\u{a681}', - '\u{a681}', SC_Lower), ('\u{a682}', '\u{a682}', SC_Upper), ('\u{a683}', '\u{a683}', - SC_Lower), ('\u{a684}', '\u{a684}', SC_Upper), ('\u{a685}', '\u{a685}', SC_Lower), - ('\u{a686}', '\u{a686}', SC_Upper), ('\u{a687}', '\u{a687}', SC_Lower), ('\u{a688}', - '\u{a688}', SC_Upper), ('\u{a689}', '\u{a689}', SC_Lower), ('\u{a68a}', '\u{a68a}', - SC_Upper), ('\u{a68b}', '\u{a68b}', SC_Lower), ('\u{a68c}', '\u{a68c}', SC_Upper), - ('\u{a68d}', '\u{a68d}', SC_Lower), ('\u{a68e}', '\u{a68e}', SC_Upper), ('\u{a68f}', - '\u{a68f}', SC_Lower), ('\u{a690}', '\u{a690}', SC_Upper), ('\u{a691}', '\u{a691}', - SC_Lower), ('\u{a692}', '\u{a692}', SC_Upper), ('\u{a693}', '\u{a693}', SC_Lower), - ('\u{a694}', '\u{a694}', SC_Upper), ('\u{a695}', '\u{a695}', SC_Lower), ('\u{a696}', - '\u{a696}', SC_Upper), ('\u{a697}', '\u{a697}', SC_Lower), ('\u{a698}', '\u{a698}', - SC_Upper), ('\u{a699}', '\u{a699}', SC_Lower), ('\u{a69a}', '\u{a69a}', SC_Upper), - ('\u{a69b}', '\u{a69d}', SC_Lower), ('\u{a69e}', '\u{a69f}', SC_Extend), ('\u{a6a0}', - '\u{a6ef}', SC_OLetter), ('\u{a6f0}', '\u{a6f1}', SC_Extend), ('\u{a6f3}', '\u{a6f3}', - SC_STerm), ('\u{a6f7}', '\u{a6f7}', SC_STerm), ('\u{a717}', '\u{a71f}', SC_OLetter), - ('\u{a722}', '\u{a722}', SC_Upper), ('\u{a723}', '\u{a723}', SC_Lower), ('\u{a724}', - '\u{a724}', SC_Upper), ('\u{a725}', '\u{a725}', SC_Lower), ('\u{a726}', '\u{a726}', - SC_Upper), ('\u{a727}', '\u{a727}', SC_Lower), ('\u{a728}', '\u{a728}', SC_Upper), - ('\u{a729}', '\u{a729}', SC_Lower), ('\u{a72a}', '\u{a72a}', SC_Upper), ('\u{a72b}', - '\u{a72b}', SC_Lower), ('\u{a72c}', '\u{a72c}', SC_Upper), ('\u{a72d}', '\u{a72d}', - SC_Lower), ('\u{a72e}', '\u{a72e}', SC_Upper), ('\u{a72f}', '\u{a731}', SC_Lower), - ('\u{a732}', '\u{a732}', SC_Upper), ('\u{a733}', '\u{a733}', SC_Lower), ('\u{a734}', - '\u{a734}', SC_Upper), ('\u{a735}', '\u{a735}', SC_Lower), ('\u{a736}', '\u{a736}', - SC_Upper), ('\u{a737}', '\u{a737}', SC_Lower), ('\u{a738}', '\u{a738}', SC_Upper), - ('\u{a739}', '\u{a739}', SC_Lower), ('\u{a73a}', '\u{a73a}', SC_Upper), ('\u{a73b}', - '\u{a73b}', SC_Lower), ('\u{a73c}', '\u{a73c}', SC_Upper), ('\u{a73d}', '\u{a73d}', - SC_Lower), ('\u{a73e}', '\u{a73e}', SC_Upper), ('\u{a73f}', '\u{a73f}', SC_Lower), - ('\u{a740}', '\u{a740}', SC_Upper), ('\u{a741}', '\u{a741}', SC_Lower), ('\u{a742}', - '\u{a742}', SC_Upper), ('\u{a743}', '\u{a743}', SC_Lower), ('\u{a744}', '\u{a744}', - SC_Upper), ('\u{a745}', '\u{a745}', SC_Lower), ('\u{a746}', '\u{a746}', SC_Upper), - ('\u{a747}', '\u{a747}', SC_Lower), ('\u{a748}', '\u{a748}', SC_Upper), ('\u{a749}', - '\u{a749}', SC_Lower), ('\u{a74a}', '\u{a74a}', SC_Upper), ('\u{a74b}', '\u{a74b}', - SC_Lower), ('\u{a74c}', '\u{a74c}', SC_Upper), ('\u{a74d}', '\u{a74d}', SC_Lower), - ('\u{a74e}', '\u{a74e}', SC_Upper), ('\u{a74f}', '\u{a74f}', SC_Lower), ('\u{a750}', - '\u{a750}', SC_Upper), ('\u{a751}', '\u{a751}', SC_Lower), ('\u{a752}', '\u{a752}', - SC_Upper), ('\u{a753}', '\u{a753}', SC_Lower), ('\u{a754}', '\u{a754}', SC_Upper), - ('\u{a755}', '\u{a755}', SC_Lower), ('\u{a756}', '\u{a756}', SC_Upper), ('\u{a757}', - '\u{a757}', SC_Lower), ('\u{a758}', '\u{a758}', SC_Upper), ('\u{a759}', '\u{a759}', - SC_Lower), ('\u{a75a}', '\u{a75a}', SC_Upper), ('\u{a75b}', '\u{a75b}', SC_Lower), - ('\u{a75c}', '\u{a75c}', SC_Upper), ('\u{a75d}', '\u{a75d}', SC_Lower), ('\u{a75e}', - '\u{a75e}', SC_Upper), ('\u{a75f}', '\u{a75f}', SC_Lower), ('\u{a760}', '\u{a760}', - SC_Upper), ('\u{a761}', '\u{a761}', SC_Lower), ('\u{a762}', '\u{a762}', SC_Upper), - ('\u{a763}', '\u{a763}', SC_Lower), ('\u{a764}', '\u{a764}', SC_Upper), ('\u{a765}', - '\u{a765}', SC_Lower), ('\u{a766}', '\u{a766}', SC_Upper), ('\u{a767}', '\u{a767}', - SC_Lower), ('\u{a768}', '\u{a768}', SC_Upper), ('\u{a769}', '\u{a769}', SC_Lower), - ('\u{a76a}', '\u{a76a}', SC_Upper), ('\u{a76b}', '\u{a76b}', SC_Lower), ('\u{a76c}', - '\u{a76c}', SC_Upper), ('\u{a76d}', '\u{a76d}', SC_Lower), ('\u{a76e}', '\u{a76e}', - SC_Upper), ('\u{a76f}', '\u{a778}', SC_Lower), ('\u{a779}', '\u{a779}', SC_Upper), - ('\u{a77a}', '\u{a77a}', SC_Lower), ('\u{a77b}', '\u{a77b}', SC_Upper), ('\u{a77c}', - '\u{a77c}', SC_Lower), ('\u{a77d}', '\u{a77e}', SC_Upper), ('\u{a77f}', '\u{a77f}', - SC_Lower), ('\u{a780}', '\u{a780}', SC_Upper), ('\u{a781}', '\u{a781}', SC_Lower), - ('\u{a782}', '\u{a782}', SC_Upper), ('\u{a783}', '\u{a783}', SC_Lower), ('\u{a784}', - '\u{a784}', SC_Upper), ('\u{a785}', '\u{a785}', SC_Lower), ('\u{a786}', '\u{a786}', - SC_Upper), ('\u{a787}', '\u{a787}', SC_Lower), ('\u{a788}', '\u{a788}', SC_OLetter), - ('\u{a78b}', '\u{a78b}', SC_Upper), ('\u{a78c}', '\u{a78c}', SC_Lower), ('\u{a78d}', - '\u{a78d}', SC_Upper), ('\u{a78e}', '\u{a78e}', SC_Lower), ('\u{a78f}', '\u{a78f}', - SC_OLetter), ('\u{a790}', '\u{a790}', SC_Upper), ('\u{a791}', '\u{a791}', SC_Lower), - ('\u{a792}', '\u{a792}', SC_Upper), ('\u{a793}', '\u{a795}', SC_Lower), ('\u{a796}', - '\u{a796}', SC_Upper), ('\u{a797}', '\u{a797}', SC_Lower), ('\u{a798}', '\u{a798}', - SC_Upper), ('\u{a799}', '\u{a799}', SC_Lower), ('\u{a79a}', '\u{a79a}', SC_Upper), - ('\u{a79b}', '\u{a79b}', SC_Lower), ('\u{a79c}', '\u{a79c}', SC_Upper), ('\u{a79d}', - '\u{a79d}', SC_Lower), ('\u{a79e}', '\u{a79e}', SC_Upper), ('\u{a79f}', '\u{a79f}', - SC_Lower), ('\u{a7a0}', '\u{a7a0}', SC_Upper), ('\u{a7a1}', '\u{a7a1}', SC_Lower), - ('\u{a7a2}', '\u{a7a2}', SC_Upper), ('\u{a7a3}', '\u{a7a3}', SC_Lower), ('\u{a7a4}', - '\u{a7a4}', SC_Upper), ('\u{a7a5}', '\u{a7a5}', SC_Lower), ('\u{a7a6}', '\u{a7a6}', - SC_Upper), ('\u{a7a7}', '\u{a7a7}', SC_Lower), ('\u{a7a8}', '\u{a7a8}', SC_Upper), - ('\u{a7a9}', '\u{a7a9}', SC_Lower), ('\u{a7aa}', '\u{a7ae}', SC_Upper), ('\u{a7af}', - '\u{a7af}', SC_Lower), ('\u{a7b0}', '\u{a7b4}', SC_Upper), ('\u{a7b5}', '\u{a7b5}', - SC_Lower), ('\u{a7b6}', '\u{a7b6}', SC_Upper), ('\u{a7b7}', '\u{a7b7}', SC_Lower), - ('\u{a7b8}', '\u{a7b8}', SC_Upper), ('\u{a7b9}', '\u{a7b9}', SC_Lower), ('\u{a7ba}', - '\u{a7ba}', SC_Upper), ('\u{a7bb}', '\u{a7bb}', SC_Lower), ('\u{a7bc}', '\u{a7bc}', - SC_Upper), ('\u{a7bd}', '\u{a7bd}', SC_Lower), ('\u{a7be}', '\u{a7be}', SC_Upper), - ('\u{a7bf}', '\u{a7bf}', SC_Lower), ('\u{a7c0}', '\u{a7c0}', SC_Upper), ('\u{a7c1}', - '\u{a7c1}', SC_Lower), ('\u{a7c2}', '\u{a7c2}', SC_Upper), ('\u{a7c3}', '\u{a7c3}', - SC_Lower), ('\u{a7c4}', '\u{a7c7}', SC_Upper), ('\u{a7c8}', '\u{a7c8}', SC_Lower), - ('\u{a7c9}', '\u{a7c9}', SC_Upper), ('\u{a7ca}', '\u{a7ca}', SC_Lower), ('\u{a7d0}', - '\u{a7d0}', SC_Upper), ('\u{a7d1}', '\u{a7d1}', SC_Lower), ('\u{a7d3}', '\u{a7d3}', - SC_Lower), ('\u{a7d5}', '\u{a7d5}', SC_Lower), ('\u{a7d6}', '\u{a7d6}', SC_Upper), - ('\u{a7d7}', '\u{a7d7}', SC_Lower), ('\u{a7d8}', '\u{a7d8}', SC_Upper), ('\u{a7d9}', - '\u{a7d9}', SC_Lower), ('\u{a7f2}', '\u{a7f4}', SC_OLetter), ('\u{a7f5}', '\u{a7f5}', - SC_Upper), ('\u{a7f6}', '\u{a7f6}', SC_Lower), ('\u{a7f7}', '\u{a7f7}', SC_OLetter), - ('\u{a7f8}', '\u{a7fa}', SC_Lower), ('\u{a7fb}', '\u{a801}', SC_OLetter), ('\u{a802}', - '\u{a802}', SC_Extend), ('\u{a803}', '\u{a805}', SC_OLetter), ('\u{a806}', '\u{a806}', - SC_Extend), ('\u{a807}', '\u{a80a}', SC_OLetter), ('\u{a80b}', '\u{a80b}', SC_Extend), - ('\u{a80c}', '\u{a822}', SC_OLetter), ('\u{a823}', '\u{a827}', SC_Extend), ('\u{a82c}', - '\u{a82c}', SC_Extend), ('\u{a840}', '\u{a873}', SC_OLetter), ('\u{a876}', '\u{a877}', - SC_STerm), ('\u{a880}', '\u{a881}', SC_Extend), ('\u{a882}', '\u{a8b3}', SC_OLetter), - ('\u{a8b4}', '\u{a8c5}', SC_Extend), ('\u{a8ce}', '\u{a8cf}', SC_STerm), ('\u{a8d0}', - '\u{a8d9}', SC_Numeric), ('\u{a8e0}', '\u{a8f1}', SC_Extend), ('\u{a8f2}', '\u{a8f7}', - SC_OLetter), ('\u{a8fb}', '\u{a8fb}', SC_OLetter), ('\u{a8fd}', '\u{a8fe}', SC_OLetter), - ('\u{a8ff}', '\u{a8ff}', SC_Extend), ('\u{a900}', '\u{a909}', SC_Numeric), ('\u{a90a}', - '\u{a925}', SC_OLetter), ('\u{a926}', '\u{a92d}', SC_Extend), ('\u{a92f}', '\u{a92f}', - SC_STerm), ('\u{a930}', '\u{a946}', SC_OLetter), ('\u{a947}', '\u{a953}', SC_Extend), - ('\u{a960}', '\u{a97c}', SC_OLetter), ('\u{a980}', '\u{a983}', SC_Extend), ('\u{a984}', - '\u{a9b2}', SC_OLetter), ('\u{a9b3}', '\u{a9c0}', SC_Extend), ('\u{a9c8}', '\u{a9c9}', - SC_STerm), ('\u{a9cf}', '\u{a9cf}', SC_OLetter), ('\u{a9d0}', '\u{a9d9}', SC_Numeric), - ('\u{a9e0}', '\u{a9e4}', SC_OLetter), ('\u{a9e5}', '\u{a9e5}', SC_Extend), ('\u{a9e6}', - '\u{a9ef}', SC_OLetter), ('\u{a9f0}', '\u{a9f9}', SC_Numeric), ('\u{a9fa}', '\u{a9fe}', - SC_OLetter), ('\u{aa00}', '\u{aa28}', SC_OLetter), ('\u{aa29}', '\u{aa36}', SC_Extend), - ('\u{aa40}', '\u{aa42}', SC_OLetter), ('\u{aa43}', '\u{aa43}', SC_Extend), ('\u{aa44}', - '\u{aa4b}', SC_OLetter), ('\u{aa4c}', '\u{aa4d}', SC_Extend), ('\u{aa50}', '\u{aa59}', - SC_Numeric), ('\u{aa5d}', '\u{aa5f}', SC_STerm), ('\u{aa60}', '\u{aa76}', SC_OLetter), - ('\u{aa7a}', '\u{aa7a}', SC_OLetter), ('\u{aa7b}', '\u{aa7d}', SC_Extend), ('\u{aa7e}', - '\u{aaaf}', SC_OLetter), ('\u{aab0}', '\u{aab0}', SC_Extend), ('\u{aab1}', '\u{aab1}', - SC_OLetter), ('\u{aab2}', '\u{aab4}', SC_Extend), ('\u{aab5}', '\u{aab6}', SC_OLetter), - ('\u{aab7}', '\u{aab8}', SC_Extend), ('\u{aab9}', '\u{aabd}', SC_OLetter), ('\u{aabe}', - '\u{aabf}', SC_Extend), ('\u{aac0}', '\u{aac0}', SC_OLetter), ('\u{aac1}', '\u{aac1}', - SC_Extend), ('\u{aac2}', '\u{aac2}', SC_OLetter), ('\u{aadb}', '\u{aadd}', SC_OLetter), - ('\u{aae0}', '\u{aaea}', SC_OLetter), ('\u{aaeb}', '\u{aaef}', SC_Extend), ('\u{aaf0}', - '\u{aaf1}', SC_STerm), ('\u{aaf2}', '\u{aaf4}', SC_OLetter), ('\u{aaf5}', '\u{aaf6}', - SC_Extend), ('\u{ab01}', '\u{ab06}', SC_OLetter), ('\u{ab09}', '\u{ab0e}', SC_OLetter), - ('\u{ab11}', '\u{ab16}', SC_OLetter), ('\u{ab20}', '\u{ab26}', SC_OLetter), ('\u{ab28}', - '\u{ab2e}', SC_OLetter), ('\u{ab30}', '\u{ab5a}', SC_Lower), ('\u{ab5c}', '\u{ab68}', - SC_Lower), ('\u{ab69}', '\u{ab69}', SC_OLetter), ('\u{ab70}', '\u{abbf}', SC_Lower), - ('\u{abc0}', '\u{abe2}', SC_OLetter), ('\u{abe3}', '\u{abea}', SC_Extend), ('\u{abeb}', - '\u{abeb}', SC_STerm), ('\u{abec}', '\u{abed}', SC_Extend), ('\u{abf0}', '\u{abf9}', - SC_Numeric), ('\u{ac00}', '\u{d7a3}', SC_OLetter), ('\u{d7b0}', '\u{d7c6}', SC_OLetter), - ('\u{d7cb}', '\u{d7fb}', SC_OLetter), ('\u{f900}', '\u{fa6d}', SC_OLetter), ('\u{fa70}', - '\u{fad9}', SC_OLetter), ('\u{fb00}', '\u{fb06}', SC_Lower), ('\u{fb13}', '\u{fb17}', - SC_Lower), ('\u{fb1d}', '\u{fb1d}', SC_OLetter), ('\u{fb1e}', '\u{fb1e}', SC_Extend), - ('\u{fb1f}', '\u{fb28}', SC_OLetter), ('\u{fb2a}', '\u{fb36}', SC_OLetter), ('\u{fb38}', - '\u{fb3c}', SC_OLetter), ('\u{fb3e}', '\u{fb3e}', SC_OLetter), ('\u{fb40}', '\u{fb41}', - SC_OLetter), ('\u{fb43}', '\u{fb44}', SC_OLetter), ('\u{fb46}', '\u{fbb1}', SC_OLetter), - ('\u{fbd3}', '\u{fd3d}', SC_OLetter), ('\u{fd3e}', '\u{fd3f}', SC_Close), ('\u{fd50}', - '\u{fd8f}', SC_OLetter), ('\u{fd92}', '\u{fdc7}', SC_OLetter), ('\u{fdf0}', '\u{fdfb}', - SC_OLetter), ('\u{fe00}', '\u{fe0f}', SC_Extend), ('\u{fe10}', '\u{fe11}', SC_SContinue), - ('\u{fe13}', '\u{fe13}', SC_SContinue), ('\u{fe17}', '\u{fe18}', SC_Close), ('\u{fe20}', - '\u{fe2f}', SC_Extend), ('\u{fe31}', '\u{fe32}', SC_SContinue), ('\u{fe35}', '\u{fe44}', - SC_Close), ('\u{fe47}', '\u{fe48}', SC_Close), ('\u{fe50}', '\u{fe51}', SC_SContinue), - ('\u{fe52}', '\u{fe52}', SC_ATerm), ('\u{fe55}', '\u{fe55}', SC_SContinue), ('\u{fe56}', - '\u{fe57}', SC_STerm), ('\u{fe58}', '\u{fe58}', SC_SContinue), ('\u{fe59}', '\u{fe5e}', - SC_Close), ('\u{fe63}', '\u{fe63}', SC_SContinue), ('\u{fe70}', '\u{fe74}', SC_OLetter), - ('\u{fe76}', '\u{fefc}', SC_OLetter), ('\u{feff}', '\u{feff}', SC_Format), ('\u{ff01}', - '\u{ff01}', SC_STerm), ('\u{ff08}', '\u{ff09}', SC_Close), ('\u{ff0c}', '\u{ff0d}', - SC_SContinue), ('\u{ff0e}', '\u{ff0e}', SC_ATerm), ('\u{ff10}', '\u{ff19}', SC_Numeric), - ('\u{ff1a}', '\u{ff1a}', SC_SContinue), ('\u{ff1f}', '\u{ff1f}', SC_STerm), ('\u{ff21}', - '\u{ff3a}', SC_Upper), ('\u{ff3b}', '\u{ff3b}', SC_Close), ('\u{ff3d}', '\u{ff3d}', - SC_Close), ('\u{ff41}', '\u{ff5a}', SC_Lower), ('\u{ff5b}', '\u{ff5b}', SC_Close), - ('\u{ff5d}', '\u{ff5d}', SC_Close), ('\u{ff5f}', '\u{ff60}', SC_Close), ('\u{ff61}', - '\u{ff61}', SC_STerm), ('\u{ff62}', '\u{ff63}', SC_Close), ('\u{ff64}', '\u{ff64}', - SC_SContinue), ('\u{ff66}', '\u{ff9d}', SC_OLetter), ('\u{ff9e}', '\u{ff9f}', SC_Extend), - ('\u{ffa0}', '\u{ffbe}', SC_OLetter), ('\u{ffc2}', '\u{ffc7}', SC_OLetter), ('\u{ffca}', - '\u{ffcf}', SC_OLetter), ('\u{ffd2}', '\u{ffd7}', SC_OLetter), ('\u{ffda}', '\u{ffdc}', - SC_OLetter), ('\u{fff9}', '\u{fffb}', SC_Format), ('\u{10000}', '\u{1000b}', SC_OLetter), - ('\u{1000d}', '\u{10026}', SC_OLetter), ('\u{10028}', '\u{1003a}', SC_OLetter), - ('\u{1003c}', '\u{1003d}', SC_OLetter), ('\u{1003f}', '\u{1004d}', SC_OLetter), - ('\u{10050}', '\u{1005d}', SC_OLetter), ('\u{10080}', '\u{100fa}', SC_OLetter), - ('\u{10140}', '\u{10174}', SC_OLetter), ('\u{101fd}', '\u{101fd}', SC_Extend), ('\u{10280}', - '\u{1029c}', SC_OLetter), ('\u{102a0}', '\u{102d0}', SC_OLetter), ('\u{102e0}', '\u{102e0}', - SC_Extend), ('\u{10300}', '\u{1031f}', SC_OLetter), ('\u{1032d}', '\u{1034a}', SC_OLetter), - ('\u{10350}', '\u{10375}', SC_OLetter), ('\u{10376}', '\u{1037a}', SC_Extend), ('\u{10380}', - '\u{1039d}', SC_OLetter), ('\u{103a0}', '\u{103c3}', SC_OLetter), ('\u{103c8}', '\u{103cf}', - SC_OLetter), ('\u{103d1}', '\u{103d5}', SC_OLetter), ('\u{10400}', '\u{10427}', SC_Upper), - ('\u{10428}', '\u{1044f}', SC_Lower), ('\u{10450}', '\u{1049d}', SC_OLetter), ('\u{104a0}', - '\u{104a9}', SC_Numeric), ('\u{104b0}', '\u{104d3}', SC_Upper), ('\u{104d8}', '\u{104fb}', - SC_Lower), ('\u{10500}', '\u{10527}', SC_OLetter), ('\u{10530}', '\u{10563}', SC_OLetter), - ('\u{10570}', '\u{1057a}', SC_Upper), ('\u{1057c}', '\u{1058a}', SC_Upper), ('\u{1058c}', - '\u{10592}', SC_Upper), ('\u{10594}', '\u{10595}', SC_Upper), ('\u{10597}', '\u{105a1}', - SC_Lower), ('\u{105a3}', '\u{105b1}', SC_Lower), ('\u{105b3}', '\u{105b9}', SC_Lower), - ('\u{105bb}', '\u{105bc}', SC_Lower), ('\u{10600}', '\u{10736}', SC_OLetter), ('\u{10740}', - '\u{10755}', SC_OLetter), ('\u{10760}', '\u{10767}', SC_OLetter), ('\u{10780}', '\u{10780}', - SC_Lower), ('\u{10781}', '\u{10782}', SC_OLetter), ('\u{10783}', '\u{10785}', SC_Lower), - ('\u{10787}', '\u{107b0}', SC_Lower), ('\u{107b2}', '\u{107ba}', SC_Lower), ('\u{10800}', - '\u{10805}', SC_OLetter), ('\u{10808}', '\u{10808}', SC_OLetter), ('\u{1080a}', '\u{10835}', - SC_OLetter), ('\u{10837}', '\u{10838}', SC_OLetter), ('\u{1083c}', '\u{1083c}', SC_OLetter), + '\u{cf2}', SC_OLetter), ('\u{cf3}', '\u{cf3}', SC_Extend), ('\u{d00}', '\u{d03}', + SC_Extend), ('\u{d04}', '\u{d0c}', SC_OLetter), ('\u{d0e}', '\u{d10}', SC_OLetter), + ('\u{d12}', '\u{d3a}', SC_OLetter), ('\u{d3b}', '\u{d3c}', SC_Extend), ('\u{d3d}', + '\u{d3d}', SC_OLetter), ('\u{d3e}', '\u{d44}', SC_Extend), ('\u{d46}', '\u{d48}', + SC_Extend), ('\u{d4a}', '\u{d4d}', SC_Extend), ('\u{d4e}', '\u{d4e}', SC_OLetter), + ('\u{d54}', '\u{d56}', SC_OLetter), ('\u{d57}', '\u{d57}', SC_Extend), ('\u{d5f}', + '\u{d61}', SC_OLetter), ('\u{d62}', '\u{d63}', SC_Extend), ('\u{d66}', '\u{d6f}', + SC_Numeric), ('\u{d7a}', '\u{d7f}', SC_OLetter), ('\u{d81}', '\u{d83}', SC_Extend), + ('\u{d85}', '\u{d96}', SC_OLetter), ('\u{d9a}', '\u{db1}', SC_OLetter), ('\u{db3}', + '\u{dbb}', SC_OLetter), ('\u{dbd}', '\u{dbd}', SC_OLetter), ('\u{dc0}', '\u{dc6}', + SC_OLetter), ('\u{dca}', '\u{dca}', SC_Extend), ('\u{dcf}', '\u{dd4}', SC_Extend), + ('\u{dd6}', '\u{dd6}', SC_Extend), ('\u{dd8}', '\u{ddf}', SC_Extend), ('\u{de6}', '\u{def}', + SC_Numeric), ('\u{df2}', '\u{df3}', SC_Extend), ('\u{e01}', '\u{e30}', SC_OLetter), + ('\u{e31}', '\u{e31}', SC_Extend), ('\u{e32}', '\u{e33}', SC_OLetter), ('\u{e34}', + '\u{e3a}', SC_Extend), ('\u{e40}', '\u{e46}', SC_OLetter), ('\u{e47}', '\u{e4e}', + SC_Extend), ('\u{e50}', '\u{e59}', SC_Numeric), ('\u{e81}', '\u{e82}', SC_OLetter), + ('\u{e84}', '\u{e84}', SC_OLetter), ('\u{e86}', '\u{e8a}', SC_OLetter), ('\u{e8c}', + '\u{ea3}', SC_OLetter), ('\u{ea5}', '\u{ea5}', SC_OLetter), ('\u{ea7}', '\u{eb0}', + SC_OLetter), ('\u{eb1}', '\u{eb1}', SC_Extend), ('\u{eb2}', '\u{eb3}', SC_OLetter), + ('\u{eb4}', '\u{ebc}', SC_Extend), ('\u{ebd}', '\u{ebd}', SC_OLetter), ('\u{ec0}', + '\u{ec4}', SC_OLetter), ('\u{ec6}', '\u{ec6}', SC_OLetter), ('\u{ec8}', '\u{ece}', + SC_Extend), ('\u{ed0}', '\u{ed9}', SC_Numeric), ('\u{edc}', '\u{edf}', SC_OLetter), + ('\u{f00}', '\u{f00}', SC_OLetter), ('\u{f18}', '\u{f19}', SC_Extend), ('\u{f20}', + '\u{f29}', SC_Numeric), ('\u{f35}', '\u{f35}', SC_Extend), ('\u{f37}', '\u{f37}', + SC_Extend), ('\u{f39}', '\u{f39}', SC_Extend), ('\u{f3a}', '\u{f3d}', SC_Close), ('\u{f3e}', + '\u{f3f}', SC_Extend), ('\u{f40}', '\u{f47}', SC_OLetter), ('\u{f49}', '\u{f6c}', + SC_OLetter), ('\u{f71}', '\u{f84}', SC_Extend), ('\u{f86}', '\u{f87}', SC_Extend), + ('\u{f88}', '\u{f8c}', SC_OLetter), ('\u{f8d}', '\u{f97}', SC_Extend), ('\u{f99}', + '\u{fbc}', SC_Extend), ('\u{fc6}', '\u{fc6}', SC_Extend), ('\u{1000}', '\u{102a}', + SC_OLetter), ('\u{102b}', '\u{103e}', SC_Extend), ('\u{103f}', '\u{103f}', SC_OLetter), + ('\u{1040}', '\u{1049}', SC_Numeric), ('\u{104a}', '\u{104b}', SC_STerm), ('\u{1050}', + '\u{1055}', SC_OLetter), ('\u{1056}', '\u{1059}', SC_Extend), ('\u{105a}', '\u{105d}', + SC_OLetter), ('\u{105e}', '\u{1060}', SC_Extend), ('\u{1061}', '\u{1061}', SC_OLetter), + ('\u{1062}', '\u{1064}', SC_Extend), ('\u{1065}', '\u{1066}', SC_OLetter), ('\u{1067}', + '\u{106d}', SC_Extend), ('\u{106e}', '\u{1070}', SC_OLetter), ('\u{1071}', '\u{1074}', + SC_Extend), ('\u{1075}', '\u{1081}', SC_OLetter), ('\u{1082}', '\u{108d}', SC_Extend), + ('\u{108e}', '\u{108e}', SC_OLetter), ('\u{108f}', '\u{108f}', SC_Extend), ('\u{1090}', + '\u{1099}', SC_Numeric), ('\u{109a}', '\u{109d}', SC_Extend), ('\u{10a0}', '\u{10c5}', + SC_Upper), ('\u{10c7}', '\u{10c7}', SC_Upper), ('\u{10cd}', '\u{10cd}', SC_Upper), + ('\u{10d0}', '\u{10fa}', SC_OLetter), ('\u{10fc}', '\u{10fc}', SC_Lower), ('\u{10fd}', + '\u{1248}', SC_OLetter), ('\u{124a}', '\u{124d}', SC_OLetter), ('\u{1250}', '\u{1256}', + SC_OLetter), ('\u{1258}', '\u{1258}', SC_OLetter), ('\u{125a}', '\u{125d}', SC_OLetter), + ('\u{1260}', '\u{1288}', SC_OLetter), ('\u{128a}', '\u{128d}', SC_OLetter), ('\u{1290}', + '\u{12b0}', SC_OLetter), ('\u{12b2}', '\u{12b5}', SC_OLetter), ('\u{12b8}', '\u{12be}', + SC_OLetter), ('\u{12c0}', '\u{12c0}', SC_OLetter), ('\u{12c2}', '\u{12c5}', SC_OLetter), + ('\u{12c8}', '\u{12d6}', SC_OLetter), ('\u{12d8}', '\u{1310}', SC_OLetter), ('\u{1312}', + '\u{1315}', SC_OLetter), ('\u{1318}', '\u{135a}', SC_OLetter), ('\u{135d}', '\u{135f}', + SC_Extend), ('\u{1362}', '\u{1362}', SC_STerm), ('\u{1367}', '\u{1368}', SC_STerm), + ('\u{1380}', '\u{138f}', SC_OLetter), ('\u{13a0}', '\u{13f5}', SC_Upper), ('\u{13f8}', + '\u{13fd}', SC_Lower), ('\u{1401}', '\u{166c}', SC_OLetter), ('\u{166e}', '\u{166e}', + SC_STerm), ('\u{166f}', '\u{167f}', SC_OLetter), ('\u{1680}', '\u{1680}', SC_Sp), + ('\u{1681}', '\u{169a}', SC_OLetter), ('\u{169b}', '\u{169c}', SC_Close), ('\u{16a0}', + '\u{16ea}', SC_OLetter), ('\u{16ee}', '\u{16f8}', SC_OLetter), ('\u{1700}', '\u{1711}', + SC_OLetter), ('\u{1712}', '\u{1715}', SC_Extend), ('\u{171f}', '\u{1731}', SC_OLetter), + ('\u{1732}', '\u{1734}', SC_Extend), ('\u{1735}', '\u{1736}', SC_STerm), ('\u{1740}', + '\u{1751}', SC_OLetter), ('\u{1752}', '\u{1753}', SC_Extend), ('\u{1760}', '\u{176c}', + SC_OLetter), ('\u{176e}', '\u{1770}', SC_OLetter), ('\u{1772}', '\u{1773}', SC_Extend), + ('\u{1780}', '\u{17b3}', SC_OLetter), ('\u{17b4}', '\u{17d3}', SC_Extend), ('\u{17d7}', + '\u{17d7}', SC_OLetter), ('\u{17dc}', '\u{17dc}', SC_OLetter), ('\u{17dd}', '\u{17dd}', + SC_Extend), ('\u{17e0}', '\u{17e9}', SC_Numeric), ('\u{1802}', '\u{1802}', SC_SContinue), + ('\u{1803}', '\u{1803}', SC_STerm), ('\u{1808}', '\u{1808}', SC_SContinue), ('\u{1809}', + '\u{1809}', SC_STerm), ('\u{180b}', '\u{180d}', SC_Extend), ('\u{180e}', '\u{180e}', + SC_Format), ('\u{180f}', '\u{180f}', SC_Extend), ('\u{1810}', '\u{1819}', SC_Numeric), + ('\u{1820}', '\u{1878}', SC_OLetter), ('\u{1880}', '\u{1884}', SC_OLetter), ('\u{1885}', + '\u{1886}', SC_Extend), ('\u{1887}', '\u{18a8}', SC_OLetter), ('\u{18a9}', '\u{18a9}', + SC_Extend), ('\u{18aa}', '\u{18aa}', SC_OLetter), ('\u{18b0}', '\u{18f5}', SC_OLetter), + ('\u{1900}', '\u{191e}', SC_OLetter), ('\u{1920}', '\u{192b}', SC_Extend), ('\u{1930}', + '\u{193b}', SC_Extend), ('\u{1944}', '\u{1945}', SC_STerm), ('\u{1946}', '\u{194f}', + SC_Numeric), ('\u{1950}', '\u{196d}', SC_OLetter), ('\u{1970}', '\u{1974}', SC_OLetter), + ('\u{1980}', '\u{19ab}', SC_OLetter), ('\u{19b0}', '\u{19c9}', SC_OLetter), ('\u{19d0}', + '\u{19d9}', SC_Numeric), ('\u{1a00}', '\u{1a16}', SC_OLetter), ('\u{1a17}', '\u{1a1b}', + SC_Extend), ('\u{1a20}', '\u{1a54}', SC_OLetter), ('\u{1a55}', '\u{1a5e}', SC_Extend), + ('\u{1a60}', '\u{1a7c}', SC_Extend), ('\u{1a7f}', '\u{1a7f}', SC_Extend), ('\u{1a80}', + '\u{1a89}', SC_Numeric), ('\u{1a90}', '\u{1a99}', SC_Numeric), ('\u{1aa7}', '\u{1aa7}', + SC_OLetter), ('\u{1aa8}', '\u{1aab}', SC_STerm), ('\u{1ab0}', '\u{1ace}', SC_Extend), + ('\u{1b00}', '\u{1b04}', SC_Extend), ('\u{1b05}', '\u{1b33}', SC_OLetter), ('\u{1b34}', + '\u{1b44}', SC_Extend), ('\u{1b45}', '\u{1b4c}', SC_OLetter), ('\u{1b50}', '\u{1b59}', + SC_Numeric), ('\u{1b5a}', '\u{1b5b}', SC_STerm), ('\u{1b5e}', '\u{1b5f}', SC_STerm), + ('\u{1b6b}', '\u{1b73}', SC_Extend), ('\u{1b7d}', '\u{1b7e}', SC_STerm), ('\u{1b80}', + '\u{1b82}', SC_Extend), ('\u{1b83}', '\u{1ba0}', SC_OLetter), ('\u{1ba1}', '\u{1bad}', + SC_Extend), ('\u{1bae}', '\u{1baf}', SC_OLetter), ('\u{1bb0}', '\u{1bb9}', SC_Numeric), + ('\u{1bba}', '\u{1be5}', SC_OLetter), ('\u{1be6}', '\u{1bf3}', SC_Extend), ('\u{1c00}', + '\u{1c23}', SC_OLetter), ('\u{1c24}', '\u{1c37}', SC_Extend), ('\u{1c3b}', '\u{1c3c}', + SC_STerm), ('\u{1c40}', '\u{1c49}', SC_Numeric), ('\u{1c4d}', '\u{1c4f}', SC_OLetter), + ('\u{1c50}', '\u{1c59}', SC_Numeric), ('\u{1c5a}', '\u{1c7d}', SC_OLetter), ('\u{1c7e}', + '\u{1c7f}', SC_STerm), ('\u{1c80}', '\u{1c88}', SC_Lower), ('\u{1c90}', '\u{1cba}', + SC_OLetter), ('\u{1cbd}', '\u{1cbf}', SC_OLetter), ('\u{1cd0}', '\u{1cd2}', SC_Extend), + ('\u{1cd4}', '\u{1ce8}', SC_Extend), ('\u{1ce9}', '\u{1cec}', SC_OLetter), ('\u{1ced}', + '\u{1ced}', SC_Extend), ('\u{1cee}', '\u{1cf3}', SC_OLetter), ('\u{1cf4}', '\u{1cf4}', + SC_Extend), ('\u{1cf5}', '\u{1cf6}', SC_OLetter), ('\u{1cf7}', '\u{1cf9}', SC_Extend), + ('\u{1cfa}', '\u{1cfa}', SC_OLetter), ('\u{1d00}', '\u{1dbf}', SC_Lower), ('\u{1dc0}', + '\u{1dff}', SC_Extend), ('\u{1e00}', '\u{1e00}', SC_Upper), ('\u{1e01}', '\u{1e01}', + SC_Lower), ('\u{1e02}', '\u{1e02}', SC_Upper), ('\u{1e03}', '\u{1e03}', SC_Lower), + ('\u{1e04}', '\u{1e04}', SC_Upper), ('\u{1e05}', '\u{1e05}', SC_Lower), ('\u{1e06}', + '\u{1e06}', SC_Upper), ('\u{1e07}', '\u{1e07}', SC_Lower), ('\u{1e08}', '\u{1e08}', + SC_Upper), ('\u{1e09}', '\u{1e09}', SC_Lower), ('\u{1e0a}', '\u{1e0a}', SC_Upper), + ('\u{1e0b}', '\u{1e0b}', SC_Lower), ('\u{1e0c}', '\u{1e0c}', SC_Upper), ('\u{1e0d}', + '\u{1e0d}', SC_Lower), ('\u{1e0e}', '\u{1e0e}', SC_Upper), ('\u{1e0f}', '\u{1e0f}', + SC_Lower), ('\u{1e10}', '\u{1e10}', SC_Upper), ('\u{1e11}', '\u{1e11}', SC_Lower), + ('\u{1e12}', '\u{1e12}', SC_Upper), ('\u{1e13}', '\u{1e13}', SC_Lower), ('\u{1e14}', + '\u{1e14}', SC_Upper), ('\u{1e15}', '\u{1e15}', SC_Lower), ('\u{1e16}', '\u{1e16}', + SC_Upper), ('\u{1e17}', '\u{1e17}', SC_Lower), ('\u{1e18}', '\u{1e18}', SC_Upper), + ('\u{1e19}', '\u{1e19}', SC_Lower), ('\u{1e1a}', '\u{1e1a}', SC_Upper), ('\u{1e1b}', + '\u{1e1b}', SC_Lower), ('\u{1e1c}', '\u{1e1c}', SC_Upper), ('\u{1e1d}', '\u{1e1d}', + SC_Lower), ('\u{1e1e}', '\u{1e1e}', SC_Upper), ('\u{1e1f}', '\u{1e1f}', SC_Lower), + ('\u{1e20}', '\u{1e20}', SC_Upper), ('\u{1e21}', '\u{1e21}', SC_Lower), ('\u{1e22}', + '\u{1e22}', SC_Upper), ('\u{1e23}', '\u{1e23}', SC_Lower), ('\u{1e24}', '\u{1e24}', + SC_Upper), ('\u{1e25}', '\u{1e25}', SC_Lower), ('\u{1e26}', '\u{1e26}', SC_Upper), + ('\u{1e27}', '\u{1e27}', SC_Lower), ('\u{1e28}', '\u{1e28}', SC_Upper), ('\u{1e29}', + '\u{1e29}', SC_Lower), ('\u{1e2a}', '\u{1e2a}', SC_Upper), ('\u{1e2b}', '\u{1e2b}', + SC_Lower), ('\u{1e2c}', '\u{1e2c}', SC_Upper), ('\u{1e2d}', '\u{1e2d}', SC_Lower), + ('\u{1e2e}', '\u{1e2e}', SC_Upper), ('\u{1e2f}', '\u{1e2f}', SC_Lower), ('\u{1e30}', + '\u{1e30}', SC_Upper), ('\u{1e31}', '\u{1e31}', SC_Lower), ('\u{1e32}', '\u{1e32}', + SC_Upper), ('\u{1e33}', '\u{1e33}', SC_Lower), ('\u{1e34}', '\u{1e34}', SC_Upper), + ('\u{1e35}', '\u{1e35}', SC_Lower), ('\u{1e36}', '\u{1e36}', SC_Upper), ('\u{1e37}', + '\u{1e37}', SC_Lower), ('\u{1e38}', '\u{1e38}', SC_Upper), ('\u{1e39}', '\u{1e39}', + SC_Lower), ('\u{1e3a}', '\u{1e3a}', SC_Upper), ('\u{1e3b}', '\u{1e3b}', SC_Lower), + ('\u{1e3c}', '\u{1e3c}', SC_Upper), ('\u{1e3d}', '\u{1e3d}', SC_Lower), ('\u{1e3e}', + '\u{1e3e}', SC_Upper), ('\u{1e3f}', '\u{1e3f}', SC_Lower), ('\u{1e40}', '\u{1e40}', + SC_Upper), ('\u{1e41}', '\u{1e41}', SC_Lower), ('\u{1e42}', '\u{1e42}', SC_Upper), + ('\u{1e43}', '\u{1e43}', SC_Lower), ('\u{1e44}', '\u{1e44}', SC_Upper), ('\u{1e45}', + '\u{1e45}', SC_Lower), ('\u{1e46}', '\u{1e46}', SC_Upper), ('\u{1e47}', '\u{1e47}', + SC_Lower), ('\u{1e48}', '\u{1e48}', SC_Upper), ('\u{1e49}', '\u{1e49}', SC_Lower), + ('\u{1e4a}', '\u{1e4a}', SC_Upper), ('\u{1e4b}', '\u{1e4b}', SC_Lower), ('\u{1e4c}', + '\u{1e4c}', SC_Upper), ('\u{1e4d}', '\u{1e4d}', SC_Lower), ('\u{1e4e}', '\u{1e4e}', + SC_Upper), ('\u{1e4f}', '\u{1e4f}', SC_Lower), ('\u{1e50}', '\u{1e50}', SC_Upper), + ('\u{1e51}', '\u{1e51}', SC_Lower), ('\u{1e52}', '\u{1e52}', SC_Upper), ('\u{1e53}', + '\u{1e53}', SC_Lower), ('\u{1e54}', '\u{1e54}', SC_Upper), ('\u{1e55}', '\u{1e55}', + SC_Lower), ('\u{1e56}', '\u{1e56}', SC_Upper), ('\u{1e57}', '\u{1e57}', SC_Lower), + ('\u{1e58}', '\u{1e58}', SC_Upper), ('\u{1e59}', '\u{1e59}', SC_Lower), ('\u{1e5a}', + '\u{1e5a}', SC_Upper), ('\u{1e5b}', '\u{1e5b}', SC_Lower), ('\u{1e5c}', '\u{1e5c}', + SC_Upper), ('\u{1e5d}', '\u{1e5d}', SC_Lower), ('\u{1e5e}', '\u{1e5e}', SC_Upper), + ('\u{1e5f}', '\u{1e5f}', SC_Lower), ('\u{1e60}', '\u{1e60}', SC_Upper), ('\u{1e61}', + '\u{1e61}', SC_Lower), ('\u{1e62}', '\u{1e62}', SC_Upper), ('\u{1e63}', '\u{1e63}', + SC_Lower), ('\u{1e64}', '\u{1e64}', SC_Upper), ('\u{1e65}', '\u{1e65}', SC_Lower), + ('\u{1e66}', '\u{1e66}', SC_Upper), ('\u{1e67}', '\u{1e67}', SC_Lower), ('\u{1e68}', + '\u{1e68}', SC_Upper), ('\u{1e69}', '\u{1e69}', SC_Lower), ('\u{1e6a}', '\u{1e6a}', + SC_Upper), ('\u{1e6b}', '\u{1e6b}', SC_Lower), ('\u{1e6c}', '\u{1e6c}', SC_Upper), + ('\u{1e6d}', '\u{1e6d}', SC_Lower), ('\u{1e6e}', '\u{1e6e}', SC_Upper), ('\u{1e6f}', + '\u{1e6f}', SC_Lower), ('\u{1e70}', '\u{1e70}', SC_Upper), ('\u{1e71}', '\u{1e71}', + SC_Lower), ('\u{1e72}', '\u{1e72}', SC_Upper), ('\u{1e73}', '\u{1e73}', SC_Lower), + ('\u{1e74}', '\u{1e74}', SC_Upper), ('\u{1e75}', '\u{1e75}', SC_Lower), ('\u{1e76}', + '\u{1e76}', SC_Upper), ('\u{1e77}', '\u{1e77}', SC_Lower), ('\u{1e78}', '\u{1e78}', + SC_Upper), ('\u{1e79}', '\u{1e79}', SC_Lower), ('\u{1e7a}', '\u{1e7a}', SC_Upper), + ('\u{1e7b}', '\u{1e7b}', SC_Lower), ('\u{1e7c}', '\u{1e7c}', SC_Upper), ('\u{1e7d}', + '\u{1e7d}', SC_Lower), ('\u{1e7e}', '\u{1e7e}', SC_Upper), ('\u{1e7f}', '\u{1e7f}', + SC_Lower), ('\u{1e80}', '\u{1e80}', SC_Upper), ('\u{1e81}', '\u{1e81}', SC_Lower), + ('\u{1e82}', '\u{1e82}', SC_Upper), ('\u{1e83}', '\u{1e83}', SC_Lower), ('\u{1e84}', + '\u{1e84}', SC_Upper), ('\u{1e85}', '\u{1e85}', SC_Lower), ('\u{1e86}', '\u{1e86}', + SC_Upper), ('\u{1e87}', '\u{1e87}', SC_Lower), ('\u{1e88}', '\u{1e88}', SC_Upper), + ('\u{1e89}', '\u{1e89}', SC_Lower), ('\u{1e8a}', '\u{1e8a}', SC_Upper), ('\u{1e8b}', + '\u{1e8b}', SC_Lower), ('\u{1e8c}', '\u{1e8c}', SC_Upper), ('\u{1e8d}', '\u{1e8d}', + SC_Lower), ('\u{1e8e}', '\u{1e8e}', SC_Upper), ('\u{1e8f}', '\u{1e8f}', SC_Lower), + ('\u{1e90}', '\u{1e90}', SC_Upper), ('\u{1e91}', '\u{1e91}', SC_Lower), ('\u{1e92}', + '\u{1e92}', SC_Upper), ('\u{1e93}', '\u{1e93}', SC_Lower), ('\u{1e94}', '\u{1e94}', + SC_Upper), ('\u{1e95}', '\u{1e9d}', SC_Lower), ('\u{1e9e}', '\u{1e9e}', SC_Upper), + ('\u{1e9f}', '\u{1e9f}', SC_Lower), ('\u{1ea0}', '\u{1ea0}', SC_Upper), ('\u{1ea1}', + '\u{1ea1}', SC_Lower), ('\u{1ea2}', '\u{1ea2}', SC_Upper), ('\u{1ea3}', '\u{1ea3}', + SC_Lower), ('\u{1ea4}', '\u{1ea4}', SC_Upper), ('\u{1ea5}', '\u{1ea5}', SC_Lower), + ('\u{1ea6}', '\u{1ea6}', SC_Upper), ('\u{1ea7}', '\u{1ea7}', SC_Lower), ('\u{1ea8}', + '\u{1ea8}', SC_Upper), ('\u{1ea9}', '\u{1ea9}', SC_Lower), ('\u{1eaa}', '\u{1eaa}', + SC_Upper), ('\u{1eab}', '\u{1eab}', SC_Lower), ('\u{1eac}', '\u{1eac}', SC_Upper), + ('\u{1ead}', '\u{1ead}', SC_Lower), ('\u{1eae}', '\u{1eae}', SC_Upper), ('\u{1eaf}', + '\u{1eaf}', SC_Lower), ('\u{1eb0}', '\u{1eb0}', SC_Upper), ('\u{1eb1}', '\u{1eb1}', + SC_Lower), ('\u{1eb2}', '\u{1eb2}', SC_Upper), ('\u{1eb3}', '\u{1eb3}', SC_Lower), + ('\u{1eb4}', '\u{1eb4}', SC_Upper), ('\u{1eb5}', '\u{1eb5}', SC_Lower), ('\u{1eb6}', + '\u{1eb6}', SC_Upper), ('\u{1eb7}', '\u{1eb7}', SC_Lower), ('\u{1eb8}', '\u{1eb8}', + SC_Upper), ('\u{1eb9}', '\u{1eb9}', SC_Lower), ('\u{1eba}', '\u{1eba}', SC_Upper), + ('\u{1ebb}', '\u{1ebb}', SC_Lower), ('\u{1ebc}', '\u{1ebc}', SC_Upper), ('\u{1ebd}', + '\u{1ebd}', SC_Lower), ('\u{1ebe}', '\u{1ebe}', SC_Upper), ('\u{1ebf}', '\u{1ebf}', + SC_Lower), ('\u{1ec0}', '\u{1ec0}', SC_Upper), ('\u{1ec1}', '\u{1ec1}', SC_Lower), + ('\u{1ec2}', '\u{1ec2}', SC_Upper), ('\u{1ec3}', '\u{1ec3}', SC_Lower), ('\u{1ec4}', + '\u{1ec4}', SC_Upper), ('\u{1ec5}', '\u{1ec5}', SC_Lower), ('\u{1ec6}', '\u{1ec6}', + SC_Upper), ('\u{1ec7}', '\u{1ec7}', SC_Lower), ('\u{1ec8}', '\u{1ec8}', SC_Upper), + ('\u{1ec9}', '\u{1ec9}', SC_Lower), ('\u{1eca}', '\u{1eca}', SC_Upper), ('\u{1ecb}', + '\u{1ecb}', SC_Lower), ('\u{1ecc}', '\u{1ecc}', SC_Upper), ('\u{1ecd}', '\u{1ecd}', + SC_Lower), ('\u{1ece}', '\u{1ece}', SC_Upper), ('\u{1ecf}', '\u{1ecf}', SC_Lower), + ('\u{1ed0}', '\u{1ed0}', SC_Upper), ('\u{1ed1}', '\u{1ed1}', SC_Lower), ('\u{1ed2}', + '\u{1ed2}', SC_Upper), ('\u{1ed3}', '\u{1ed3}', SC_Lower), ('\u{1ed4}', '\u{1ed4}', + SC_Upper), ('\u{1ed5}', '\u{1ed5}', SC_Lower), ('\u{1ed6}', '\u{1ed6}', SC_Upper), + ('\u{1ed7}', '\u{1ed7}', SC_Lower), ('\u{1ed8}', '\u{1ed8}', SC_Upper), ('\u{1ed9}', + '\u{1ed9}', SC_Lower), ('\u{1eda}', '\u{1eda}', SC_Upper), ('\u{1edb}', '\u{1edb}', + SC_Lower), ('\u{1edc}', '\u{1edc}', SC_Upper), ('\u{1edd}', '\u{1edd}', SC_Lower), + ('\u{1ede}', '\u{1ede}', SC_Upper), ('\u{1edf}', '\u{1edf}', SC_Lower), ('\u{1ee0}', + '\u{1ee0}', SC_Upper), ('\u{1ee1}', '\u{1ee1}', SC_Lower), ('\u{1ee2}', '\u{1ee2}', + SC_Upper), ('\u{1ee3}', '\u{1ee3}', SC_Lower), ('\u{1ee4}', '\u{1ee4}', SC_Upper), + ('\u{1ee5}', '\u{1ee5}', SC_Lower), ('\u{1ee6}', '\u{1ee6}', SC_Upper), ('\u{1ee7}', + '\u{1ee7}', SC_Lower), ('\u{1ee8}', '\u{1ee8}', SC_Upper), ('\u{1ee9}', '\u{1ee9}', + SC_Lower), ('\u{1eea}', '\u{1eea}', SC_Upper), ('\u{1eeb}', '\u{1eeb}', SC_Lower), + ('\u{1eec}', '\u{1eec}', SC_Upper), ('\u{1eed}', '\u{1eed}', SC_Lower), ('\u{1eee}', + '\u{1eee}', SC_Upper), ('\u{1eef}', '\u{1eef}', SC_Lower), ('\u{1ef0}', '\u{1ef0}', + SC_Upper), ('\u{1ef1}', '\u{1ef1}', SC_Lower), ('\u{1ef2}', '\u{1ef2}', SC_Upper), + ('\u{1ef3}', '\u{1ef3}', SC_Lower), ('\u{1ef4}', '\u{1ef4}', SC_Upper), ('\u{1ef5}', + '\u{1ef5}', SC_Lower), ('\u{1ef6}', '\u{1ef6}', SC_Upper), ('\u{1ef7}', '\u{1ef7}', + SC_Lower), ('\u{1ef8}', '\u{1ef8}', SC_Upper), ('\u{1ef9}', '\u{1ef9}', SC_Lower), + ('\u{1efa}', '\u{1efa}', SC_Upper), ('\u{1efb}', '\u{1efb}', SC_Lower), ('\u{1efc}', + '\u{1efc}', SC_Upper), ('\u{1efd}', '\u{1efd}', SC_Lower), ('\u{1efe}', '\u{1efe}', + SC_Upper), ('\u{1eff}', '\u{1f07}', SC_Lower), ('\u{1f08}', '\u{1f0f}', SC_Upper), + ('\u{1f10}', '\u{1f15}', SC_Lower), ('\u{1f18}', '\u{1f1d}', SC_Upper), ('\u{1f20}', + '\u{1f27}', SC_Lower), ('\u{1f28}', '\u{1f2f}', SC_Upper), ('\u{1f30}', '\u{1f37}', + SC_Lower), ('\u{1f38}', '\u{1f3f}', SC_Upper), ('\u{1f40}', '\u{1f45}', SC_Lower), + ('\u{1f48}', '\u{1f4d}', SC_Upper), ('\u{1f50}', '\u{1f57}', SC_Lower), ('\u{1f59}', + '\u{1f59}', SC_Upper), ('\u{1f5b}', '\u{1f5b}', SC_Upper), ('\u{1f5d}', '\u{1f5d}', + SC_Upper), ('\u{1f5f}', '\u{1f5f}', SC_Upper), ('\u{1f60}', '\u{1f67}', SC_Lower), + ('\u{1f68}', '\u{1f6f}', SC_Upper), ('\u{1f70}', '\u{1f7d}', SC_Lower), ('\u{1f80}', + '\u{1f87}', SC_Lower), ('\u{1f88}', '\u{1f8f}', SC_Upper), ('\u{1f90}', '\u{1f97}', + SC_Lower), ('\u{1f98}', '\u{1f9f}', SC_Upper), ('\u{1fa0}', '\u{1fa7}', SC_Lower), + ('\u{1fa8}', '\u{1faf}', SC_Upper), ('\u{1fb0}', '\u{1fb4}', SC_Lower), ('\u{1fb6}', + '\u{1fb7}', SC_Lower), ('\u{1fb8}', '\u{1fbc}', SC_Upper), ('\u{1fbe}', '\u{1fbe}', + SC_Lower), ('\u{1fc2}', '\u{1fc4}', SC_Lower), ('\u{1fc6}', '\u{1fc7}', SC_Lower), + ('\u{1fc8}', '\u{1fcc}', SC_Upper), ('\u{1fd0}', '\u{1fd3}', SC_Lower), ('\u{1fd6}', + '\u{1fd7}', SC_Lower), ('\u{1fd8}', '\u{1fdb}', SC_Upper), ('\u{1fe0}', '\u{1fe7}', + SC_Lower), ('\u{1fe8}', '\u{1fec}', SC_Upper), ('\u{1ff2}', '\u{1ff4}', SC_Lower), + ('\u{1ff6}', '\u{1ff7}', SC_Lower), ('\u{1ff8}', '\u{1ffc}', SC_Upper), ('\u{2000}', + '\u{200a}', SC_Sp), ('\u{200b}', '\u{200b}', SC_Format), ('\u{200c}', '\u{200d}', + SC_Extend), ('\u{200e}', '\u{200f}', SC_Format), ('\u{2013}', '\u{2014}', SC_SContinue), + ('\u{2018}', '\u{201f}', SC_Close), ('\u{2024}', '\u{2024}', SC_ATerm), ('\u{2028}', + '\u{2029}', SC_Sep), ('\u{202a}', '\u{202e}', SC_Format), ('\u{202f}', '\u{202f}', SC_Sp), + ('\u{2039}', '\u{203a}', SC_Close), ('\u{203c}', '\u{203d}', SC_STerm), ('\u{2045}', + '\u{2046}', SC_Close), ('\u{2047}', '\u{2049}', SC_STerm), ('\u{205f}', '\u{205f}', SC_Sp), + ('\u{2060}', '\u{2064}', SC_Format), ('\u{2066}', '\u{206f}', SC_Format), ('\u{2071}', + '\u{2071}', SC_Lower), ('\u{207d}', '\u{207e}', SC_Close), ('\u{207f}', '\u{207f}', + SC_Lower), ('\u{208d}', '\u{208e}', SC_Close), ('\u{2090}', '\u{209c}', SC_Lower), + ('\u{20d0}', '\u{20f0}', SC_Extend), ('\u{2102}', '\u{2102}', SC_Upper), ('\u{2107}', + '\u{2107}', SC_Upper), ('\u{210a}', '\u{210a}', SC_Lower), ('\u{210b}', '\u{210d}', + SC_Upper), ('\u{210e}', '\u{210f}', SC_Lower), ('\u{2110}', '\u{2112}', SC_Upper), + ('\u{2113}', '\u{2113}', SC_Lower), ('\u{2115}', '\u{2115}', SC_Upper), ('\u{2119}', + '\u{211d}', SC_Upper), ('\u{2124}', '\u{2124}', SC_Upper), ('\u{2126}', '\u{2126}', + SC_Upper), ('\u{2128}', '\u{2128}', SC_Upper), ('\u{212a}', '\u{212d}', SC_Upper), + ('\u{212f}', '\u{212f}', SC_Lower), ('\u{2130}', '\u{2133}', SC_Upper), ('\u{2134}', + '\u{2134}', SC_Lower), ('\u{2135}', '\u{2138}', SC_OLetter), ('\u{2139}', '\u{2139}', + SC_Lower), ('\u{213c}', '\u{213d}', SC_Lower), ('\u{213e}', '\u{213f}', SC_Upper), + ('\u{2145}', '\u{2145}', SC_Upper), ('\u{2146}', '\u{2149}', SC_Lower), ('\u{214e}', + '\u{214e}', SC_Lower), ('\u{2160}', '\u{216f}', SC_Upper), ('\u{2170}', '\u{217f}', + SC_Lower), ('\u{2180}', '\u{2182}', SC_OLetter), ('\u{2183}', '\u{2183}', SC_Upper), + ('\u{2184}', '\u{2184}', SC_Lower), ('\u{2185}', '\u{2188}', SC_OLetter), ('\u{2308}', + '\u{230b}', SC_Close), ('\u{2329}', '\u{232a}', SC_Close), ('\u{24b6}', '\u{24cf}', + SC_Upper), ('\u{24d0}', '\u{24e9}', SC_Lower), ('\u{275b}', '\u{2760}', SC_Close), + ('\u{2768}', '\u{2775}', SC_Close), ('\u{27c5}', '\u{27c6}', SC_Close), ('\u{27e6}', + '\u{27ef}', SC_Close), ('\u{2983}', '\u{2998}', SC_Close), ('\u{29d8}', '\u{29db}', + SC_Close), ('\u{29fc}', '\u{29fd}', SC_Close), ('\u{2c00}', '\u{2c2f}', SC_Upper), + ('\u{2c30}', '\u{2c5f}', SC_Lower), ('\u{2c60}', '\u{2c60}', SC_Upper), ('\u{2c61}', + '\u{2c61}', SC_Lower), ('\u{2c62}', '\u{2c64}', SC_Upper), ('\u{2c65}', '\u{2c66}', + SC_Lower), ('\u{2c67}', '\u{2c67}', SC_Upper), ('\u{2c68}', '\u{2c68}', SC_Lower), + ('\u{2c69}', '\u{2c69}', SC_Upper), ('\u{2c6a}', '\u{2c6a}', SC_Lower), ('\u{2c6b}', + '\u{2c6b}', SC_Upper), ('\u{2c6c}', '\u{2c6c}', SC_Lower), ('\u{2c6d}', '\u{2c70}', + SC_Upper), ('\u{2c71}', '\u{2c71}', SC_Lower), ('\u{2c72}', '\u{2c72}', SC_Upper), + ('\u{2c73}', '\u{2c74}', SC_Lower), ('\u{2c75}', '\u{2c75}', SC_Upper), ('\u{2c76}', + '\u{2c7d}', SC_Lower), ('\u{2c7e}', '\u{2c80}', SC_Upper), ('\u{2c81}', '\u{2c81}', + SC_Lower), ('\u{2c82}', '\u{2c82}', SC_Upper), ('\u{2c83}', '\u{2c83}', SC_Lower), + ('\u{2c84}', '\u{2c84}', SC_Upper), ('\u{2c85}', '\u{2c85}', SC_Lower), ('\u{2c86}', + '\u{2c86}', SC_Upper), ('\u{2c87}', '\u{2c87}', SC_Lower), ('\u{2c88}', '\u{2c88}', + SC_Upper), ('\u{2c89}', '\u{2c89}', SC_Lower), ('\u{2c8a}', '\u{2c8a}', SC_Upper), + ('\u{2c8b}', '\u{2c8b}', SC_Lower), ('\u{2c8c}', '\u{2c8c}', SC_Upper), ('\u{2c8d}', + '\u{2c8d}', SC_Lower), ('\u{2c8e}', '\u{2c8e}', SC_Upper), ('\u{2c8f}', '\u{2c8f}', + SC_Lower), ('\u{2c90}', '\u{2c90}', SC_Upper), ('\u{2c91}', '\u{2c91}', SC_Lower), + ('\u{2c92}', '\u{2c92}', SC_Upper), ('\u{2c93}', '\u{2c93}', SC_Lower), ('\u{2c94}', + '\u{2c94}', SC_Upper), ('\u{2c95}', '\u{2c95}', SC_Lower), ('\u{2c96}', '\u{2c96}', + SC_Upper), ('\u{2c97}', '\u{2c97}', SC_Lower), ('\u{2c98}', '\u{2c98}', SC_Upper), + ('\u{2c99}', '\u{2c99}', SC_Lower), ('\u{2c9a}', '\u{2c9a}', SC_Upper), ('\u{2c9b}', + '\u{2c9b}', SC_Lower), ('\u{2c9c}', '\u{2c9c}', SC_Upper), ('\u{2c9d}', '\u{2c9d}', + SC_Lower), ('\u{2c9e}', '\u{2c9e}', SC_Upper), ('\u{2c9f}', '\u{2c9f}', SC_Lower), + ('\u{2ca0}', '\u{2ca0}', SC_Upper), ('\u{2ca1}', '\u{2ca1}', SC_Lower), ('\u{2ca2}', + '\u{2ca2}', SC_Upper), ('\u{2ca3}', '\u{2ca3}', SC_Lower), ('\u{2ca4}', '\u{2ca4}', + SC_Upper), ('\u{2ca5}', '\u{2ca5}', SC_Lower), ('\u{2ca6}', '\u{2ca6}', SC_Upper), + ('\u{2ca7}', '\u{2ca7}', SC_Lower), ('\u{2ca8}', '\u{2ca8}', SC_Upper), ('\u{2ca9}', + '\u{2ca9}', SC_Lower), ('\u{2caa}', '\u{2caa}', SC_Upper), ('\u{2cab}', '\u{2cab}', + SC_Lower), ('\u{2cac}', '\u{2cac}', SC_Upper), ('\u{2cad}', '\u{2cad}', SC_Lower), + ('\u{2cae}', '\u{2cae}', SC_Upper), ('\u{2caf}', '\u{2caf}', SC_Lower), ('\u{2cb0}', + '\u{2cb0}', SC_Upper), ('\u{2cb1}', '\u{2cb1}', SC_Lower), ('\u{2cb2}', '\u{2cb2}', + SC_Upper), ('\u{2cb3}', '\u{2cb3}', SC_Lower), ('\u{2cb4}', '\u{2cb4}', SC_Upper), + ('\u{2cb5}', '\u{2cb5}', SC_Lower), ('\u{2cb6}', '\u{2cb6}', SC_Upper), ('\u{2cb7}', + '\u{2cb7}', SC_Lower), ('\u{2cb8}', '\u{2cb8}', SC_Upper), ('\u{2cb9}', '\u{2cb9}', + SC_Lower), ('\u{2cba}', '\u{2cba}', SC_Upper), ('\u{2cbb}', '\u{2cbb}', SC_Lower), + ('\u{2cbc}', '\u{2cbc}', SC_Upper), ('\u{2cbd}', '\u{2cbd}', SC_Lower), ('\u{2cbe}', + '\u{2cbe}', SC_Upper), ('\u{2cbf}', '\u{2cbf}', SC_Lower), ('\u{2cc0}', '\u{2cc0}', + SC_Upper), ('\u{2cc1}', '\u{2cc1}', SC_Lower), ('\u{2cc2}', '\u{2cc2}', SC_Upper), + ('\u{2cc3}', '\u{2cc3}', SC_Lower), ('\u{2cc4}', '\u{2cc4}', SC_Upper), ('\u{2cc5}', + '\u{2cc5}', SC_Lower), ('\u{2cc6}', '\u{2cc6}', SC_Upper), ('\u{2cc7}', '\u{2cc7}', + SC_Lower), ('\u{2cc8}', '\u{2cc8}', SC_Upper), ('\u{2cc9}', '\u{2cc9}', SC_Lower), + ('\u{2cca}', '\u{2cca}', SC_Upper), ('\u{2ccb}', '\u{2ccb}', SC_Lower), ('\u{2ccc}', + '\u{2ccc}', SC_Upper), ('\u{2ccd}', '\u{2ccd}', SC_Lower), ('\u{2cce}', '\u{2cce}', + SC_Upper), ('\u{2ccf}', '\u{2ccf}', SC_Lower), ('\u{2cd0}', '\u{2cd0}', SC_Upper), + ('\u{2cd1}', '\u{2cd1}', SC_Lower), ('\u{2cd2}', '\u{2cd2}', SC_Upper), ('\u{2cd3}', + '\u{2cd3}', SC_Lower), ('\u{2cd4}', '\u{2cd4}', SC_Upper), ('\u{2cd5}', '\u{2cd5}', + SC_Lower), ('\u{2cd6}', '\u{2cd6}', SC_Upper), ('\u{2cd7}', '\u{2cd7}', SC_Lower), + ('\u{2cd8}', '\u{2cd8}', SC_Upper), ('\u{2cd9}', '\u{2cd9}', SC_Lower), ('\u{2cda}', + '\u{2cda}', SC_Upper), ('\u{2cdb}', '\u{2cdb}', SC_Lower), ('\u{2cdc}', '\u{2cdc}', + SC_Upper), ('\u{2cdd}', '\u{2cdd}', SC_Lower), ('\u{2cde}', '\u{2cde}', SC_Upper), + ('\u{2cdf}', '\u{2cdf}', SC_Lower), ('\u{2ce0}', '\u{2ce0}', SC_Upper), ('\u{2ce1}', + '\u{2ce1}', SC_Lower), ('\u{2ce2}', '\u{2ce2}', SC_Upper), ('\u{2ce3}', '\u{2ce4}', + SC_Lower), ('\u{2ceb}', '\u{2ceb}', SC_Upper), ('\u{2cec}', '\u{2cec}', SC_Lower), + ('\u{2ced}', '\u{2ced}', SC_Upper), ('\u{2cee}', '\u{2cee}', SC_Lower), ('\u{2cef}', + '\u{2cf1}', SC_Extend), ('\u{2cf2}', '\u{2cf2}', SC_Upper), ('\u{2cf3}', '\u{2cf3}', + SC_Lower), ('\u{2d00}', '\u{2d25}', SC_Lower), ('\u{2d27}', '\u{2d27}', SC_Lower), + ('\u{2d2d}', '\u{2d2d}', SC_Lower), ('\u{2d30}', '\u{2d67}', SC_OLetter), ('\u{2d6f}', + '\u{2d6f}', SC_OLetter), ('\u{2d7f}', '\u{2d7f}', SC_Extend), ('\u{2d80}', '\u{2d96}', + SC_OLetter), ('\u{2da0}', '\u{2da6}', SC_OLetter), ('\u{2da8}', '\u{2dae}', SC_OLetter), + ('\u{2db0}', '\u{2db6}', SC_OLetter), ('\u{2db8}', '\u{2dbe}', SC_OLetter), ('\u{2dc0}', + '\u{2dc6}', SC_OLetter), ('\u{2dc8}', '\u{2dce}', SC_OLetter), ('\u{2dd0}', '\u{2dd6}', + SC_OLetter), ('\u{2dd8}', '\u{2dde}', SC_OLetter), ('\u{2de0}', '\u{2dff}', SC_Extend), + ('\u{2e00}', '\u{2e0d}', SC_Close), ('\u{2e1c}', '\u{2e1d}', SC_Close), ('\u{2e20}', + '\u{2e29}', SC_Close), ('\u{2e2e}', '\u{2e2e}', SC_STerm), ('\u{2e2f}', '\u{2e2f}', + SC_OLetter), ('\u{2e3c}', '\u{2e3c}', SC_STerm), ('\u{2e42}', '\u{2e42}', SC_Close), + ('\u{2e53}', '\u{2e54}', SC_STerm), ('\u{2e55}', '\u{2e5c}', SC_Close), ('\u{3000}', + '\u{3000}', SC_Sp), ('\u{3001}', '\u{3001}', SC_SContinue), ('\u{3002}', '\u{3002}', + SC_STerm), ('\u{3005}', '\u{3007}', SC_OLetter), ('\u{3008}', '\u{3011}', SC_Close), + ('\u{3014}', '\u{301b}', SC_Close), ('\u{301d}', '\u{301f}', SC_Close), ('\u{3021}', + '\u{3029}', SC_OLetter), ('\u{302a}', '\u{302f}', SC_Extend), ('\u{3031}', '\u{3035}', + SC_OLetter), ('\u{3038}', '\u{303c}', SC_OLetter), ('\u{3041}', '\u{3096}', SC_OLetter), + ('\u{3099}', '\u{309a}', SC_Extend), ('\u{309d}', '\u{309f}', SC_OLetter), ('\u{30a1}', + '\u{30fa}', SC_OLetter), ('\u{30fc}', '\u{30ff}', SC_OLetter), ('\u{3105}', '\u{312f}', + SC_OLetter), ('\u{3131}', '\u{318e}', SC_OLetter), ('\u{31a0}', '\u{31bf}', SC_OLetter), + ('\u{31f0}', '\u{31ff}', SC_OLetter), ('\u{3400}', '\u{4dbf}', SC_OLetter), ('\u{4e00}', + '\u{a48c}', SC_OLetter), ('\u{a4d0}', '\u{a4fd}', SC_OLetter), ('\u{a4ff}', '\u{a4ff}', + SC_STerm), ('\u{a500}', '\u{a60c}', SC_OLetter), ('\u{a60e}', '\u{a60f}', SC_STerm), + ('\u{a610}', '\u{a61f}', SC_OLetter), ('\u{a620}', '\u{a629}', SC_Numeric), ('\u{a62a}', + '\u{a62b}', SC_OLetter), ('\u{a640}', '\u{a640}', SC_Upper), ('\u{a641}', '\u{a641}', + SC_Lower), ('\u{a642}', '\u{a642}', SC_Upper), ('\u{a643}', '\u{a643}', SC_Lower), + ('\u{a644}', '\u{a644}', SC_Upper), ('\u{a645}', '\u{a645}', SC_Lower), ('\u{a646}', + '\u{a646}', SC_Upper), ('\u{a647}', '\u{a647}', SC_Lower), ('\u{a648}', '\u{a648}', + SC_Upper), ('\u{a649}', '\u{a649}', SC_Lower), ('\u{a64a}', '\u{a64a}', SC_Upper), + ('\u{a64b}', '\u{a64b}', SC_Lower), ('\u{a64c}', '\u{a64c}', SC_Upper), ('\u{a64d}', + '\u{a64d}', SC_Lower), ('\u{a64e}', '\u{a64e}', SC_Upper), ('\u{a64f}', '\u{a64f}', + SC_Lower), ('\u{a650}', '\u{a650}', SC_Upper), ('\u{a651}', '\u{a651}', SC_Lower), + ('\u{a652}', '\u{a652}', SC_Upper), ('\u{a653}', '\u{a653}', SC_Lower), ('\u{a654}', + '\u{a654}', SC_Upper), ('\u{a655}', '\u{a655}', SC_Lower), ('\u{a656}', '\u{a656}', + SC_Upper), ('\u{a657}', '\u{a657}', SC_Lower), ('\u{a658}', '\u{a658}', SC_Upper), + ('\u{a659}', '\u{a659}', SC_Lower), ('\u{a65a}', '\u{a65a}', SC_Upper), ('\u{a65b}', + '\u{a65b}', SC_Lower), ('\u{a65c}', '\u{a65c}', SC_Upper), ('\u{a65d}', '\u{a65d}', + SC_Lower), ('\u{a65e}', '\u{a65e}', SC_Upper), ('\u{a65f}', '\u{a65f}', SC_Lower), + ('\u{a660}', '\u{a660}', SC_Upper), ('\u{a661}', '\u{a661}', SC_Lower), ('\u{a662}', + '\u{a662}', SC_Upper), ('\u{a663}', '\u{a663}', SC_Lower), ('\u{a664}', '\u{a664}', + SC_Upper), ('\u{a665}', '\u{a665}', SC_Lower), ('\u{a666}', '\u{a666}', SC_Upper), + ('\u{a667}', '\u{a667}', SC_Lower), ('\u{a668}', '\u{a668}', SC_Upper), ('\u{a669}', + '\u{a669}', SC_Lower), ('\u{a66a}', '\u{a66a}', SC_Upper), ('\u{a66b}', '\u{a66b}', + SC_Lower), ('\u{a66c}', '\u{a66c}', SC_Upper), ('\u{a66d}', '\u{a66d}', SC_Lower), + ('\u{a66e}', '\u{a66e}', SC_OLetter), ('\u{a66f}', '\u{a672}', SC_Extend), ('\u{a674}', + '\u{a67d}', SC_Extend), ('\u{a67f}', '\u{a67f}', SC_OLetter), ('\u{a680}', '\u{a680}', + SC_Upper), ('\u{a681}', '\u{a681}', SC_Lower), ('\u{a682}', '\u{a682}', SC_Upper), + ('\u{a683}', '\u{a683}', SC_Lower), ('\u{a684}', '\u{a684}', SC_Upper), ('\u{a685}', + '\u{a685}', SC_Lower), ('\u{a686}', '\u{a686}', SC_Upper), ('\u{a687}', '\u{a687}', + SC_Lower), ('\u{a688}', '\u{a688}', SC_Upper), ('\u{a689}', '\u{a689}', SC_Lower), + ('\u{a68a}', '\u{a68a}', SC_Upper), ('\u{a68b}', '\u{a68b}', SC_Lower), ('\u{a68c}', + '\u{a68c}', SC_Upper), ('\u{a68d}', '\u{a68d}', SC_Lower), ('\u{a68e}', '\u{a68e}', + SC_Upper), ('\u{a68f}', '\u{a68f}', SC_Lower), ('\u{a690}', '\u{a690}', SC_Upper), + ('\u{a691}', '\u{a691}', SC_Lower), ('\u{a692}', '\u{a692}', SC_Upper), ('\u{a693}', + '\u{a693}', SC_Lower), ('\u{a694}', '\u{a694}', SC_Upper), ('\u{a695}', '\u{a695}', + SC_Lower), ('\u{a696}', '\u{a696}', SC_Upper), ('\u{a697}', '\u{a697}', SC_Lower), + ('\u{a698}', '\u{a698}', SC_Upper), ('\u{a699}', '\u{a699}', SC_Lower), ('\u{a69a}', + '\u{a69a}', SC_Upper), ('\u{a69b}', '\u{a69d}', SC_Lower), ('\u{a69e}', '\u{a69f}', + SC_Extend), ('\u{a6a0}', '\u{a6ef}', SC_OLetter), ('\u{a6f0}', '\u{a6f1}', SC_Extend), + ('\u{a6f3}', '\u{a6f3}', SC_STerm), ('\u{a6f7}', '\u{a6f7}', SC_STerm), ('\u{a717}', + '\u{a71f}', SC_OLetter), ('\u{a722}', '\u{a722}', SC_Upper), ('\u{a723}', '\u{a723}', + SC_Lower), ('\u{a724}', '\u{a724}', SC_Upper), ('\u{a725}', '\u{a725}', SC_Lower), + ('\u{a726}', '\u{a726}', SC_Upper), ('\u{a727}', '\u{a727}', SC_Lower), ('\u{a728}', + '\u{a728}', SC_Upper), ('\u{a729}', '\u{a729}', SC_Lower), ('\u{a72a}', '\u{a72a}', + SC_Upper), ('\u{a72b}', '\u{a72b}', SC_Lower), ('\u{a72c}', '\u{a72c}', SC_Upper), + ('\u{a72d}', '\u{a72d}', SC_Lower), ('\u{a72e}', '\u{a72e}', SC_Upper), ('\u{a72f}', + '\u{a731}', SC_Lower), ('\u{a732}', '\u{a732}', SC_Upper), ('\u{a733}', '\u{a733}', + SC_Lower), ('\u{a734}', '\u{a734}', SC_Upper), ('\u{a735}', '\u{a735}', SC_Lower), + ('\u{a736}', '\u{a736}', SC_Upper), ('\u{a737}', '\u{a737}', SC_Lower), ('\u{a738}', + '\u{a738}', SC_Upper), ('\u{a739}', '\u{a739}', SC_Lower), ('\u{a73a}', '\u{a73a}', + SC_Upper), ('\u{a73b}', '\u{a73b}', SC_Lower), ('\u{a73c}', '\u{a73c}', SC_Upper), + ('\u{a73d}', '\u{a73d}', SC_Lower), ('\u{a73e}', '\u{a73e}', SC_Upper), ('\u{a73f}', + '\u{a73f}', SC_Lower), ('\u{a740}', '\u{a740}', SC_Upper), ('\u{a741}', '\u{a741}', + SC_Lower), ('\u{a742}', '\u{a742}', SC_Upper), ('\u{a743}', '\u{a743}', SC_Lower), + ('\u{a744}', '\u{a744}', SC_Upper), ('\u{a745}', '\u{a745}', SC_Lower), ('\u{a746}', + '\u{a746}', SC_Upper), ('\u{a747}', '\u{a747}', SC_Lower), ('\u{a748}', '\u{a748}', + SC_Upper), ('\u{a749}', '\u{a749}', SC_Lower), ('\u{a74a}', '\u{a74a}', SC_Upper), + ('\u{a74b}', '\u{a74b}', SC_Lower), ('\u{a74c}', '\u{a74c}', SC_Upper), ('\u{a74d}', + '\u{a74d}', SC_Lower), ('\u{a74e}', '\u{a74e}', SC_Upper), ('\u{a74f}', '\u{a74f}', + SC_Lower), ('\u{a750}', '\u{a750}', SC_Upper), ('\u{a751}', '\u{a751}', SC_Lower), + ('\u{a752}', '\u{a752}', SC_Upper), ('\u{a753}', '\u{a753}', SC_Lower), ('\u{a754}', + '\u{a754}', SC_Upper), ('\u{a755}', '\u{a755}', SC_Lower), ('\u{a756}', '\u{a756}', + SC_Upper), ('\u{a757}', '\u{a757}', SC_Lower), ('\u{a758}', '\u{a758}', SC_Upper), + ('\u{a759}', '\u{a759}', SC_Lower), ('\u{a75a}', '\u{a75a}', SC_Upper), ('\u{a75b}', + '\u{a75b}', SC_Lower), ('\u{a75c}', '\u{a75c}', SC_Upper), ('\u{a75d}', '\u{a75d}', + SC_Lower), ('\u{a75e}', '\u{a75e}', SC_Upper), ('\u{a75f}', '\u{a75f}', SC_Lower), + ('\u{a760}', '\u{a760}', SC_Upper), ('\u{a761}', '\u{a761}', SC_Lower), ('\u{a762}', + '\u{a762}', SC_Upper), ('\u{a763}', '\u{a763}', SC_Lower), ('\u{a764}', '\u{a764}', + SC_Upper), ('\u{a765}', '\u{a765}', SC_Lower), ('\u{a766}', '\u{a766}', SC_Upper), + ('\u{a767}', '\u{a767}', SC_Lower), ('\u{a768}', '\u{a768}', SC_Upper), ('\u{a769}', + '\u{a769}', SC_Lower), ('\u{a76a}', '\u{a76a}', SC_Upper), ('\u{a76b}', '\u{a76b}', + SC_Lower), ('\u{a76c}', '\u{a76c}', SC_Upper), ('\u{a76d}', '\u{a76d}', SC_Lower), + ('\u{a76e}', '\u{a76e}', SC_Upper), ('\u{a76f}', '\u{a778}', SC_Lower), ('\u{a779}', + '\u{a779}', SC_Upper), ('\u{a77a}', '\u{a77a}', SC_Lower), ('\u{a77b}', '\u{a77b}', + SC_Upper), ('\u{a77c}', '\u{a77c}', SC_Lower), ('\u{a77d}', '\u{a77e}', SC_Upper), + ('\u{a77f}', '\u{a77f}', SC_Lower), ('\u{a780}', '\u{a780}', SC_Upper), ('\u{a781}', + '\u{a781}', SC_Lower), ('\u{a782}', '\u{a782}', SC_Upper), ('\u{a783}', '\u{a783}', + SC_Lower), ('\u{a784}', '\u{a784}', SC_Upper), ('\u{a785}', '\u{a785}', SC_Lower), + ('\u{a786}', '\u{a786}', SC_Upper), ('\u{a787}', '\u{a787}', SC_Lower), ('\u{a788}', + '\u{a788}', SC_OLetter), ('\u{a78b}', '\u{a78b}', SC_Upper), ('\u{a78c}', '\u{a78c}', + SC_Lower), ('\u{a78d}', '\u{a78d}', SC_Upper), ('\u{a78e}', '\u{a78e}', SC_Lower), + ('\u{a78f}', '\u{a78f}', SC_OLetter), ('\u{a790}', '\u{a790}', SC_Upper), ('\u{a791}', + '\u{a791}', SC_Lower), ('\u{a792}', '\u{a792}', SC_Upper), ('\u{a793}', '\u{a795}', + SC_Lower), ('\u{a796}', '\u{a796}', SC_Upper), ('\u{a797}', '\u{a797}', SC_Lower), + ('\u{a798}', '\u{a798}', SC_Upper), ('\u{a799}', '\u{a799}', SC_Lower), ('\u{a79a}', + '\u{a79a}', SC_Upper), ('\u{a79b}', '\u{a79b}', SC_Lower), ('\u{a79c}', '\u{a79c}', + SC_Upper), ('\u{a79d}', '\u{a79d}', SC_Lower), ('\u{a79e}', '\u{a79e}', SC_Upper), + ('\u{a79f}', '\u{a79f}', SC_Lower), ('\u{a7a0}', '\u{a7a0}', SC_Upper), ('\u{a7a1}', + '\u{a7a1}', SC_Lower), ('\u{a7a2}', '\u{a7a2}', SC_Upper), ('\u{a7a3}', '\u{a7a3}', + SC_Lower), ('\u{a7a4}', '\u{a7a4}', SC_Upper), ('\u{a7a5}', '\u{a7a5}', SC_Lower), + ('\u{a7a6}', '\u{a7a6}', SC_Upper), ('\u{a7a7}', '\u{a7a7}', SC_Lower), ('\u{a7a8}', + '\u{a7a8}', SC_Upper), ('\u{a7a9}', '\u{a7a9}', SC_Lower), ('\u{a7aa}', '\u{a7ae}', + SC_Upper), ('\u{a7af}', '\u{a7af}', SC_Lower), ('\u{a7b0}', '\u{a7b4}', SC_Upper), + ('\u{a7b5}', '\u{a7b5}', SC_Lower), ('\u{a7b6}', '\u{a7b6}', SC_Upper), ('\u{a7b7}', + '\u{a7b7}', SC_Lower), ('\u{a7b8}', '\u{a7b8}', SC_Upper), ('\u{a7b9}', '\u{a7b9}', + SC_Lower), ('\u{a7ba}', '\u{a7ba}', SC_Upper), ('\u{a7bb}', '\u{a7bb}', SC_Lower), + ('\u{a7bc}', '\u{a7bc}', SC_Upper), ('\u{a7bd}', '\u{a7bd}', SC_Lower), ('\u{a7be}', + '\u{a7be}', SC_Upper), ('\u{a7bf}', '\u{a7bf}', SC_Lower), ('\u{a7c0}', '\u{a7c0}', + SC_Upper), ('\u{a7c1}', '\u{a7c1}', SC_Lower), ('\u{a7c2}', '\u{a7c2}', SC_Upper), + ('\u{a7c3}', '\u{a7c3}', SC_Lower), ('\u{a7c4}', '\u{a7c7}', SC_Upper), ('\u{a7c8}', + '\u{a7c8}', SC_Lower), ('\u{a7c9}', '\u{a7c9}', SC_Upper), ('\u{a7ca}', '\u{a7ca}', + SC_Lower), ('\u{a7d0}', '\u{a7d0}', SC_Upper), ('\u{a7d1}', '\u{a7d1}', SC_Lower), + ('\u{a7d3}', '\u{a7d3}', SC_Lower), ('\u{a7d5}', '\u{a7d5}', SC_Lower), ('\u{a7d6}', + '\u{a7d6}', SC_Upper), ('\u{a7d7}', '\u{a7d7}', SC_Lower), ('\u{a7d8}', '\u{a7d8}', + SC_Upper), ('\u{a7d9}', '\u{a7d9}', SC_Lower), ('\u{a7f2}', '\u{a7f4}', SC_Lower), + ('\u{a7f5}', '\u{a7f5}', SC_Upper), ('\u{a7f6}', '\u{a7f6}', SC_Lower), ('\u{a7f7}', + '\u{a7f7}', SC_OLetter), ('\u{a7f8}', '\u{a7fa}', SC_Lower), ('\u{a7fb}', '\u{a801}', + SC_OLetter), ('\u{a802}', '\u{a802}', SC_Extend), ('\u{a803}', '\u{a805}', SC_OLetter), + ('\u{a806}', '\u{a806}', SC_Extend), ('\u{a807}', '\u{a80a}', SC_OLetter), ('\u{a80b}', + '\u{a80b}', SC_Extend), ('\u{a80c}', '\u{a822}', SC_OLetter), ('\u{a823}', '\u{a827}', + SC_Extend), ('\u{a82c}', '\u{a82c}', SC_Extend), ('\u{a840}', '\u{a873}', SC_OLetter), + ('\u{a876}', '\u{a877}', SC_STerm), ('\u{a880}', '\u{a881}', SC_Extend), ('\u{a882}', + '\u{a8b3}', SC_OLetter), ('\u{a8b4}', '\u{a8c5}', SC_Extend), ('\u{a8ce}', '\u{a8cf}', + SC_STerm), ('\u{a8d0}', '\u{a8d9}', SC_Numeric), ('\u{a8e0}', '\u{a8f1}', SC_Extend), + ('\u{a8f2}', '\u{a8f7}', SC_OLetter), ('\u{a8fb}', '\u{a8fb}', SC_OLetter), ('\u{a8fd}', + '\u{a8fe}', SC_OLetter), ('\u{a8ff}', '\u{a8ff}', SC_Extend), ('\u{a900}', '\u{a909}', + SC_Numeric), ('\u{a90a}', '\u{a925}', SC_OLetter), ('\u{a926}', '\u{a92d}', SC_Extend), + ('\u{a92f}', '\u{a92f}', SC_STerm), ('\u{a930}', '\u{a946}', SC_OLetter), ('\u{a947}', + '\u{a953}', SC_Extend), ('\u{a960}', '\u{a97c}', SC_OLetter), ('\u{a980}', '\u{a983}', + SC_Extend), ('\u{a984}', '\u{a9b2}', SC_OLetter), ('\u{a9b3}', '\u{a9c0}', SC_Extend), + ('\u{a9c8}', '\u{a9c9}', SC_STerm), ('\u{a9cf}', '\u{a9cf}', SC_OLetter), ('\u{a9d0}', + '\u{a9d9}', SC_Numeric), ('\u{a9e0}', '\u{a9e4}', SC_OLetter), ('\u{a9e5}', '\u{a9e5}', + SC_Extend), ('\u{a9e6}', '\u{a9ef}', SC_OLetter), ('\u{a9f0}', '\u{a9f9}', SC_Numeric), + ('\u{a9fa}', '\u{a9fe}', SC_OLetter), ('\u{aa00}', '\u{aa28}', SC_OLetter), ('\u{aa29}', + '\u{aa36}', SC_Extend), ('\u{aa40}', '\u{aa42}', SC_OLetter), ('\u{aa43}', '\u{aa43}', + SC_Extend), ('\u{aa44}', '\u{aa4b}', SC_OLetter), ('\u{aa4c}', '\u{aa4d}', SC_Extend), + ('\u{aa50}', '\u{aa59}', SC_Numeric), ('\u{aa5d}', '\u{aa5f}', SC_STerm), ('\u{aa60}', + '\u{aa76}', SC_OLetter), ('\u{aa7a}', '\u{aa7a}', SC_OLetter), ('\u{aa7b}', '\u{aa7d}', + SC_Extend), ('\u{aa7e}', '\u{aaaf}', SC_OLetter), ('\u{aab0}', '\u{aab0}', SC_Extend), + ('\u{aab1}', '\u{aab1}', SC_OLetter), ('\u{aab2}', '\u{aab4}', SC_Extend), ('\u{aab5}', + '\u{aab6}', SC_OLetter), ('\u{aab7}', '\u{aab8}', SC_Extend), ('\u{aab9}', '\u{aabd}', + SC_OLetter), ('\u{aabe}', '\u{aabf}', SC_Extend), ('\u{aac0}', '\u{aac0}', SC_OLetter), + ('\u{aac1}', '\u{aac1}', SC_Extend), ('\u{aac2}', '\u{aac2}', SC_OLetter), ('\u{aadb}', + '\u{aadd}', SC_OLetter), ('\u{aae0}', '\u{aaea}', SC_OLetter), ('\u{aaeb}', '\u{aaef}', + SC_Extend), ('\u{aaf0}', '\u{aaf1}', SC_STerm), ('\u{aaf2}', '\u{aaf4}', SC_OLetter), + ('\u{aaf5}', '\u{aaf6}', SC_Extend), ('\u{ab01}', '\u{ab06}', SC_OLetter), ('\u{ab09}', + '\u{ab0e}', SC_OLetter), ('\u{ab11}', '\u{ab16}', SC_OLetter), ('\u{ab20}', '\u{ab26}', + SC_OLetter), ('\u{ab28}', '\u{ab2e}', SC_OLetter), ('\u{ab30}', '\u{ab5a}', SC_Lower), + ('\u{ab5c}', '\u{ab69}', SC_Lower), ('\u{ab70}', '\u{abbf}', SC_Lower), ('\u{abc0}', + '\u{abe2}', SC_OLetter), ('\u{abe3}', '\u{abea}', SC_Extend), ('\u{abeb}', '\u{abeb}', + SC_STerm), ('\u{abec}', '\u{abed}', SC_Extend), ('\u{abf0}', '\u{abf9}', SC_Numeric), + ('\u{ac00}', '\u{d7a3}', SC_OLetter), ('\u{d7b0}', '\u{d7c6}', SC_OLetter), ('\u{d7cb}', + '\u{d7fb}', SC_OLetter), ('\u{f900}', '\u{fa6d}', SC_OLetter), ('\u{fa70}', '\u{fad9}', + SC_OLetter), ('\u{fb00}', '\u{fb06}', SC_Lower), ('\u{fb13}', '\u{fb17}', SC_Lower), + ('\u{fb1d}', '\u{fb1d}', SC_OLetter), ('\u{fb1e}', '\u{fb1e}', SC_Extend), ('\u{fb1f}', + '\u{fb28}', SC_OLetter), ('\u{fb2a}', '\u{fb36}', SC_OLetter), ('\u{fb38}', '\u{fb3c}', + SC_OLetter), ('\u{fb3e}', '\u{fb3e}', SC_OLetter), ('\u{fb40}', '\u{fb41}', SC_OLetter), + ('\u{fb43}', '\u{fb44}', SC_OLetter), ('\u{fb46}', '\u{fbb1}', SC_OLetter), ('\u{fbd3}', + '\u{fd3d}', SC_OLetter), ('\u{fd3e}', '\u{fd3f}', SC_Close), ('\u{fd50}', '\u{fd8f}', + SC_OLetter), ('\u{fd92}', '\u{fdc7}', SC_OLetter), ('\u{fdf0}', '\u{fdfb}', SC_OLetter), + ('\u{fe00}', '\u{fe0f}', SC_Extend), ('\u{fe10}', '\u{fe11}', SC_SContinue), ('\u{fe13}', + '\u{fe13}', SC_SContinue), ('\u{fe17}', '\u{fe18}', SC_Close), ('\u{fe20}', '\u{fe2f}', + SC_Extend), ('\u{fe31}', '\u{fe32}', SC_SContinue), ('\u{fe35}', '\u{fe44}', SC_Close), + ('\u{fe47}', '\u{fe48}', SC_Close), ('\u{fe50}', '\u{fe51}', SC_SContinue), ('\u{fe52}', + '\u{fe52}', SC_ATerm), ('\u{fe55}', '\u{fe55}', SC_SContinue), ('\u{fe56}', '\u{fe57}', + SC_STerm), ('\u{fe58}', '\u{fe58}', SC_SContinue), ('\u{fe59}', '\u{fe5e}', SC_Close), + ('\u{fe63}', '\u{fe63}', SC_SContinue), ('\u{fe70}', '\u{fe74}', SC_OLetter), ('\u{fe76}', + '\u{fefc}', SC_OLetter), ('\u{feff}', '\u{feff}', SC_Format), ('\u{ff01}', '\u{ff01}', + SC_STerm), ('\u{ff08}', '\u{ff09}', SC_Close), ('\u{ff0c}', '\u{ff0d}', SC_SContinue), + ('\u{ff0e}', '\u{ff0e}', SC_ATerm), ('\u{ff10}', '\u{ff19}', SC_Numeric), ('\u{ff1a}', + '\u{ff1a}', SC_SContinue), ('\u{ff1f}', '\u{ff1f}', SC_STerm), ('\u{ff21}', '\u{ff3a}', + SC_Upper), ('\u{ff3b}', '\u{ff3b}', SC_Close), ('\u{ff3d}', '\u{ff3d}', SC_Close), + ('\u{ff41}', '\u{ff5a}', SC_Lower), ('\u{ff5b}', '\u{ff5b}', SC_Close), ('\u{ff5d}', + '\u{ff5d}', SC_Close), ('\u{ff5f}', '\u{ff60}', SC_Close), ('\u{ff61}', '\u{ff61}', + SC_STerm), ('\u{ff62}', '\u{ff63}', SC_Close), ('\u{ff64}', '\u{ff64}', SC_SContinue), + ('\u{ff66}', '\u{ff9d}', SC_OLetter), ('\u{ff9e}', '\u{ff9f}', SC_Extend), ('\u{ffa0}', + '\u{ffbe}', SC_OLetter), ('\u{ffc2}', '\u{ffc7}', SC_OLetter), ('\u{ffca}', '\u{ffcf}', + SC_OLetter), ('\u{ffd2}', '\u{ffd7}', SC_OLetter), ('\u{ffda}', '\u{ffdc}', SC_OLetter), + ('\u{fff9}', '\u{fffb}', SC_Format), ('\u{10000}', '\u{1000b}', SC_OLetter), ('\u{1000d}', + '\u{10026}', SC_OLetter), ('\u{10028}', '\u{1003a}', SC_OLetter), ('\u{1003c}', '\u{1003d}', + SC_OLetter), ('\u{1003f}', '\u{1004d}', SC_OLetter), ('\u{10050}', '\u{1005d}', SC_OLetter), + ('\u{10080}', '\u{100fa}', SC_OLetter), ('\u{10140}', '\u{10174}', SC_OLetter), + ('\u{101fd}', '\u{101fd}', SC_Extend), ('\u{10280}', '\u{1029c}', SC_OLetter), ('\u{102a0}', + '\u{102d0}', SC_OLetter), ('\u{102e0}', '\u{102e0}', SC_Extend), ('\u{10300}', '\u{1031f}', + SC_OLetter), ('\u{1032d}', '\u{1034a}', SC_OLetter), ('\u{10350}', '\u{10375}', SC_OLetter), + ('\u{10376}', '\u{1037a}', SC_Extend), ('\u{10380}', '\u{1039d}', SC_OLetter), ('\u{103a0}', + '\u{103c3}', SC_OLetter), ('\u{103c8}', '\u{103cf}', SC_OLetter), ('\u{103d1}', '\u{103d5}', + SC_OLetter), ('\u{10400}', '\u{10427}', SC_Upper), ('\u{10428}', '\u{1044f}', SC_Lower), + ('\u{10450}', '\u{1049d}', SC_OLetter), ('\u{104a0}', '\u{104a9}', SC_Numeric), + ('\u{104b0}', '\u{104d3}', SC_Upper), ('\u{104d8}', '\u{104fb}', SC_Lower), ('\u{10500}', + '\u{10527}', SC_OLetter), ('\u{10530}', '\u{10563}', SC_OLetter), ('\u{10570}', '\u{1057a}', + SC_Upper), ('\u{1057c}', '\u{1058a}', SC_Upper), ('\u{1058c}', '\u{10592}', SC_Upper), + ('\u{10594}', '\u{10595}', SC_Upper), ('\u{10597}', '\u{105a1}', SC_Lower), ('\u{105a3}', + '\u{105b1}', SC_Lower), ('\u{105b3}', '\u{105b9}', SC_Lower), ('\u{105bb}', '\u{105bc}', + SC_Lower), ('\u{10600}', '\u{10736}', SC_OLetter), ('\u{10740}', '\u{10755}', SC_OLetter), + ('\u{10760}', '\u{10767}', SC_OLetter), ('\u{10780}', '\u{10780}', SC_Lower), ('\u{10781}', + '\u{10782}', SC_OLetter), ('\u{10783}', '\u{10785}', SC_Lower), ('\u{10787}', '\u{107b0}', + SC_Lower), ('\u{107b2}', '\u{107ba}', SC_Lower), ('\u{10800}', '\u{10805}', SC_OLetter), + ('\u{10808}', '\u{10808}', SC_OLetter), ('\u{1080a}', '\u{10835}', SC_OLetter), + ('\u{10837}', '\u{10838}', SC_OLetter), ('\u{1083c}', '\u{1083c}', SC_OLetter), ('\u{1083f}', '\u{10855}', SC_OLetter), ('\u{10860}', '\u{10876}', SC_OLetter), ('\u{10880}', '\u{1089e}', SC_OLetter), ('\u{108e0}', '\u{108f2}', SC_OLetter), ('\u{108f4}', '\u{108f5}', SC_OLetter), ('\u{10900}', '\u{10915}', SC_OLetter), @@ -2459,33 +2483,34 @@ pub mod sentence { ('\u{10c00}', '\u{10c48}', SC_OLetter), ('\u{10c80}', '\u{10cb2}', SC_Upper), ('\u{10cc0}', '\u{10cf2}', SC_Lower), ('\u{10d00}', '\u{10d23}', SC_OLetter), ('\u{10d24}', '\u{10d27}', SC_Extend), ('\u{10d30}', '\u{10d39}', SC_Numeric), ('\u{10e80}', '\u{10ea9}', SC_OLetter), - ('\u{10eab}', '\u{10eac}', SC_Extend), ('\u{10eb0}', '\u{10eb1}', SC_OLetter), ('\u{10f00}', - '\u{10f1c}', SC_OLetter), ('\u{10f27}', '\u{10f27}', SC_OLetter), ('\u{10f30}', '\u{10f45}', - SC_OLetter), ('\u{10f46}', '\u{10f50}', SC_Extend), ('\u{10f55}', '\u{10f59}', SC_STerm), - ('\u{10f70}', '\u{10f81}', SC_OLetter), ('\u{10f82}', '\u{10f85}', SC_Extend), ('\u{10f86}', - '\u{10f89}', SC_STerm), ('\u{10fb0}', '\u{10fc4}', SC_OLetter), ('\u{10fe0}', '\u{10ff6}', - SC_OLetter), ('\u{11000}', '\u{11002}', SC_Extend), ('\u{11003}', '\u{11037}', SC_OLetter), - ('\u{11038}', '\u{11046}', SC_Extend), ('\u{11047}', '\u{11048}', SC_STerm), ('\u{11066}', - '\u{1106f}', SC_Numeric), ('\u{11070}', '\u{11070}', SC_Extend), ('\u{11071}', '\u{11072}', - SC_OLetter), ('\u{11073}', '\u{11074}', SC_Extend), ('\u{11075}', '\u{11075}', SC_OLetter), - ('\u{1107f}', '\u{11082}', SC_Extend), ('\u{11083}', '\u{110af}', SC_OLetter), ('\u{110b0}', - '\u{110ba}', SC_Extend), ('\u{110bd}', '\u{110bd}', SC_Format), ('\u{110be}', '\u{110c1}', - SC_STerm), ('\u{110c2}', '\u{110c2}', SC_Extend), ('\u{110cd}', '\u{110cd}', SC_Format), - ('\u{110d0}', '\u{110e8}', SC_OLetter), ('\u{110f0}', '\u{110f9}', SC_Numeric), - ('\u{11100}', '\u{11102}', SC_Extend), ('\u{11103}', '\u{11126}', SC_OLetter), ('\u{11127}', - '\u{11134}', SC_Extend), ('\u{11136}', '\u{1113f}', SC_Numeric), ('\u{11141}', '\u{11143}', - SC_STerm), ('\u{11144}', '\u{11144}', SC_OLetter), ('\u{11145}', '\u{11146}', SC_Extend), - ('\u{11147}', '\u{11147}', SC_OLetter), ('\u{11150}', '\u{11172}', SC_OLetter), - ('\u{11173}', '\u{11173}', SC_Extend), ('\u{11176}', '\u{11176}', SC_OLetter), ('\u{11180}', - '\u{11182}', SC_Extend), ('\u{11183}', '\u{111b2}', SC_OLetter), ('\u{111b3}', '\u{111c0}', - SC_Extend), ('\u{111c1}', '\u{111c4}', SC_OLetter), ('\u{111c5}', '\u{111c6}', SC_STerm), - ('\u{111c9}', '\u{111cc}', SC_Extend), ('\u{111cd}', '\u{111cd}', SC_STerm), ('\u{111ce}', - '\u{111cf}', SC_Extend), ('\u{111d0}', '\u{111d9}', SC_Numeric), ('\u{111da}', '\u{111da}', - SC_OLetter), ('\u{111dc}', '\u{111dc}', SC_OLetter), ('\u{111de}', '\u{111df}', SC_STerm), - ('\u{11200}', '\u{11211}', SC_OLetter), ('\u{11213}', '\u{1122b}', SC_OLetter), + ('\u{10eab}', '\u{10eac}', SC_Extend), ('\u{10eb0}', '\u{10eb1}', SC_OLetter), ('\u{10efd}', + '\u{10eff}', SC_Extend), ('\u{10f00}', '\u{10f1c}', SC_OLetter), ('\u{10f27}', '\u{10f27}', + SC_OLetter), ('\u{10f30}', '\u{10f45}', SC_OLetter), ('\u{10f46}', '\u{10f50}', SC_Extend), + ('\u{10f55}', '\u{10f59}', SC_STerm), ('\u{10f70}', '\u{10f81}', SC_OLetter), ('\u{10f82}', + '\u{10f85}', SC_Extend), ('\u{10f86}', '\u{10f89}', SC_STerm), ('\u{10fb0}', '\u{10fc4}', + SC_OLetter), ('\u{10fe0}', '\u{10ff6}', SC_OLetter), ('\u{11000}', '\u{11002}', SC_Extend), + ('\u{11003}', '\u{11037}', SC_OLetter), ('\u{11038}', '\u{11046}', SC_Extend), ('\u{11047}', + '\u{11048}', SC_STerm), ('\u{11066}', '\u{1106f}', SC_Numeric), ('\u{11070}', '\u{11070}', + SC_Extend), ('\u{11071}', '\u{11072}', SC_OLetter), ('\u{11073}', '\u{11074}', SC_Extend), + ('\u{11075}', '\u{11075}', SC_OLetter), ('\u{1107f}', '\u{11082}', SC_Extend), ('\u{11083}', + '\u{110af}', SC_OLetter), ('\u{110b0}', '\u{110ba}', SC_Extend), ('\u{110bd}', '\u{110bd}', + SC_Format), ('\u{110be}', '\u{110c1}', SC_STerm), ('\u{110c2}', '\u{110c2}', SC_Extend), + ('\u{110cd}', '\u{110cd}', SC_Format), ('\u{110d0}', '\u{110e8}', SC_OLetter), ('\u{110f0}', + '\u{110f9}', SC_Numeric), ('\u{11100}', '\u{11102}', SC_Extend), ('\u{11103}', '\u{11126}', + SC_OLetter), ('\u{11127}', '\u{11134}', SC_Extend), ('\u{11136}', '\u{1113f}', SC_Numeric), + ('\u{11141}', '\u{11143}', SC_STerm), ('\u{11144}', '\u{11144}', SC_OLetter), ('\u{11145}', + '\u{11146}', SC_Extend), ('\u{11147}', '\u{11147}', SC_OLetter), ('\u{11150}', '\u{11172}', + SC_OLetter), ('\u{11173}', '\u{11173}', SC_Extend), ('\u{11176}', '\u{11176}', SC_OLetter), + ('\u{11180}', '\u{11182}', SC_Extend), ('\u{11183}', '\u{111b2}', SC_OLetter), ('\u{111b3}', + '\u{111c0}', SC_Extend), ('\u{111c1}', '\u{111c4}', SC_OLetter), ('\u{111c5}', '\u{111c6}', + SC_STerm), ('\u{111c9}', '\u{111cc}', SC_Extend), ('\u{111cd}', '\u{111cd}', SC_STerm), + ('\u{111ce}', '\u{111cf}', SC_Extend), ('\u{111d0}', '\u{111d9}', SC_Numeric), ('\u{111da}', + '\u{111da}', SC_OLetter), ('\u{111dc}', '\u{111dc}', SC_OLetter), ('\u{111de}', '\u{111df}', + SC_STerm), ('\u{11200}', '\u{11211}', SC_OLetter), ('\u{11213}', '\u{1122b}', SC_OLetter), ('\u{1122c}', '\u{11237}', SC_Extend), ('\u{11238}', '\u{11239}', SC_STerm), ('\u{1123b}', - '\u{1123c}', SC_STerm), ('\u{1123e}', '\u{1123e}', SC_Extend), ('\u{11280}', '\u{11286}', - SC_OLetter), ('\u{11288}', '\u{11288}', SC_OLetter), ('\u{1128a}', '\u{1128d}', SC_OLetter), + '\u{1123c}', SC_STerm), ('\u{1123e}', '\u{1123e}', SC_Extend), ('\u{1123f}', '\u{11240}', + SC_OLetter), ('\u{11241}', '\u{11241}', SC_Extend), ('\u{11280}', '\u{11286}', SC_OLetter), + ('\u{11288}', '\u{11288}', SC_OLetter), ('\u{1128a}', '\u{1128d}', SC_OLetter), ('\u{1128f}', '\u{1129d}', SC_OLetter), ('\u{1129f}', '\u{112a8}', SC_OLetter), ('\u{112a9}', '\u{112a9}', SC_STerm), ('\u{112b0}', '\u{112de}', SC_OLetter), ('\u{112df}', '\u{112ea}', SC_Extend), ('\u{112f0}', '\u{112f9}', SC_Numeric), ('\u{11300}', '\u{11303}', @@ -2542,17 +2567,22 @@ pub mod sentence { ('\u{11d8a}', '\u{11d8e}', SC_Extend), ('\u{11d90}', '\u{11d91}', SC_Extend), ('\u{11d93}', '\u{11d97}', SC_Extend), ('\u{11d98}', '\u{11d98}', SC_OLetter), ('\u{11da0}', '\u{11da9}', SC_Numeric), ('\u{11ee0}', '\u{11ef2}', SC_OLetter), ('\u{11ef3}', '\u{11ef6}', SC_Extend), - ('\u{11ef7}', '\u{11ef8}', SC_STerm), ('\u{11fb0}', '\u{11fb0}', SC_OLetter), ('\u{12000}', - '\u{12399}', SC_OLetter), ('\u{12400}', '\u{1246e}', SC_OLetter), ('\u{12480}', '\u{12543}', - SC_OLetter), ('\u{12f90}', '\u{12ff0}', SC_OLetter), ('\u{13000}', '\u{1342e}', SC_OLetter), - ('\u{13430}', '\u{13438}', SC_Format), ('\u{14400}', '\u{14646}', SC_OLetter), ('\u{16800}', - '\u{16a38}', SC_OLetter), ('\u{16a40}', '\u{16a5e}', SC_OLetter), ('\u{16a60}', '\u{16a69}', - SC_Numeric), ('\u{16a6e}', '\u{16a6f}', SC_STerm), ('\u{16a70}', '\u{16abe}', SC_OLetter), - ('\u{16ac0}', '\u{16ac9}', SC_Numeric), ('\u{16ad0}', '\u{16aed}', SC_OLetter), - ('\u{16af0}', '\u{16af4}', SC_Extend), ('\u{16af5}', '\u{16af5}', SC_STerm), ('\u{16b00}', - '\u{16b2f}', SC_OLetter), ('\u{16b30}', '\u{16b36}', SC_Extend), ('\u{16b37}', '\u{16b38}', - SC_STerm), ('\u{16b40}', '\u{16b43}', SC_OLetter), ('\u{16b44}', '\u{16b44}', SC_STerm), - ('\u{16b50}', '\u{16b59}', SC_Numeric), ('\u{16b63}', '\u{16b77}', SC_OLetter), + ('\u{11ef7}', '\u{11ef8}', SC_STerm), ('\u{11f00}', '\u{11f01}', SC_Extend), ('\u{11f02}', + '\u{11f02}', SC_OLetter), ('\u{11f03}', '\u{11f03}', SC_Extend), ('\u{11f04}', '\u{11f10}', + SC_OLetter), ('\u{11f12}', '\u{11f33}', SC_OLetter), ('\u{11f34}', '\u{11f3a}', SC_Extend), + ('\u{11f3e}', '\u{11f42}', SC_Extend), ('\u{11f43}', '\u{11f44}', SC_STerm), ('\u{11f50}', + '\u{11f59}', SC_Numeric), ('\u{11fb0}', '\u{11fb0}', SC_OLetter), ('\u{12000}', '\u{12399}', + SC_OLetter), ('\u{12400}', '\u{1246e}', SC_OLetter), ('\u{12480}', '\u{12543}', SC_OLetter), + ('\u{12f90}', '\u{12ff0}', SC_OLetter), ('\u{13000}', '\u{1342f}', SC_OLetter), + ('\u{13430}', '\u{1343f}', SC_Format), ('\u{13440}', '\u{13440}', SC_Extend), ('\u{13441}', + '\u{13446}', SC_OLetter), ('\u{13447}', '\u{13455}', SC_Extend), ('\u{14400}', '\u{14646}', + SC_OLetter), ('\u{16800}', '\u{16a38}', SC_OLetter), ('\u{16a40}', '\u{16a5e}', SC_OLetter), + ('\u{16a60}', '\u{16a69}', SC_Numeric), ('\u{16a6e}', '\u{16a6f}', SC_STerm), ('\u{16a70}', + '\u{16abe}', SC_OLetter), ('\u{16ac0}', '\u{16ac9}', SC_Numeric), ('\u{16ad0}', '\u{16aed}', + SC_OLetter), ('\u{16af0}', '\u{16af4}', SC_Extend), ('\u{16af5}', '\u{16af5}', SC_STerm), + ('\u{16b00}', '\u{16b2f}', SC_OLetter), ('\u{16b30}', '\u{16b36}', SC_Extend), ('\u{16b37}', + '\u{16b38}', SC_STerm), ('\u{16b40}', '\u{16b43}', SC_OLetter), ('\u{16b44}', '\u{16b44}', + SC_STerm), ('\u{16b50}', '\u{16b59}', SC_Numeric), ('\u{16b63}', '\u{16b77}', SC_OLetter), ('\u{16b7d}', '\u{16b8f}', SC_OLetter), ('\u{16e40}', '\u{16e5f}', SC_Upper), ('\u{16e60}', '\u{16e7f}', SC_Lower), ('\u{16e98}', '\u{16e98}', SC_STerm), ('\u{16f00}', '\u{16f4a}', SC_OLetter), ('\u{16f4f}', '\u{16f4f}', SC_Extend), ('\u{16f50}', '\u{16f50}', SC_OLetter), @@ -2562,7 +2592,8 @@ pub mod sentence { ('\u{17000}', '\u{187f7}', SC_OLetter), ('\u{18800}', '\u{18cd5}', SC_OLetter), ('\u{18d00}', '\u{18d08}', SC_OLetter), ('\u{1aff0}', '\u{1aff3}', SC_OLetter), ('\u{1aff5}', '\u{1affb}', SC_OLetter), ('\u{1affd}', '\u{1affe}', SC_OLetter), - ('\u{1b000}', '\u{1b122}', SC_OLetter), ('\u{1b150}', '\u{1b152}', SC_OLetter), + ('\u{1b000}', '\u{1b122}', SC_OLetter), ('\u{1b132}', '\u{1b132}', SC_OLetter), + ('\u{1b150}', '\u{1b152}', SC_OLetter), ('\u{1b155}', '\u{1b155}', SC_OLetter), ('\u{1b164}', '\u{1b167}', SC_OLetter), ('\u{1b170}', '\u{1b2fb}', SC_OLetter), ('\u{1bc00}', '\u{1bc6a}', SC_OLetter), ('\u{1bc70}', '\u{1bc7c}', SC_OLetter), ('\u{1bc80}', '\u{1bc88}', SC_OLetter), ('\u{1bc90}', '\u{1bc99}', SC_OLetter), @@ -2601,40 +2632,43 @@ pub mod sentence { SC_Extend), ('\u{1da84}', '\u{1da84}', SC_Extend), ('\u{1da88}', '\u{1da88}', SC_STerm), ('\u{1da9b}', '\u{1da9f}', SC_Extend), ('\u{1daa1}', '\u{1daaf}', SC_Extend), ('\u{1df00}', '\u{1df09}', SC_Lower), ('\u{1df0a}', '\u{1df0a}', SC_OLetter), ('\u{1df0b}', '\u{1df1e}', - SC_Lower), ('\u{1e000}', '\u{1e006}', SC_Extend), ('\u{1e008}', '\u{1e018}', SC_Extend), - ('\u{1e01b}', '\u{1e021}', SC_Extend), ('\u{1e023}', '\u{1e024}', SC_Extend), ('\u{1e026}', - '\u{1e02a}', SC_Extend), ('\u{1e100}', '\u{1e12c}', SC_OLetter), ('\u{1e130}', '\u{1e136}', - SC_Extend), ('\u{1e137}', '\u{1e13d}', SC_OLetter), ('\u{1e140}', '\u{1e149}', SC_Numeric), - ('\u{1e14e}', '\u{1e14e}', SC_OLetter), ('\u{1e290}', '\u{1e2ad}', SC_OLetter), - ('\u{1e2ae}', '\u{1e2ae}', SC_Extend), ('\u{1e2c0}', '\u{1e2eb}', SC_OLetter), ('\u{1e2ec}', - '\u{1e2ef}', SC_Extend), ('\u{1e2f0}', '\u{1e2f9}', SC_Numeric), ('\u{1e7e0}', '\u{1e7e6}', - SC_OLetter), ('\u{1e7e8}', '\u{1e7eb}', SC_OLetter), ('\u{1e7ed}', '\u{1e7ee}', SC_OLetter), - ('\u{1e7f0}', '\u{1e7fe}', SC_OLetter), ('\u{1e800}', '\u{1e8c4}', SC_OLetter), - ('\u{1e8d0}', '\u{1e8d6}', SC_Extend), ('\u{1e900}', '\u{1e921}', SC_Upper), ('\u{1e922}', - '\u{1e943}', SC_Lower), ('\u{1e944}', '\u{1e94a}', SC_Extend), ('\u{1e94b}', '\u{1e94b}', - SC_OLetter), ('\u{1e950}', '\u{1e959}', SC_Numeric), ('\u{1ee00}', '\u{1ee03}', SC_OLetter), - ('\u{1ee05}', '\u{1ee1f}', SC_OLetter), ('\u{1ee21}', '\u{1ee22}', SC_OLetter), - ('\u{1ee24}', '\u{1ee24}', SC_OLetter), ('\u{1ee27}', '\u{1ee27}', SC_OLetter), - ('\u{1ee29}', '\u{1ee32}', SC_OLetter), ('\u{1ee34}', '\u{1ee37}', SC_OLetter), - ('\u{1ee39}', '\u{1ee39}', SC_OLetter), ('\u{1ee3b}', '\u{1ee3b}', SC_OLetter), - ('\u{1ee42}', '\u{1ee42}', SC_OLetter), ('\u{1ee47}', '\u{1ee47}', SC_OLetter), - ('\u{1ee49}', '\u{1ee49}', SC_OLetter), ('\u{1ee4b}', '\u{1ee4b}', SC_OLetter), - ('\u{1ee4d}', '\u{1ee4f}', SC_OLetter), ('\u{1ee51}', '\u{1ee52}', SC_OLetter), - ('\u{1ee54}', '\u{1ee54}', SC_OLetter), ('\u{1ee57}', '\u{1ee57}', SC_OLetter), - ('\u{1ee59}', '\u{1ee59}', SC_OLetter), ('\u{1ee5b}', '\u{1ee5b}', SC_OLetter), - ('\u{1ee5d}', '\u{1ee5d}', SC_OLetter), ('\u{1ee5f}', '\u{1ee5f}', SC_OLetter), - ('\u{1ee61}', '\u{1ee62}', SC_OLetter), ('\u{1ee64}', '\u{1ee64}', SC_OLetter), - ('\u{1ee67}', '\u{1ee6a}', SC_OLetter), ('\u{1ee6c}', '\u{1ee72}', SC_OLetter), - ('\u{1ee74}', '\u{1ee77}', SC_OLetter), ('\u{1ee79}', '\u{1ee7c}', SC_OLetter), - ('\u{1ee7e}', '\u{1ee7e}', SC_OLetter), ('\u{1ee80}', '\u{1ee89}', SC_OLetter), - ('\u{1ee8b}', '\u{1ee9b}', SC_OLetter), ('\u{1eea1}', '\u{1eea3}', SC_OLetter), - ('\u{1eea5}', '\u{1eea9}', SC_OLetter), ('\u{1eeab}', '\u{1eebb}', SC_OLetter), - ('\u{1f130}', '\u{1f149}', SC_Upper), ('\u{1f150}', '\u{1f169}', SC_Upper), ('\u{1f170}', - '\u{1f189}', SC_Upper), ('\u{1f676}', '\u{1f678}', SC_Close), ('\u{1fbf0}', '\u{1fbf9}', - SC_Numeric), ('\u{20000}', '\u{2a6df}', SC_OLetter), ('\u{2a700}', '\u{2b738}', SC_OLetter), - ('\u{2b740}', '\u{2b81d}', SC_OLetter), ('\u{2b820}', '\u{2cea1}', SC_OLetter), - ('\u{2ceb0}', '\u{2ebe0}', SC_OLetter), ('\u{2f800}', '\u{2fa1d}', SC_OLetter), - ('\u{30000}', '\u{3134a}', SC_OLetter), ('\u{e0001}', '\u{e0001}', SC_Format), ('\u{e0020}', + SC_Lower), ('\u{1df25}', '\u{1df2a}', SC_Lower), ('\u{1e000}', '\u{1e006}', SC_Extend), + ('\u{1e008}', '\u{1e018}', SC_Extend), ('\u{1e01b}', '\u{1e021}', SC_Extend), ('\u{1e023}', + '\u{1e024}', SC_Extend), ('\u{1e026}', '\u{1e02a}', SC_Extend), ('\u{1e030}', '\u{1e06d}', + SC_Lower), ('\u{1e08f}', '\u{1e08f}', SC_Extend), ('\u{1e100}', '\u{1e12c}', SC_OLetter), + ('\u{1e130}', '\u{1e136}', SC_Extend), ('\u{1e137}', '\u{1e13d}', SC_OLetter), ('\u{1e140}', + '\u{1e149}', SC_Numeric), ('\u{1e14e}', '\u{1e14e}', SC_OLetter), ('\u{1e290}', '\u{1e2ad}', + SC_OLetter), ('\u{1e2ae}', '\u{1e2ae}', SC_Extend), ('\u{1e2c0}', '\u{1e2eb}', SC_OLetter), + ('\u{1e2ec}', '\u{1e2ef}', SC_Extend), ('\u{1e2f0}', '\u{1e2f9}', SC_Numeric), ('\u{1e4d0}', + '\u{1e4eb}', SC_OLetter), ('\u{1e4ec}', '\u{1e4ef}', SC_Extend), ('\u{1e4f0}', '\u{1e4f9}', + SC_Numeric), ('\u{1e7e0}', '\u{1e7e6}', SC_OLetter), ('\u{1e7e8}', '\u{1e7eb}', SC_OLetter), + ('\u{1e7ed}', '\u{1e7ee}', SC_OLetter), ('\u{1e7f0}', '\u{1e7fe}', SC_OLetter), + ('\u{1e800}', '\u{1e8c4}', SC_OLetter), ('\u{1e8d0}', '\u{1e8d6}', SC_Extend), ('\u{1e900}', + '\u{1e921}', SC_Upper), ('\u{1e922}', '\u{1e943}', SC_Lower), ('\u{1e944}', '\u{1e94a}', + SC_Extend), ('\u{1e94b}', '\u{1e94b}', SC_OLetter), ('\u{1e950}', '\u{1e959}', SC_Numeric), + ('\u{1ee00}', '\u{1ee03}', SC_OLetter), ('\u{1ee05}', '\u{1ee1f}', SC_OLetter), + ('\u{1ee21}', '\u{1ee22}', SC_OLetter), ('\u{1ee24}', '\u{1ee24}', SC_OLetter), + ('\u{1ee27}', '\u{1ee27}', SC_OLetter), ('\u{1ee29}', '\u{1ee32}', SC_OLetter), + ('\u{1ee34}', '\u{1ee37}', SC_OLetter), ('\u{1ee39}', '\u{1ee39}', SC_OLetter), + ('\u{1ee3b}', '\u{1ee3b}', SC_OLetter), ('\u{1ee42}', '\u{1ee42}', SC_OLetter), + ('\u{1ee47}', '\u{1ee47}', SC_OLetter), ('\u{1ee49}', '\u{1ee49}', SC_OLetter), + ('\u{1ee4b}', '\u{1ee4b}', SC_OLetter), ('\u{1ee4d}', '\u{1ee4f}', SC_OLetter), + ('\u{1ee51}', '\u{1ee52}', SC_OLetter), ('\u{1ee54}', '\u{1ee54}', SC_OLetter), + ('\u{1ee57}', '\u{1ee57}', SC_OLetter), ('\u{1ee59}', '\u{1ee59}', SC_OLetter), + ('\u{1ee5b}', '\u{1ee5b}', SC_OLetter), ('\u{1ee5d}', '\u{1ee5d}', SC_OLetter), + ('\u{1ee5f}', '\u{1ee5f}', SC_OLetter), ('\u{1ee61}', '\u{1ee62}', SC_OLetter), + ('\u{1ee64}', '\u{1ee64}', SC_OLetter), ('\u{1ee67}', '\u{1ee6a}', SC_OLetter), + ('\u{1ee6c}', '\u{1ee72}', SC_OLetter), ('\u{1ee74}', '\u{1ee77}', SC_OLetter), + ('\u{1ee79}', '\u{1ee7c}', SC_OLetter), ('\u{1ee7e}', '\u{1ee7e}', SC_OLetter), + ('\u{1ee80}', '\u{1ee89}', SC_OLetter), ('\u{1ee8b}', '\u{1ee9b}', SC_OLetter), + ('\u{1eea1}', '\u{1eea3}', SC_OLetter), ('\u{1eea5}', '\u{1eea9}', SC_OLetter), + ('\u{1eeab}', '\u{1eebb}', SC_OLetter), ('\u{1f130}', '\u{1f149}', SC_Upper), ('\u{1f150}', + '\u{1f169}', SC_Upper), ('\u{1f170}', '\u{1f189}', SC_Upper), ('\u{1f676}', '\u{1f678}', + SC_Close), ('\u{1fbf0}', '\u{1fbf9}', SC_Numeric), ('\u{20000}', '\u{2a6df}', SC_OLetter), + ('\u{2a700}', '\u{2b739}', SC_OLetter), ('\u{2b740}', '\u{2b81d}', SC_OLetter), + ('\u{2b820}', '\u{2cea1}', SC_OLetter), ('\u{2ceb0}', '\u{2ebe0}', SC_OLetter), + ('\u{2f800}', '\u{2fa1d}', SC_OLetter), ('\u{30000}', '\u{3134a}', SC_OLetter), + ('\u{31350}', '\u{323af}', SC_OLetter), ('\u{e0001}', '\u{e0001}', SC_Format), ('\u{e0020}', '\u{e007f}', SC_Extend), ('\u{e0100}', '\u{e01ef}', SC_Extend) ]; diff --git a/vendor/unicode-segmentation/src/testdata.rs b/vendor/unicode-segmentation/src/testdata.rs index b4a1cc0c3..8a675aafe 100644 --- a/vendor/unicode-segmentation/src/testdata.rs +++ b/vendor/unicode-segmentation/src/testdata.rs @@ -12,7 +12,7 @@ #![allow(missing_docs, non_upper_case_globals, non_snake_case)] // official Unicode test data -// http://www.unicode.org/Public/14.0.0/ucd/auxiliary/GraphemeBreakTest.txt +// http://www.unicode.org/Public/15.0.0/ucd/auxiliary/GraphemeBreakTest.txt pub const TEST_SAME: &'static [(&'static str, &'static [&'static str])] = &[ ("\u{20}\u{20}", &["\u{20}", "\u{20}"]), ("\u{20}\u{308}\u{20}", &["\u{20}\u{308}", "\u{20}"]), @@ -886,7 +886,7 @@ pub const TEST_DIFF: &'static [( ]; // official Unicode test data -// http://www.unicode.org/Public/14.0.0/ucd/auxiliary/WordBreakTest.txt +// http://www.unicode.org/Public/15.0.0/ucd/auxiliary/WordBreakTest.txt pub const TEST_WORD: &'static [(&'static str, &'static [&'static str])] = &[ ("\u{1}\u{1}", &["\u{1}", "\u{1}"]), ("\u{1}\u{308}\u{1}", &["\u{1}\u{308}", "\u{1}"]), @@ -4917,7 +4917,7 @@ pub const TEST_WORD: &'static [(&'static str, &'static [&'static str])] = &[ ]; // official Unicode test data -// http://www.unicode.org/Public/14.0.0/ucd/auxiliary/SentenceBreakTest.txt +// http://www.unicode.org/Public/15.0.0/ucd/auxiliary/SentenceBreakTest.txt pub const TEST_SENTENCE: &'static [(&'static str, &'static [&'static str])] = &[ ("\u{1}\u{1}", &["\u{1}\u{1}"]), ("\u{1}\u{308}\u{1}", &["\u{1}\u{308}\u{1}"]), ("\u{1}\u{d}", &["\u{1}\u{d}"]), ("\u{1}\u{308}\u{d}", &["\u{1}\u{308}\u{d}"]), diff --git a/vendor/unicode-width/.cargo-checksum.json b/vendor/unicode-width/.cargo-checksum.json index 0d3d03912..5c7b92228 100644 --- a/vendor/unicode-width/.cargo-checksum.json +++ b/vendor/unicode-width/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"5c1c5fff7aaa9b6a7a2331ec2e26064e4cd519254446675196fb2eb5cc91c282","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"8a041a4305fb318f5c2cb284046f8480796521d0e829023b0441b5e8469490eb","scripts/unicode.py":"5c7d8d78b70223d9f0d6713bd5714c3a6fd4fcee4ed1b3bf749c84ed6dc7479a","src/lib.rs":"38c44436eac069bd8d11203f31ecfef8adfe92da1fce19ba00bdd25aa3fbbe20","src/tables.rs":"4026a4c18a4904edc38dff6fa6a179623091b5b6e8c434605f49d2377b4e8a01","src/tests.rs":"ca610f64b76ded8abb4b0cc5f373b40cf25cef009988fa6bd3382d0de3356bf7"},"package":"3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"} \ No newline at end of file +{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"f22e31fb3559e916864820719a09ab3adbf80301440e1702acf827210bbf76df","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"8a041a4305fb318f5c2cb284046f8480796521d0e829023b0441b5e8469490eb","scripts/unicode.py":"0c53095ef99395338399f9ad218b4481cffcf63774fd61871ed32efb242419f8","src/lib.rs":"38c44436eac069bd8d11203f31ecfef8adfe92da1fce19ba00bdd25aa3fbbe20","src/tables.rs":"c6ddb420c289517bb92973199fd2987b9608f29fc10bb33b5290f39b301ce92f","src/tests.rs":"ff9f331210861ba78040f119a0f6ccfacf5b2ca1ebee430784de0858fad01860"},"package":"c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"} \ No newline at end of file diff --git a/vendor/unicode-width/Cargo.toml b/vendor/unicode-width/Cargo.toml index 9cb47d54c..77aded9fc 100644 --- a/vendor/unicode-width/Cargo.toml +++ b/vendor/unicode-width/Cargo.toml @@ -11,16 +11,30 @@ [package] name = "unicode-width" -version = "0.1.9" -authors = ["kwantam ", "Manish Goregaokar "] -exclude = ["target/*", "Cargo.lock"] -description = "Determine displayed width of `char` and `str` types\naccording to Unicode Standard Annex #11 rules.\n" +version = "0.1.10" +authors = [ + "kwantam ", + "Manish Goregaokar ", +] +exclude = [ + "target/*", + "Cargo.lock", +] +description = """ +Determine displayed width of `char` and `str` types +according to Unicode Standard Annex #11 rules. +""" homepage = "https://github.com/unicode-rs/unicode-width" documentation = "https://unicode-rs.github.io/unicode-width" readme = "README.md" -keywords = ["text", "width", "unicode"] +keywords = [ + "text", + "width", + "unicode", +] license = "MIT/Apache-2.0" repository = "https://github.com/unicode-rs/unicode-width" + [dependencies.compiler_builtins] version = "0.1" optional = true @@ -39,4 +53,8 @@ package = "rustc-std-workspace-std" bench = [] default = [] no_std = [] -rustc-dep-of-std = ["std", "core", "compiler_builtins"] +rustc-dep-of-std = [ + "std", + "core", + "compiler_builtins", +] diff --git a/vendor/unicode-width/scripts/unicode.py b/vendor/unicode-width/scripts/unicode.py index 7f5959d4b..2efb0b63f 100755 --- a/vendor/unicode-width/scripts/unicode.py +++ b/vendor/unicode-width/scripts/unicode.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright 2011-2015 The Rust Project Developers. See the COPYRIGHT +# Copyright 2011-2022 The Rust Project Developers. See the COPYRIGHT # file at the top-level directory of this distribution and at # http://rust-lang.org/COPYRIGHT. # @@ -16,11 +16,322 @@ # - UnicodeData.txt # # Since this should not require frequent updates, we just store this -# out-of-line and check the unicode.rs file into git. - -import fileinput, re, os, sys, operator +# out-of-line and check the generated module into git. + +import enum +import math +import os +import re +import sys + +NUM_CODEPOINTS = 0x110000 +"""An upper bound for which `range(0, NUM_CODEPOINTS)` contains Unicode's codespace.""" + +MAX_CODEPOINT_BITS = math.ceil(math.log2(NUM_CODEPOINTS - 1)) +"""The maximum number of bits required to represent a Unicode codepoint.""" + + +class OffsetType(enum.IntEnum): + """Represents the data type of a lookup table's offsets. Each variant's value represents the + number of bits required to represent that variant's type.""" + + U2 = 2 + """Offsets are 2-bit unsigned integers, packed four-per-byte.""" + U4 = 4 + """Offsets are 4-bit unsigned integers, packed two-per-byte.""" + U8 = 8 + """Each offset is a single byte (u8).""" + + +TABLE_CFGS = [ + (13, MAX_CODEPOINT_BITS, OffsetType.U8), + (6, 13, OffsetType.U8), + (0, 6, OffsetType.U2), +] +"""Represents the format of each level of the multi-level lookup table. +A level's entry is of the form `(low_bit, cap_bit, offset_type)`. +This means that every sub-table in that level is indexed by bits `low_bit..cap_bit` of the +codepoint and those tables offsets are stored according to `offset_type`. + +If this is edited, you must ensure that `emit_module` reflects your changes.""" + +MODULE_FILENAME = "tables.rs" +"""The filename of the emitted Rust module (will be created in the working directory)""" + +Codepoint = int +BitPos = int + + +def fetch_open(filename: str): + """Opens `filename` and return its corresponding file object. If `filename` isn't on disk, + fetches it from `http://www.unicode.org/Public/UNIDATA/`. Exits with code 1 on failure.""" + if not os.path.exists(os.path.basename(filename)): + os.system(f"curl -O http://www.unicode.org/Public/UNIDATA/{filename}") + try: + return open(filename, encoding="utf-8") + except OSError: + sys.stderr.write(f"cannot load {filename}") + sys.exit(1) + + +def load_unicode_version() -> "tuple[int, int, int]": + """Returns the current Unicode version by fetching and processing `ReadMe.txt`.""" + with fetch_open("ReadMe.txt") as readme: + pattern = r"for Version (\d+)\.(\d+)\.(\d+) of the Unicode" + return tuple(map(int, re.search(pattern, readme.read()).groups())) + + +class EffectiveWidth(enum.IntEnum): + """Represents the width of a Unicode character. All East Asian Width classes resolve into + either `EffectiveWidth.NARROW`, `EffectiveWidth.WIDE`, or `EffectiveWidth.AMBIGUOUS`.""" + + ZERO = 0 + """ Zero columns wide. """ + NARROW = 1 + """ One column wide. """ + WIDE = 2 + """ Two columns wide. """ + AMBIGUOUS = 3 + """ Two columns wide in a CJK context. One column wide in all other contexts. """ + + +def load_east_asian_widths() -> "list[EffectiveWidth]": + """Return a list of effective widths, indexed by codepoint. + Widths are determined by fetching and parsing `EastAsianWidth.txt`. + + `Neutral`, `Narrow`, and `Halfwidth` characters are assigned `EffectiveWidth.NARROW`. + + `Wide` and `Fullwidth` characters are assigned `EffectiveWidth.WIDE`. + + `Ambiguous` chracters are assigned `EffectiveWidth.AMBIGUOUS`.""" + with fetch_open("EastAsianWidth.txt") as eaw: + # matches a width assignment for a single codepoint, i.e. "1F336;N # ..." + single = re.compile(r"^([0-9A-F]+);(\w+) +# (\w+)") + # matches a width assignment for a range of codepoints, i.e. "3001..3003;W # ..." + multiple = re.compile(r"^([0-9A-F]+)\.\.([0-9A-F]+);(\w+) +# (\w+)") + # map between width category code and condensed width + width_codes = { + **{c: EffectiveWidth.NARROW for c in ["N", "Na", "H"]}, + **{c: EffectiveWidth.WIDE for c in ["W", "F"]}, + "A": EffectiveWidth.AMBIGUOUS, + } -preamble = '''// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT + width_map = [] + current = 0 + for line in eaw.readlines(): + raw_data = None # (low, high, width) + if match := single.match(line): + raw_data = (match.group(1), match.group(1), match.group(2)) + elif match := multiple.match(line): + raw_data = (match.group(1), match.group(2), match.group(3)) + else: + continue + low = int(raw_data[0], 16) + high = int(raw_data[1], 16) + width = width_codes[raw_data[2]] + + assert current <= high + while current <= high: + # Some codepoints don't fall into any of the ranges in EastAsianWidth.txt. + # All such codepoints are implicitly given Neural width (resolves to narrow) + width_map.append(EffectiveWidth.NARROW if current < low else width) + current += 1 + + while len(width_map) < NUM_CODEPOINTS: + # Catch any leftover codepoints and assign them implicit Neutral/narrow width. + width_map.append(EffectiveWidth.NARROW) + + return width_map + + +def load_zero_widths() -> "list[bool]": + """Returns a list `l` where `l[c]` is true if codepoint `c` is considered a zero-width + character. `c` is considered a zero-width character if `c` is in general categories + `Cc`, `Cf`, `Mn`, or `Me` (determined by fetching and processing `UnicodeData.txt`).""" + with fetch_open("UnicodeData.txt") as categories: + zw_map = [] + current = 0 + for line in categories.readlines(): + if len(raw_data := line.split(";")) != 15: + continue + [codepoint, name, cat_code] = [ + int(raw_data[0], 16), + raw_data[1], + raw_data[2], + ] + zero_width = cat_code in ["Cc", "Cf", "Mn", "Me"] + + assert current <= codepoint + while current <= codepoint: + if name.endswith(", Last>") or current == codepoint: + # if name ends with Last, we backfill the width value to all codepoints since + # the previous codepoint (aka the start of the range) + zw_map.append(zero_width) + else: + # unassigned characters are implicitly given Neutral width, which is nonzero + zw_map.append(False) + current += 1 + + while len(zw_map) < NUM_CODEPOINTS: + # Catch any leftover codepoints. They must be unassigned (so nonzero width) + zw_map.append(False) + + return zw_map + + +class Bucket: + """A bucket contains a group of codepoints and an ordered width list. If one bucket's width + list overlaps with another's width list, those buckets can be merged via `try_extend`.""" + + def __init__(self): + """Creates an empty bucket.""" + self.entry_set = set() + self.widths = [] + + def append(self, codepoint: Codepoint, width: EffectiveWidth): + """Adds a codepoint/width pair to the bucket, and appends `width` to the width list.""" + self.entry_set.add((codepoint, width)) + self.widths.append(width) + + def try_extend(self, attempt: "Bucket") -> bool: + """If either `self` or `attempt`'s width list starts with the other bucket's width list, + set `self`'s width list to the longer of the two, add all of `attempt`'s codepoints + into `self`, and return `True`. Otherwise, return `False`.""" + (less, more) = (self.widths, attempt.widths) + if len(self.widths) > len(attempt.widths): + (less, more) = (attempt.widths, self.widths) + if less != more[: len(less)]: + return False + self.entry_set |= attempt.entry_set + self.widths = more + return True + + def entries(self) -> "list[tuple[Codepoint, EffectiveWidth]]": + """Return a list of the codepoint/width pairs in this bucket, sorted by codepoint.""" + result = list(self.entry_set) + result.sort() + return result + + def width(self) -> "EffectiveWidth": + """If all codepoints in this bucket have the same width, return that width; otherwise, + return `None`.""" + if len(self.widths) == 0: + return None + potential_width = self.widths[0] + for width in self.widths[1:]: + if potential_width != width: + return None + return potential_width + + +def make_buckets(entries, low_bit: BitPos, cap_bit: BitPos) -> "list[Bucket]": + """Partitions the `(Codepoint, EffectiveWidth)` tuples in `entries` into `Bucket`s. All + codepoints with identical bits from `low_bit` to `cap_bit` (exclusive) are placed in the + same bucket. Returns a list of the buckets in increasing order of those bits.""" + num_bits = cap_bit - low_bit + assert num_bits > 0 + buckets = [Bucket() for _ in range(0, 2 ** num_bits)] + mask = (1 << num_bits) - 1 + for (codepoint, width) in entries: + buckets[(codepoint >> low_bit) & mask].append(codepoint, width) + return buckets + + +class Table: + """Represents a lookup table. Each table contains a certain number of subtables; each + subtable is indexed by a contiguous bit range of the codepoint and contains a list + of `2**(number of bits in bit range)` entries. (The bit range is the same for all subtables.) + + Typically, tables contain a list of buckets of codepoints. Bucket `i`'s codepoints should + be indexed by sub-table `i` in the next-level lookup table. The entries of this table are + indexes into the bucket list (~= indexes into the sub-tables of the next-level table.) The + key to compression is that two different buckets in two different sub-tables may have the + same width list, which means that they can be merged into the same bucket. + + If no bucket contains two codepoints with different widths, calling `indices_to_widths` will + discard the buckets and convert the entries into `EffectiveWidth` values.""" + + def __init__( + self, entry_groups, low_bit: BitPos, cap_bit: BitPos, offset_type: OffsetType + ): + """Create a lookup table with a sub-table for each `(Codepoint, EffectiveWidth)` iterator + in `entry_groups`. Each sub-table is indexed by codepoint bits in `low_bit..cap_bit`, + and each table entry is represented in the format specified by `offset_type`. Asserts + that this table is actually representable with `offset_type`.""" + self.low_bit = low_bit + self.cap_bit = cap_bit + self.offset_type = offset_type + self.entries = [] + self.indexed = [] + + buckets = [] + for entries in entry_groups: + buckets.extend(make_buckets(entries, self.low_bit, self.cap_bit)) + + for bucket in buckets: + for (i, existing) in enumerate(self.indexed): + if existing.try_extend(bucket): + self.entries.append(i) + break + else: + self.entries.append(len(self.indexed)) + self.indexed.append(bucket) + + # Validate offset type + for index in self.entries: + assert index < (1 << int(self.offset_type)) + + def indices_to_widths(self): + """Destructively converts the indices in this table to the `EffectiveWidth` values of + their buckets. Assumes that no bucket contains codepoints with different widths.""" + self.entries = list(map(lambda i: int(self.indexed[i].width()), self.entries)) + del self.indexed + + def buckets(self): + """Returns an iterator over this table's buckets.""" + return self.indexed + + def to_bytes(self) -> "list[int]": + """Returns this table's entries as a list of bytes. The bytes are formatted according to + the `OffsetType` which the table was created with, converting any `EffectiveWidth` entries + to their enum variant's integer value. For example, with `OffsetType.U2`, each byte will + contain four packed 2-bit entries.""" + entries_per_byte = 8 // int(self.offset_type) + byte_array = [] + for i in range(0, len(self.entries), entries_per_byte): + byte = 0 + for j in range(0, entries_per_byte): + byte |= self.entries[i + j] << (j * int(self.offset_type)) + byte_array.append(byte) + return byte_array + + +def make_tables( + table_cfgs: "list[tuple[BitPos, BitPos, OffsetType]]", entries +) -> "list[Table]": + """Creates a table for each configuration in `table_cfgs`, with the first config corresponding + to the top-level lookup table, the second config corresponding to the second-level lookup + table, and so forth. `entries` is an iterator over the `(Codepoint, EffectiveWidth)` pairs + to include in the top-level table.""" + tables = [] + entry_groups = [entries] + for (low_bit, cap_bit, offset_type) in table_cfgs: + table = Table(entry_groups, low_bit, cap_bit, offset_type) + entry_groups = map(lambda bucket: bucket.entries(), table.buckets()) + tables.append(table) + return tables + + +def emit_module( + out_name: str, unicode_version: "tuple[int, int, int]", tables: "list[Table]" +): + """Outputs a Rust module to `out_name` using table data from `tables`. + If `TABLE_CFGS` is edited, you may need to edit the included code for `lookup_width`.""" + if os.path.exists(out_name): + os.remove(out_name) + with open(out_name, "w", newline="\n", encoding="utf-8") as module: + module.write( + """// Copyright 2012-2022 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -31,291 +342,164 @@ preamble = '''// Copyright 2012-2015 The Rust Project Developers. See the COPYRI // except according to those terms. // NOTE: The following code was generated by "scripts/unicode.py", do not edit directly - -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] -''' - -# Mapping taken from Table 12 from: -# http://www.unicode.org/reports/tr44/#General_Category_Values -expanded_categories = { - 'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'], - 'Lm': ['L'], 'Lo': ['L'], - 'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'], - 'Nd': ['N'], 'Nl': ['N'], 'No': ['No'], - 'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'], - 'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'], - 'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'], - 'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'], - 'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'], -} - -# these are the surrogate codepoints, which are not valid rust characters -surrogate_codepoints = (0xd800, 0xdfff) - -def fetch(f): - if not os.path.exists(os.path.basename(f)): - os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s" - % f) - - if not os.path.exists(os.path.basename(f)): - sys.stderr.write("cannot load %s" % f) - exit(1) - -def is_surrogate(n): - return surrogate_codepoints[0] <= n <= surrogate_codepoints[1] - -def load_unicode_data(f): - fetch(f) - gencats = {} - - udict = {} - range_start = -1 - for line in fileinput.input(f): - data = line.split(';') - if len(data) != 15: - continue - cp = int(data[0], 16) - if is_surrogate(cp): - continue - if range_start >= 0: - for i in range(range_start, cp): - udict[i] = data - range_start = -1 - if data[1].endswith(", First>"): - range_start = cp - continue - udict[cp] = data - - for code in udict: - [code_org, name, gencat, combine, bidi, - decomp, deci, digit, num, mirror, - old, iso, upcase, lowcase, titlecase ] = udict[code] - - # place letter in categories as appropriate - for cat in [gencat, "Assigned"] + expanded_categories.get(gencat, []): - if cat not in gencats: - gencats[cat] = [] - gencats[cat].append(code) - - gencats = group_cats(gencats) - - return gencats - -def group_cats(cats): - cats_out = {} - for cat in cats: - cats_out[cat] = group_cat(cats[cat]) - return cats_out - -def group_cat(cat): - cat_out = [] - letters = sorted(set(cat)) - cur_start = letters.pop(0) - cur_end = cur_start - for letter in letters: - assert letter > cur_end, \ - "cur_end: %s, letter: %s" % (hex(cur_end), hex(letter)) - if letter == cur_end + 1: - cur_end = letter - else: - cat_out.append((cur_start, cur_end)) - cur_start = cur_end = letter - cat_out.append((cur_start, cur_end)) - return cat_out - -def format_table_content(f, content, indent): - line = " "*indent - first = True - for chunk in content.split(","): - if len(line) + len(chunk) < 98: - if first: - line += chunk - else: - line += ", " + chunk - first = False - else: - f.write(line + ",\n") - line = " "*indent + chunk - f.write(line) - -# load all widths of want_widths, except those in except_cats -def load_east_asian_width(want_widths, except_cats): - f = "EastAsianWidth.txt" - fetch(f) - widths = {} - re1 = re.compile("^([0-9A-F]+);(\w+) +# (\w+)") - re2 = re.compile("^([0-9A-F]+)\.\.([0-9A-F]+);(\w+) +# (\w+)") - - for line in fileinput.input(f): - width = None - d_lo = 0 - d_hi = 0 - cat = None - m = re1.match(line) - if m: - d_lo = m.group(1) - d_hi = m.group(1) - width = m.group(2) - cat = m.group(3) - else: - m = re2.match(line) - if m: - d_lo = m.group(1) - d_hi = m.group(2) - width = m.group(3) - cat = m.group(4) - else: - continue - if cat in except_cats or width not in want_widths: - continue - d_lo = int(d_lo, 16) - d_hi = int(d_hi, 16) - if width not in widths: - widths[width] = [] - widths[width].append((d_lo, d_hi)) - return widths - -def escape_char(c): - return "'\\u{%x}'" % c - -def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True, - pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1])), is_const=True): - pub_string = "const" - if not is_const: - pub_string = "let" - if is_pub: - pub_string = "pub " + pub_string - f.write(" %s %s: %s = &[\n" % (pub_string, name, t_type)) - data = "" - first = True - for dat in t_data: - if not first: - data += "," - first = False - data += pfun(dat) - format_table_content(f, data, 8) - f.write("\n ];\n\n") - -def emit_charwidth_module(f, width_table): - f.write("pub mod charwidth {") - f.write(""" - use core::option::Option::{self, Some, None}; - use core::result::Result::{Ok, Err}; - +""" + ) + module.write( + f""" +/// The version of [Unicode](http://www.unicode.org/) +/// that this version of unicode-width is based on. +pub const UNICODE_VERSION: (u8, u8, u8) = {unicode_version}; +""" + ) + + module.write( + """ +pub mod charwidth { + use core::option::Option::{self, None, Some}; + + /// Returns the [UAX #11](https://www.unicode.org/reports/tr11/) based width of `c` by + /// consulting a multi-level lookup table. + /// If `is_cjk == true`, ambiguous width characters are treated as double width; otherwise, + /// they're treated as single width. + /// + /// # Maintenance + /// The tables themselves are autogenerated but this function is hardcoded. You should have + /// nothing to worry about if you re-run `unicode.py` (for example, when updating Unicode.) + /// However, if you change the *actual structure* of the lookup tables (perhaps by editing the + /// `TABLE_CFGS` global in `unicode.py`) you must ensure that this code reflects those changes. #[inline] - fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 { - use core::cmp::Ordering::{Equal, Less, Greater}; - match r.binary_search_by(|&(lo, hi, _, _)| { - if lo <= c && c <= hi { Equal } - else if hi < c { Less } - else { Greater } - }) { - Ok(idx) => { - let (_, _, r_ncjk, r_cjk) = r[idx]; - if is_cjk { r_cjk } else { r_ncjk } + fn lookup_width(c: char, is_cjk: bool) -> usize { + let cp = c as usize; + + let t1_offset = TABLES_0[cp >> 13 & 0xFF]; + + // Each sub-table in TABLES_1 is 7 bits, and each stored entry is a byte, + // so each sub-table is 128 bytes in size. + // (Sub-tables are selected using the computed offset from the previous table.) + let t2_offset = TABLES_1[128 * usize::from(t1_offset) + (cp >> 6 & 0x7F)]; + + // Each sub-table in TABLES_2 is 6 bits, but each stored entry is 2 bits. + // This is accomplished by packing four stored entries into one byte. + // So each sub-table is 2**(6-2) == 16 bytes in size. + // Since this is the last table, each entry represents an encoded width. + let packed_widths = TABLES_2[16 * usize::from(t2_offset) + (cp >> 2 & 0xF)]; + + // Extract the packed width + let width = packed_widths >> (2 * (cp & 0b11)) & 0b11; + + // A width of 3 signifies that the codepoint is ambiguous width. + if width == 3 { + if is_cjk { + 2 + } else { + 1 } - Err(_) => 1 + } else { + width.into() } } -""") - - f.write(""" +""" + ) + + module.write( + """ + /// Returns the [UAX #11](https://www.unicode.org/reports/tr11/) based width of `c`, or + /// `None` if `c` is a control character other than `'\\x00'`. + /// If `is_cjk == true`, ambiguous width characters are treated as double width; otherwise, + /// they're treated as single width. #[inline] pub fn width(c: char, is_cjk: bool) -> Option { - match c as usize { - _c @ 0 => Some(0), // null is zero width - cu if cu < 0x20 => None, // control sequences have no width - cu if cu < 0x7F => Some(1), // ASCII - cu if cu < 0xA0 => None, // more control sequences - _ => Some(bsearch_range_value_table(c, is_cjk, charwidth_table) as usize) + if c < '\\u{7F}' { + if c >= '\\u{20}' { + // U+0020 to U+007F (exclusive) are single-width ASCII codepoints + Some(1) + } else if c == '\\0' { + // U+0000 *is* a control code, but it's special-cased + Some(0) + } else { + // U+0001 to U+0020 (exclusive) are control codes + None + } + } else if c >= '\\u{A0}' { + // No characters >= U+00A0 are control codes, so we can consult the lookup tables + Some(lookup_width(c, is_cjk)) + } else { + // U+007F to U+00A0 (exclusive) are control codes + None } } +""" + ) + + subtable_count = 1 + for (i, table) in enumerate(tables): + new_subtable_count = len(table.buckets()) + if i == len(tables) - 1: + table.indices_to_widths() # for the last table, indices == widths + byte_array = table.to_bytes() + module.write( + f""" + /// Autogenerated. {subtable_count} sub-table(s). Consult [`lookup_width`] for layout info. + static TABLES_{i}: [u8; {len(byte_array)}] = [""" + ) + for (j, byte) in enumerate(byte_array): + # Add line breaks for every 15th entry (chosen to match what rustfmt does) + if j % 15 == 0: + module.write("\n ") + module.write(f" 0x{byte:02X},") + module.write("\n ];\n") + subtable_count = new_subtable_count + module.write("}\n") + + +def main(module_filename: str): + """Obtain character data from the latest version of Unicode, transform it into a multi-level + lookup table for character width, and write a Rust module utilizing that table to + `module_filename`. + + We obey the following rules in decreasing order of importance: + - The soft hyphen (`U+00AD`) is single-width. + - Hangul Jamo medial vowels & final consonants (`U+1160..=U+11FF`) are zero-width. + - All codepoints in general categories `Cc`, `Cf`, `Mn`, and `Me` are zero-width. + - All codepoints with an East Asian Width of `Ambigous` are ambiguous-width. + - All codepoints with an East Asian Width of `Wide` or `Fullwidth` are double-width. + - All other codepoints (including unassigned codepoints and codepoints with an East Asian Width + of `Neutral`, `Narrow`, or `Halfwidth`) are single-width. + + These rules are based off of Markus Kuhn's free `wcwidth()` implementation: + http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c""" + version = load_unicode_version() + print(f"Generating module for Unicode {version[0]}.{version[1]}.{version[2]}") + + eaw_map = load_east_asian_widths() + zw_map = load_zero_widths() + + # Characters marked as zero-width in zw_map should be zero-width in the final map + width_map = list( + map(lambda x: EffectiveWidth.ZERO if x[1] else x[0], zip(eaw_map, zw_map)) + ) + + # Override for soft hyphen + width_map[0x00AD] = EffectiveWidth.NARROW + + # Override for Hangul Jamo medial vowels & final consonants + for i in range(0x1160, 0x11FF + 1): + width_map[i] = EffectiveWidth.ZERO + + tables = make_tables(TABLE_CFGS, enumerate(width_map)) + + print("------------------------") + total_size = 0 + for (i, table) in enumerate(tables): + size_bytes = len(table.to_bytes()) + print(f"Table {i} Size: {size_bytes} bytes") + total_size += size_bytes + print("------------------------") + print(f" Total Size: {total_size} bytes") + + emit_module(module_filename, version, tables) + print(f'Wrote to "{module_filename}"') -""") - - f.write(" // character width table. Based on Markus Kuhn's free wcwidth() implementation,\n") - f.write(" // http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c\n") - emit_table(f, "charwidth_table", width_table, "&'static [(char, char, u8, u8)]", is_pub=False, - pfun=lambda x: "(%s,%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2], x[3])) - f.write("}\n\n") - -def remove_from_wtable(wtable, val): - wtable_out = [] - while wtable: - if wtable[0][1] < val: - wtable_out.append(wtable.pop(0)) - elif wtable[0][0] > val: - break - else: - (wt_lo, wt_hi, width, width_cjk) = wtable.pop(0) - if wt_lo == wt_hi == val: - continue - elif wt_lo == val: - wtable_out.append((wt_lo+1, wt_hi, width, width_cjk)) - elif wt_hi == val: - wtable_out.append((wt_lo, wt_hi-1, width, width_cjk)) - else: - wtable_out.append((wt_lo, val-1, width, width_cjk)) - wtable_out.append((val+1, wt_hi, width, width_cjk)) - if wtable: - wtable_out.extend(wtable) - return wtable_out - - - -def optimize_width_table(wtable): - wtable_out = [] - w_this = wtable.pop(0) - while wtable: - if w_this[1] == wtable[0][0] - 1 and w_this[2:3] == wtable[0][2:3]: - w_tmp = wtable.pop(0) - w_this = (w_this[0], w_tmp[1], w_tmp[2], w_tmp[3]) - else: - wtable_out.append(w_this) - w_this = wtable.pop(0) - wtable_out.append(w_this) - return wtable_out if __name__ == "__main__": - r = "tables.rs" - if os.path.exists(r): - os.remove(r) - with open(r, "w") as rf: - # write the file's preamble - rf.write(preamble) - - # download and parse all the data - fetch("ReadMe.txt") - with open("ReadMe.txt") as readme: - pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode" - unicode_version = re.search(pattern, readme.read()).groups() - rf.write(""" -/// The version of [Unicode](http://www.unicode.org/) -/// that this version of unicode-width is based on. -pub const UNICODE_VERSION: (u8, u8, u8) = (%s, %s, %s); - -""" % unicode_version) - gencats = load_unicode_data("UnicodeData.txt") - - ### character width module - width_table = [] - for zwcat in ["Me", "Mn", "Cf"]: - width_table.extend([(lo_hi[0], lo_hi[1], 0, 0) for lo_hi in gencats[zwcat]]) - width_table.append((4448, 4607, 0, 0)) - - # get widths, except those that are explicitly marked zero-width above - ea_widths = load_east_asian_width(["W", "F", "A"], ["Me", "Mn", "Cf"]) - # these are doublewidth - for dwcat in ["W", "F"]: - width_table.extend([(lo_hi1[0], lo_hi1[1], 2, 2) for lo_hi1 in ea_widths[dwcat]]) - width_table.extend([(lo_hi2[0], lo_hi2[1], 1, 2) for lo_hi2 in ea_widths["A"]]) - - width_table.sort(key=lambda w: w[0]) - - # soft hyphen is not zero width in preformatted text; it's used to indicate - # a hyphen inserted to facilitate a linebreak. - width_table = remove_from_wtable(width_table, 173) - - # optimize the width table by collapsing adjacent entities when possible - width_table = optimize_width_table(width_table) - emit_charwidth_module(rf, width_table) + main(MODULE_FILENAME) diff --git a/vendor/unicode-width/src/tables.rs b/vendor/unicode-width/src/tables.rs index c0bb77d73..439c69c80 100644 --- a/vendor/unicode-width/src/tables.rs +++ b/vendor/unicode-width/src/tables.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2022 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,284 +10,531 @@ // NOTE: The following code was generated by "scripts/unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] - /// The version of [Unicode](http://www.unicode.org/) /// that this version of unicode-width is based on. -pub const UNICODE_VERSION: (u8, u8, u8) = (14, 0, 0); +pub const UNICODE_VERSION: (u8, u8, u8) = (15, 0, 0); pub mod charwidth { - use core::option::Option::{self, Some, None}; - use core::result::Result::{Ok, Err}; + use core::option::Option::{self, None, Some}; + /// Returns the [UAX #11](https://www.unicode.org/reports/tr11/) based width of `c` by + /// consulting a multi-level lookup table. + /// If `is_cjk == true`, ambiguous width characters are treated as double width; otherwise, + /// they're treated as single width. + /// + /// # Maintenance + /// The tables themselves are autogenerated but this function is hardcoded. You should have + /// nothing to worry about if you re-run `unicode.py` (for example, when updating Unicode.) + /// However, if you change the *actual structure* of the lookup tables (perhaps by editing the + /// `TABLE_CFGS` global in `unicode.py`) you must ensure that this code reflects those changes. #[inline] - fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 { - use core::cmp::Ordering::{Equal, Less, Greater}; - match r.binary_search_by(|&(lo, hi, _, _)| { - if lo <= c && c <= hi { Equal } - else if hi < c { Less } - else { Greater } - }) { - Ok(idx) => { - let (_, _, r_ncjk, r_cjk) = r[idx]; - if is_cjk { r_cjk } else { r_ncjk } + fn lookup_width(c: char, is_cjk: bool) -> usize { + let cp = c as usize; + + let t1_offset = TABLES_0[cp >> 13 & 0xFF]; + + // Each sub-table in TABLES_1 is 7 bits, and each stored entry is a byte, + // so each sub-table is 128 bytes in size. + // (Sub-tables are selected using the computed offset from the previous table.) + let t2_offset = TABLES_1[128 * usize::from(t1_offset) + (cp >> 6 & 0x7F)]; + + // Each sub-table in TABLES_2 is 6 bits, but each stored entry is 2 bits. + // This is accomplished by packing four stored entries into one byte. + // So each sub-table is 2**(6-2) == 16 bytes in size. + // Since this is the last table, each entry represents an encoded width. + let packed_widths = TABLES_2[16 * usize::from(t2_offset) + (cp >> 2 & 0xF)]; + + // Extract the packed width + let width = packed_widths >> (2 * (cp & 0b11)) & 0b11; + + // A width of 3 signifies that the codepoint is ambiguous width. + if width == 3 { + if is_cjk { + 2 + } else { + 1 } - Err(_) => 1 + } else { + width.into() } } + /// Returns the [UAX #11](https://www.unicode.org/reports/tr11/) based width of `c`, or + /// `None` if `c` is a control character other than `'\x00'`. + /// If `is_cjk == true`, ambiguous width characters are treated as double width; otherwise, + /// they're treated as single width. #[inline] pub fn width(c: char, is_cjk: bool) -> Option { - match c as usize { - _c @ 0 => Some(0), // null is zero width - cu if cu < 0x20 => None, // control sequences have no width - cu if cu < 0x7F => Some(1), // ASCII - cu if cu < 0xA0 => None, // more control sequences - _ => Some(bsearch_range_value_table(c, is_cjk, charwidth_table) as usize) + if c < '\u{7F}' { + if c >= '\u{20}' { + // U+0020 to U+007F (exclusive) are single-width ASCII codepoints + Some(1) + } else if c == '\0' { + // U+0000 *is* a control code, but it's special-cased + Some(0) + } else { + // U+0001 to U+0020 (exclusive) are control codes + None + } + } else if c >= '\u{A0}' { + // No characters >= U+00A0 are control codes, so we can consult the lookup tables + Some(lookup_width(c, is_cjk)) + } else { + // U+007F to U+00A0 (exclusive) are control codes + None } } - // character width table. Based on Markus Kuhn's free wcwidth() implementation, - // http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - const charwidth_table: &'static [(char, char, u8, u8)] = &[ - ('\u{a1}', '\u{a1}', 1, 2), ('\u{a4}', '\u{a4}', 1, 2), ('\u{a7}', '\u{a8}', 1, 2), - ('\u{aa}', '\u{aa}', 1, 2), ('\u{ae}', '\u{ae}', 1, 2), ('\u{b0}', '\u{b4}', 1, 2), - ('\u{b6}', '\u{ba}', 1, 2), ('\u{bc}', '\u{bf}', 1, 2), ('\u{c6}', '\u{c6}', 1, 2), - ('\u{d0}', '\u{d0}', 1, 2), ('\u{d7}', '\u{d8}', 1, 2), ('\u{de}', '\u{e1}', 1, 2), - ('\u{e6}', '\u{e6}', 1, 2), ('\u{e8}', '\u{ea}', 1, 2), ('\u{ec}', '\u{ed}', 1, 2), - ('\u{f0}', '\u{f0}', 1, 2), ('\u{f2}', '\u{f3}', 1, 2), ('\u{f7}', '\u{fa}', 1, 2), - ('\u{fc}', '\u{fc}', 1, 2), ('\u{fe}', '\u{fe}', 1, 2), ('\u{101}', '\u{101}', 1, 2), - ('\u{111}', '\u{111}', 1, 2), ('\u{113}', '\u{113}', 1, 2), ('\u{11b}', '\u{11b}', 1, 2), - ('\u{126}', '\u{127}', 1, 2), ('\u{12b}', '\u{12b}', 1, 2), ('\u{131}', '\u{133}', 1, 2), - ('\u{138}', '\u{138}', 1, 2), ('\u{13f}', '\u{142}', 1, 2), ('\u{144}', '\u{144}', 1, 2), - ('\u{148}', '\u{14b}', 1, 2), ('\u{14d}', '\u{14d}', 1, 2), ('\u{152}', '\u{153}', 1, 2), - ('\u{166}', '\u{167}', 1, 2), ('\u{16b}', '\u{16b}', 1, 2), ('\u{1ce}', '\u{1ce}', 1, 2), - ('\u{1d0}', '\u{1d0}', 1, 2), ('\u{1d2}', '\u{1d2}', 1, 2), ('\u{1d4}', '\u{1d4}', 1, 2), - ('\u{1d6}', '\u{1d6}', 1, 2), ('\u{1d8}', '\u{1d8}', 1, 2), ('\u{1da}', '\u{1da}', 1, 2), - ('\u{1dc}', '\u{1dc}', 1, 2), ('\u{251}', '\u{251}', 1, 2), ('\u{261}', '\u{261}', 1, 2), - ('\u{2c4}', '\u{2c4}', 1, 2), ('\u{2c7}', '\u{2c7}', 1, 2), ('\u{2c9}', '\u{2cb}', 1, 2), - ('\u{2cd}', '\u{2cd}', 1, 2), ('\u{2d0}', '\u{2d0}', 1, 2), ('\u{2d8}', '\u{2db}', 1, 2), - ('\u{2dd}', '\u{2dd}', 1, 2), ('\u{2df}', '\u{2df}', 1, 2), ('\u{300}', '\u{36f}', 0, 0), - ('\u{391}', '\u{3a1}', 1, 2), ('\u{3a3}', '\u{3a9}', 1, 2), ('\u{3b1}', '\u{3c1}', 1, 2), - ('\u{3c3}', '\u{3c9}', 1, 2), ('\u{401}', '\u{401}', 1, 2), ('\u{410}', '\u{44f}', 1, 2), - ('\u{451}', '\u{451}', 1, 2), ('\u{483}', '\u{489}', 0, 0), ('\u{591}', '\u{5bd}', 0, 0), - ('\u{5bf}', '\u{5bf}', 0, 0), ('\u{5c1}', '\u{5c2}', 0, 0), ('\u{5c4}', '\u{5c5}', 0, 0), - ('\u{5c7}', '\u{5c7}', 0, 0), ('\u{600}', '\u{605}', 0, 0), ('\u{610}', '\u{61a}', 0, 0), - ('\u{61c}', '\u{61c}', 0, 0), ('\u{64b}', '\u{65f}', 0, 0), ('\u{670}', '\u{670}', 0, 0), - ('\u{6d6}', '\u{6dd}', 0, 0), ('\u{6df}', '\u{6e4}', 0, 0), ('\u{6e7}', '\u{6e8}', 0, 0), - ('\u{6ea}', '\u{6ed}', 0, 0), ('\u{70f}', '\u{70f}', 0, 0), ('\u{711}', '\u{711}', 0, 0), - ('\u{730}', '\u{74a}', 0, 0), ('\u{7a6}', '\u{7b0}', 0, 0), ('\u{7eb}', '\u{7f3}', 0, 0), - ('\u{7fd}', '\u{7fd}', 0, 0), ('\u{816}', '\u{819}', 0, 0), ('\u{81b}', '\u{823}', 0, 0), - ('\u{825}', '\u{827}', 0, 0), ('\u{829}', '\u{82d}', 0, 0), ('\u{859}', '\u{85b}', 0, 0), - ('\u{890}', '\u{891}', 0, 0), ('\u{898}', '\u{89f}', 0, 0), ('\u{8ca}', '\u{902}', 0, 0), - ('\u{93a}', '\u{93a}', 0, 0), ('\u{93c}', '\u{93c}', 0, 0), ('\u{941}', '\u{948}', 0, 0), - ('\u{94d}', '\u{94d}', 0, 0), ('\u{951}', '\u{957}', 0, 0), ('\u{962}', '\u{963}', 0, 0), - ('\u{981}', '\u{981}', 0, 0), ('\u{9bc}', '\u{9bc}', 0, 0), ('\u{9c1}', '\u{9c4}', 0, 0), - ('\u{9cd}', '\u{9cd}', 0, 0), ('\u{9e2}', '\u{9e3}', 0, 0), ('\u{9fe}', '\u{9fe}', 0, 0), - ('\u{a01}', '\u{a02}', 0, 0), ('\u{a3c}', '\u{a3c}', 0, 0), ('\u{a41}', '\u{a42}', 0, 0), - ('\u{a47}', '\u{a48}', 0, 0), ('\u{a4b}', '\u{a4d}', 0, 0), ('\u{a51}', '\u{a51}', 0, 0), - ('\u{a70}', '\u{a71}', 0, 0), ('\u{a75}', '\u{a75}', 0, 0), ('\u{a81}', '\u{a82}', 0, 0), - ('\u{abc}', '\u{abc}', 0, 0), ('\u{ac1}', '\u{ac5}', 0, 0), ('\u{ac7}', '\u{ac8}', 0, 0), - ('\u{acd}', '\u{acd}', 0, 0), ('\u{ae2}', '\u{ae3}', 0, 0), ('\u{afa}', '\u{aff}', 0, 0), - ('\u{b01}', '\u{b01}', 0, 0), ('\u{b3c}', '\u{b3c}', 0, 0), ('\u{b3f}', '\u{b3f}', 0, 0), - ('\u{b41}', '\u{b44}', 0, 0), ('\u{b4d}', '\u{b4d}', 0, 0), ('\u{b55}', '\u{b56}', 0, 0), - ('\u{b62}', '\u{b63}', 0, 0), ('\u{b82}', '\u{b82}', 0, 0), ('\u{bc0}', '\u{bc0}', 0, 0), - ('\u{bcd}', '\u{bcd}', 0, 0), ('\u{c00}', '\u{c00}', 0, 0), ('\u{c04}', '\u{c04}', 0, 0), - ('\u{c3c}', '\u{c3c}', 0, 0), ('\u{c3e}', '\u{c40}', 0, 0), ('\u{c46}', '\u{c48}', 0, 0), - ('\u{c4a}', '\u{c4d}', 0, 0), ('\u{c55}', '\u{c56}', 0, 0), ('\u{c62}', '\u{c63}', 0, 0), - ('\u{c81}', '\u{c81}', 0, 0), ('\u{cbc}', '\u{cbc}', 0, 0), ('\u{cbf}', '\u{cbf}', 0, 0), - ('\u{cc6}', '\u{cc6}', 0, 0), ('\u{ccc}', '\u{ccd}', 0, 0), ('\u{ce2}', '\u{ce3}', 0, 0), - ('\u{d00}', '\u{d01}', 0, 0), ('\u{d3b}', '\u{d3c}', 0, 0), ('\u{d41}', '\u{d44}', 0, 0), - ('\u{d4d}', '\u{d4d}', 0, 0), ('\u{d62}', '\u{d63}', 0, 0), ('\u{d81}', '\u{d81}', 0, 0), - ('\u{dca}', '\u{dca}', 0, 0), ('\u{dd2}', '\u{dd4}', 0, 0), ('\u{dd6}', '\u{dd6}', 0, 0), - ('\u{e31}', '\u{e31}', 0, 0), ('\u{e34}', '\u{e3a}', 0, 0), ('\u{e47}', '\u{e4e}', 0, 0), - ('\u{eb1}', '\u{eb1}', 0, 0), ('\u{eb4}', '\u{ebc}', 0, 0), ('\u{ec8}', '\u{ecd}', 0, 0), - ('\u{f18}', '\u{f19}', 0, 0), ('\u{f35}', '\u{f35}', 0, 0), ('\u{f37}', '\u{f37}', 0, 0), - ('\u{f39}', '\u{f39}', 0, 0), ('\u{f71}', '\u{f7e}', 0, 0), ('\u{f80}', '\u{f84}', 0, 0), - ('\u{f86}', '\u{f87}', 0, 0), ('\u{f8d}', '\u{f97}', 0, 0), ('\u{f99}', '\u{fbc}', 0, 0), - ('\u{fc6}', '\u{fc6}', 0, 0), ('\u{102d}', '\u{1030}', 0, 0), ('\u{1032}', '\u{1037}', 0, - 0), ('\u{1039}', '\u{103a}', 0, 0), ('\u{103d}', '\u{103e}', 0, 0), ('\u{1058}', '\u{1059}', - 0, 0), ('\u{105e}', '\u{1060}', 0, 0), ('\u{1071}', '\u{1074}', 0, 0), ('\u{1082}', - '\u{1082}', 0, 0), ('\u{1085}', '\u{1086}', 0, 0), ('\u{108d}', '\u{108d}', 0, 0), - ('\u{109d}', '\u{109d}', 0, 0), ('\u{1100}', '\u{115f}', 2, 2), ('\u{1160}', '\u{11ff}', 0, - 0), ('\u{135d}', '\u{135f}', 0, 0), ('\u{1712}', '\u{1714}', 0, 0), ('\u{1732}', '\u{1733}', - 0, 0), ('\u{1752}', '\u{1753}', 0, 0), ('\u{1772}', '\u{1773}', 0, 0), ('\u{17b4}', - '\u{17b5}', 0, 0), ('\u{17b7}', '\u{17bd}', 0, 0), ('\u{17c6}', '\u{17c6}', 0, 0), - ('\u{17c9}', '\u{17d3}', 0, 0), ('\u{17dd}', '\u{17dd}', 0, 0), ('\u{180b}', '\u{180f}', 0, - 0), ('\u{1885}', '\u{1886}', 0, 0), ('\u{18a9}', '\u{18a9}', 0, 0), ('\u{1920}', '\u{1922}', - 0, 0), ('\u{1927}', '\u{1928}', 0, 0), ('\u{1932}', '\u{1932}', 0, 0), ('\u{1939}', - '\u{193b}', 0, 0), ('\u{1a17}', '\u{1a18}', 0, 0), ('\u{1a1b}', '\u{1a1b}', 0, 0), - ('\u{1a56}', '\u{1a56}', 0, 0), ('\u{1a58}', '\u{1a5e}', 0, 0), ('\u{1a60}', '\u{1a60}', 0, - 0), ('\u{1a62}', '\u{1a62}', 0, 0), ('\u{1a65}', '\u{1a6c}', 0, 0), ('\u{1a73}', '\u{1a7c}', - 0, 0), ('\u{1a7f}', '\u{1a7f}', 0, 0), ('\u{1ab0}', '\u{1ace}', 0, 0), ('\u{1b00}', - '\u{1b03}', 0, 0), ('\u{1b34}', '\u{1b34}', 0, 0), ('\u{1b36}', '\u{1b3a}', 0, 0), - ('\u{1b3c}', '\u{1b3c}', 0, 0), ('\u{1b42}', '\u{1b42}', 0, 0), ('\u{1b6b}', '\u{1b73}', 0, - 0), ('\u{1b80}', '\u{1b81}', 0, 0), ('\u{1ba2}', '\u{1ba5}', 0, 0), ('\u{1ba8}', '\u{1ba9}', - 0, 0), ('\u{1bab}', '\u{1bad}', 0, 0), ('\u{1be6}', '\u{1be6}', 0, 0), ('\u{1be8}', - '\u{1be9}', 0, 0), ('\u{1bed}', '\u{1bed}', 0, 0), ('\u{1bef}', '\u{1bf1}', 0, 0), - ('\u{1c2c}', '\u{1c33}', 0, 0), ('\u{1c36}', '\u{1c37}', 0, 0), ('\u{1cd0}', '\u{1cd2}', 0, - 0), ('\u{1cd4}', '\u{1ce0}', 0, 0), ('\u{1ce2}', '\u{1ce8}', 0, 0), ('\u{1ced}', '\u{1ced}', - 0, 0), ('\u{1cf4}', '\u{1cf4}', 0, 0), ('\u{1cf8}', '\u{1cf9}', 0, 0), ('\u{1dc0}', - '\u{1dff}', 0, 0), ('\u{200b}', '\u{200f}', 0, 0), ('\u{2010}', '\u{2010}', 1, 2), - ('\u{2013}', '\u{2016}', 1, 2), ('\u{2018}', '\u{2019}', 1, 2), ('\u{201c}', '\u{201d}', 1, - 2), ('\u{2020}', '\u{2022}', 1, 2), ('\u{2024}', '\u{2027}', 1, 2), ('\u{202a}', '\u{202e}', - 0, 0), ('\u{2030}', '\u{2030}', 1, 2), ('\u{2032}', '\u{2033}', 1, 2), ('\u{2035}', - '\u{2035}', 1, 2), ('\u{203b}', '\u{203b}', 1, 2), ('\u{203e}', '\u{203e}', 1, 2), - ('\u{2060}', '\u{2064}', 0, 0), ('\u{2066}', '\u{206f}', 0, 0), ('\u{2074}', '\u{2074}', 1, - 2), ('\u{207f}', '\u{207f}', 1, 2), ('\u{2081}', '\u{2084}', 1, 2), ('\u{20ac}', '\u{20ac}', - 1, 2), ('\u{20d0}', '\u{20f0}', 0, 0), ('\u{2103}', '\u{2103}', 1, 2), ('\u{2105}', - '\u{2105}', 1, 2), ('\u{2109}', '\u{2109}', 1, 2), ('\u{2113}', '\u{2113}', 1, 2), - ('\u{2116}', '\u{2116}', 1, 2), ('\u{2121}', '\u{2122}', 1, 2), ('\u{2126}', '\u{2126}', 1, - 2), ('\u{212b}', '\u{212b}', 1, 2), ('\u{2153}', '\u{2154}', 1, 2), ('\u{215b}', '\u{215e}', - 1, 2), ('\u{2160}', '\u{216b}', 1, 2), ('\u{2170}', '\u{2179}', 1, 2), ('\u{2189}', - '\u{2189}', 1, 2), ('\u{2190}', '\u{2199}', 1, 2), ('\u{21b8}', '\u{21b9}', 1, 2), - ('\u{21d2}', '\u{21d2}', 1, 2), ('\u{21d4}', '\u{21d4}', 1, 2), ('\u{21e7}', '\u{21e7}', 1, - 2), ('\u{2200}', '\u{2200}', 1, 2), ('\u{2202}', '\u{2203}', 1, 2), ('\u{2207}', '\u{2208}', - 1, 2), ('\u{220b}', '\u{220b}', 1, 2), ('\u{220f}', '\u{220f}', 1, 2), ('\u{2211}', - '\u{2211}', 1, 2), ('\u{2215}', '\u{2215}', 1, 2), ('\u{221a}', '\u{221a}', 1, 2), - ('\u{221d}', '\u{2220}', 1, 2), ('\u{2223}', '\u{2223}', 1, 2), ('\u{2225}', '\u{2225}', 1, - 2), ('\u{2227}', '\u{222c}', 1, 2), ('\u{222e}', '\u{222e}', 1, 2), ('\u{2234}', '\u{2237}', - 1, 2), ('\u{223c}', '\u{223d}', 1, 2), ('\u{2248}', '\u{2248}', 1, 2), ('\u{224c}', - '\u{224c}', 1, 2), ('\u{2252}', '\u{2252}', 1, 2), ('\u{2260}', '\u{2261}', 1, 2), - ('\u{2264}', '\u{2267}', 1, 2), ('\u{226a}', '\u{226b}', 1, 2), ('\u{226e}', '\u{226f}', 1, - 2), ('\u{2282}', '\u{2283}', 1, 2), ('\u{2286}', '\u{2287}', 1, 2), ('\u{2295}', '\u{2295}', - 1, 2), ('\u{2299}', '\u{2299}', 1, 2), ('\u{22a5}', '\u{22a5}', 1, 2), ('\u{22bf}', - '\u{22bf}', 1, 2), ('\u{2312}', '\u{2312}', 1, 2), ('\u{231a}', '\u{231b}', 2, 2), - ('\u{2329}', '\u{232a}', 2, 2), ('\u{23e9}', '\u{23ec}', 2, 2), ('\u{23f0}', '\u{23f0}', 2, - 2), ('\u{23f3}', '\u{23f3}', 2, 2), ('\u{2460}', '\u{24e9}', 1, 2), ('\u{24eb}', '\u{254b}', - 1, 2), ('\u{2550}', '\u{2573}', 1, 2), ('\u{2580}', '\u{258f}', 1, 2), ('\u{2592}', - '\u{2595}', 1, 2), ('\u{25a0}', '\u{25a1}', 1, 2), ('\u{25a3}', '\u{25a9}', 1, 2), - ('\u{25b2}', '\u{25b3}', 1, 2), ('\u{25b6}', '\u{25b7}', 1, 2), ('\u{25bc}', '\u{25bd}', 1, - 2), ('\u{25c0}', '\u{25c1}', 1, 2), ('\u{25c6}', '\u{25c8}', 1, 2), ('\u{25cb}', '\u{25cb}', - 1, 2), ('\u{25ce}', '\u{25d1}', 1, 2), ('\u{25e2}', '\u{25e5}', 1, 2), ('\u{25ef}', - '\u{25ef}', 1, 2), ('\u{25fd}', '\u{25fe}', 2, 2), ('\u{2605}', '\u{2606}', 1, 2), - ('\u{2609}', '\u{2609}', 1, 2), ('\u{260e}', '\u{260f}', 1, 2), ('\u{2614}', '\u{2615}', 2, - 2), ('\u{261c}', '\u{261c}', 1, 2), ('\u{261e}', '\u{261e}', 1, 2), ('\u{2640}', '\u{2640}', - 1, 2), ('\u{2642}', '\u{2642}', 1, 2), ('\u{2648}', '\u{2653}', 2, 2), ('\u{2660}', - '\u{2661}', 1, 2), ('\u{2663}', '\u{2665}', 1, 2), ('\u{2667}', '\u{266a}', 1, 2), - ('\u{266c}', '\u{266d}', 1, 2), ('\u{266f}', '\u{266f}', 1, 2), ('\u{267f}', '\u{267f}', 2, - 2), ('\u{2693}', '\u{2693}', 2, 2), ('\u{269e}', '\u{269f}', 1, 2), ('\u{26a1}', '\u{26a1}', - 2, 2), ('\u{26aa}', '\u{26ab}', 2, 2), ('\u{26bd}', '\u{26be}', 2, 2), ('\u{26bf}', - '\u{26bf}', 1, 2), ('\u{26c4}', '\u{26c5}', 2, 2), ('\u{26c6}', '\u{26cd}', 1, 2), - ('\u{26ce}', '\u{26ce}', 2, 2), ('\u{26cf}', '\u{26d3}', 1, 2), ('\u{26d4}', '\u{26d4}', 2, - 2), ('\u{26d5}', '\u{26e1}', 1, 2), ('\u{26e3}', '\u{26e3}', 1, 2), ('\u{26e8}', '\u{26e9}', - 1, 2), ('\u{26ea}', '\u{26ea}', 2, 2), ('\u{26eb}', '\u{26f1}', 1, 2), ('\u{26f2}', - '\u{26f3}', 2, 2), ('\u{26f4}', '\u{26f4}', 1, 2), ('\u{26f5}', '\u{26f5}', 2, 2), - ('\u{26f6}', '\u{26f9}', 1, 2), ('\u{26fa}', '\u{26fa}', 2, 2), ('\u{26fb}', '\u{26fc}', 1, - 2), ('\u{26fd}', '\u{26fd}', 2, 2), ('\u{26fe}', '\u{26ff}', 1, 2), ('\u{2705}', '\u{2705}', - 2, 2), ('\u{270a}', '\u{270b}', 2, 2), ('\u{2728}', '\u{2728}', 2, 2), ('\u{273d}', - '\u{273d}', 1, 2), ('\u{274c}', '\u{274c}', 2, 2), ('\u{274e}', '\u{274e}', 2, 2), - ('\u{2753}', '\u{2755}', 2, 2), ('\u{2757}', '\u{2757}', 2, 2), ('\u{2776}', '\u{277f}', 1, - 2), ('\u{2795}', '\u{2797}', 2, 2), ('\u{27b0}', '\u{27b0}', 2, 2), ('\u{27bf}', '\u{27bf}', - 2, 2), ('\u{2b1b}', '\u{2b1c}', 2, 2), ('\u{2b50}', '\u{2b50}', 2, 2), ('\u{2b55}', - '\u{2b55}', 2, 2), ('\u{2b56}', '\u{2b59}', 1, 2), ('\u{2cef}', '\u{2cf1}', 0, 0), - ('\u{2d7f}', '\u{2d7f}', 0, 0), ('\u{2de0}', '\u{2dff}', 0, 0), ('\u{2e80}', '\u{2e99}', 2, - 2), ('\u{2e9b}', '\u{2ef3}', 2, 2), ('\u{2f00}', '\u{2fd5}', 2, 2), ('\u{2ff0}', '\u{2ffb}', - 2, 2), ('\u{3000}', '\u{3029}', 2, 2), ('\u{302a}', '\u{302d}', 0, 0), ('\u{302e}', - '\u{303e}', 2, 2), ('\u{3041}', '\u{3096}', 2, 2), ('\u{3099}', '\u{309a}', 0, 0), - ('\u{309b}', '\u{30ff}', 2, 2), ('\u{3105}', '\u{312f}', 2, 2), ('\u{3131}', '\u{318e}', 2, - 2), ('\u{3190}', '\u{31e3}', 2, 2), ('\u{31f0}', '\u{321e}', 2, 2), ('\u{3220}', '\u{3247}', - 2, 2), ('\u{3248}', '\u{324f}', 1, 2), ('\u{3250}', '\u{4dbf}', 2, 2), ('\u{4e00}', - '\u{a48c}', 2, 2), ('\u{a490}', '\u{a4c6}', 2, 2), ('\u{a66f}', '\u{a672}', 0, 0), - ('\u{a674}', '\u{a67d}', 0, 0), ('\u{a69e}', '\u{a69f}', 0, 0), ('\u{a6f0}', '\u{a6f1}', 0, - 0), ('\u{a802}', '\u{a802}', 0, 0), ('\u{a806}', '\u{a806}', 0, 0), ('\u{a80b}', '\u{a80b}', - 0, 0), ('\u{a825}', '\u{a826}', 0, 0), ('\u{a82c}', '\u{a82c}', 0, 0), ('\u{a8c4}', - '\u{a8c5}', 0, 0), ('\u{a8e0}', '\u{a8f1}', 0, 0), ('\u{a8ff}', '\u{a8ff}', 0, 0), - ('\u{a926}', '\u{a92d}', 0, 0), ('\u{a947}', '\u{a951}', 0, 0), ('\u{a960}', '\u{a97c}', 2, - 2), ('\u{a980}', '\u{a982}', 0, 0), ('\u{a9b3}', '\u{a9b3}', 0, 0), ('\u{a9b6}', '\u{a9b9}', - 0, 0), ('\u{a9bc}', '\u{a9bd}', 0, 0), ('\u{a9e5}', '\u{a9e5}', 0, 0), ('\u{aa29}', - '\u{aa2e}', 0, 0), ('\u{aa31}', '\u{aa32}', 0, 0), ('\u{aa35}', '\u{aa36}', 0, 0), - ('\u{aa43}', '\u{aa43}', 0, 0), ('\u{aa4c}', '\u{aa4c}', 0, 0), ('\u{aa7c}', '\u{aa7c}', 0, - 0), ('\u{aab0}', '\u{aab0}', 0, 0), ('\u{aab2}', '\u{aab4}', 0, 0), ('\u{aab7}', '\u{aab8}', - 0, 0), ('\u{aabe}', '\u{aabf}', 0, 0), ('\u{aac1}', '\u{aac1}', 0, 0), ('\u{aaec}', - '\u{aaed}', 0, 0), ('\u{aaf6}', '\u{aaf6}', 0, 0), ('\u{abe5}', '\u{abe5}', 0, 0), - ('\u{abe8}', '\u{abe8}', 0, 0), ('\u{abed}', '\u{abed}', 0, 0), ('\u{ac00}', '\u{d7a3}', 2, - 2), ('\u{e000}', '\u{f8ff}', 1, 2), ('\u{f900}', '\u{faff}', 2, 2), ('\u{fb1e}', '\u{fb1e}', - 0, 0), ('\u{fe00}', '\u{fe0f}', 0, 0), ('\u{fe10}', '\u{fe19}', 2, 2), ('\u{fe20}', - '\u{fe2f}', 0, 0), ('\u{fe30}', '\u{fe52}', 2, 2), ('\u{fe54}', '\u{fe66}', 2, 2), - ('\u{fe68}', '\u{fe6b}', 2, 2), ('\u{feff}', '\u{feff}', 0, 0), ('\u{ff01}', '\u{ff60}', 2, - 2), ('\u{ffe0}', '\u{ffe6}', 2, 2), ('\u{fff9}', '\u{fffb}', 0, 0), ('\u{fffd}', '\u{fffd}', - 1, 2), ('\u{101fd}', '\u{101fd}', 0, 0), ('\u{102e0}', '\u{102e0}', 0, 0), ('\u{10376}', - '\u{1037a}', 0, 0), ('\u{10a01}', '\u{10a03}', 0, 0), ('\u{10a05}', '\u{10a06}', 0, 0), - ('\u{10a0c}', '\u{10a0f}', 0, 0), ('\u{10a38}', '\u{10a3a}', 0, 0), ('\u{10a3f}', - '\u{10a3f}', 0, 0), ('\u{10ae5}', '\u{10ae6}', 0, 0), ('\u{10d24}', '\u{10d27}', 0, 0), - ('\u{10eab}', '\u{10eac}', 0, 0), ('\u{10f46}', '\u{10f50}', 0, 0), ('\u{10f82}', - '\u{10f85}', 0, 0), ('\u{11001}', '\u{11001}', 0, 0), ('\u{11038}', '\u{11046}', 0, 0), - ('\u{11070}', '\u{11070}', 0, 0), ('\u{11073}', '\u{11074}', 0, 0), ('\u{1107f}', - '\u{11081}', 0, 0), ('\u{110b3}', '\u{110b6}', 0, 0), ('\u{110b9}', '\u{110ba}', 0, 0), - ('\u{110bd}', '\u{110bd}', 0, 0), ('\u{110c2}', '\u{110c2}', 0, 0), ('\u{110cd}', - '\u{110cd}', 0, 0), ('\u{11100}', '\u{11102}', 0, 0), ('\u{11127}', '\u{1112b}', 0, 0), - ('\u{1112d}', '\u{11134}', 0, 0), ('\u{11173}', '\u{11173}', 0, 0), ('\u{11180}', - '\u{11181}', 0, 0), ('\u{111b6}', '\u{111be}', 0, 0), ('\u{111c9}', '\u{111cc}', 0, 0), - ('\u{111cf}', '\u{111cf}', 0, 0), ('\u{1122f}', '\u{11231}', 0, 0), ('\u{11234}', - '\u{11234}', 0, 0), ('\u{11236}', '\u{11237}', 0, 0), ('\u{1123e}', '\u{1123e}', 0, 0), - ('\u{112df}', '\u{112df}', 0, 0), ('\u{112e3}', '\u{112ea}', 0, 0), ('\u{11300}', - '\u{11301}', 0, 0), ('\u{1133b}', '\u{1133c}', 0, 0), ('\u{11340}', '\u{11340}', 0, 0), - ('\u{11366}', '\u{1136c}', 0, 0), ('\u{11370}', '\u{11374}', 0, 0), ('\u{11438}', - '\u{1143f}', 0, 0), ('\u{11442}', '\u{11444}', 0, 0), ('\u{11446}', '\u{11446}', 0, 0), - ('\u{1145e}', '\u{1145e}', 0, 0), ('\u{114b3}', '\u{114b8}', 0, 0), ('\u{114ba}', - '\u{114ba}', 0, 0), ('\u{114bf}', '\u{114c0}', 0, 0), ('\u{114c2}', '\u{114c3}', 0, 0), - ('\u{115b2}', '\u{115b5}', 0, 0), ('\u{115bc}', '\u{115bd}', 0, 0), ('\u{115bf}', - '\u{115c0}', 0, 0), ('\u{115dc}', '\u{115dd}', 0, 0), ('\u{11633}', '\u{1163a}', 0, 0), - ('\u{1163d}', '\u{1163d}', 0, 0), ('\u{1163f}', '\u{11640}', 0, 0), ('\u{116ab}', - '\u{116ab}', 0, 0), ('\u{116ad}', '\u{116ad}', 0, 0), ('\u{116b0}', '\u{116b5}', 0, 0), - ('\u{116b7}', '\u{116b7}', 0, 0), ('\u{1171d}', '\u{1171f}', 0, 0), ('\u{11722}', - '\u{11725}', 0, 0), ('\u{11727}', '\u{1172b}', 0, 0), ('\u{1182f}', '\u{11837}', 0, 0), - ('\u{11839}', '\u{1183a}', 0, 0), ('\u{1193b}', '\u{1193c}', 0, 0), ('\u{1193e}', - '\u{1193e}', 0, 0), ('\u{11943}', '\u{11943}', 0, 0), ('\u{119d4}', '\u{119d7}', 0, 0), - ('\u{119da}', '\u{119db}', 0, 0), ('\u{119e0}', '\u{119e0}', 0, 0), ('\u{11a01}', - '\u{11a0a}', 0, 0), ('\u{11a33}', '\u{11a38}', 0, 0), ('\u{11a3b}', '\u{11a3e}', 0, 0), - ('\u{11a47}', '\u{11a47}', 0, 0), ('\u{11a51}', '\u{11a56}', 0, 0), ('\u{11a59}', - '\u{11a5b}', 0, 0), ('\u{11a8a}', '\u{11a96}', 0, 0), ('\u{11a98}', '\u{11a99}', 0, 0), - ('\u{11c30}', '\u{11c36}', 0, 0), ('\u{11c38}', '\u{11c3d}', 0, 0), ('\u{11c3f}', - '\u{11c3f}', 0, 0), ('\u{11c92}', '\u{11ca7}', 0, 0), ('\u{11caa}', '\u{11cb0}', 0, 0), - ('\u{11cb2}', '\u{11cb3}', 0, 0), ('\u{11cb5}', '\u{11cb6}', 0, 0), ('\u{11d31}', - '\u{11d36}', 0, 0), ('\u{11d3a}', '\u{11d3a}', 0, 0), ('\u{11d3c}', '\u{11d3d}', 0, 0), - ('\u{11d3f}', '\u{11d45}', 0, 0), ('\u{11d47}', '\u{11d47}', 0, 0), ('\u{11d90}', - '\u{11d91}', 0, 0), ('\u{11d95}', '\u{11d95}', 0, 0), ('\u{11d97}', '\u{11d97}', 0, 0), - ('\u{11ef3}', '\u{11ef4}', 0, 0), ('\u{13430}', '\u{13438}', 0, 0), ('\u{16af0}', - '\u{16af4}', 0, 0), ('\u{16b30}', '\u{16b36}', 0, 0), ('\u{16f4f}', '\u{16f4f}', 0, 0), - ('\u{16f8f}', '\u{16f92}', 0, 0), ('\u{16fe0}', '\u{16fe3}', 2, 2), ('\u{16fe4}', - '\u{16fe4}', 0, 0), ('\u{16ff0}', '\u{16ff1}', 2, 2), ('\u{17000}', '\u{187f7}', 2, 2), - ('\u{18800}', '\u{18cd5}', 2, 2), ('\u{18d00}', '\u{18d08}', 2, 2), ('\u{1aff0}', - '\u{1aff3}', 2, 2), ('\u{1aff5}', '\u{1affb}', 2, 2), ('\u{1affd}', '\u{1affe}', 2, 2), - ('\u{1b000}', '\u{1b122}', 2, 2), ('\u{1b150}', '\u{1b152}', 2, 2), ('\u{1b164}', - '\u{1b167}', 2, 2), ('\u{1b170}', '\u{1b2fb}', 2, 2), ('\u{1bc9d}', '\u{1bc9e}', 0, 0), - ('\u{1bca0}', '\u{1bca3}', 0, 0), ('\u{1cf00}', '\u{1cf2d}', 0, 0), ('\u{1cf30}', - '\u{1cf46}', 0, 0), ('\u{1d167}', '\u{1d169}', 0, 0), ('\u{1d173}', '\u{1d182}', 0, 0), - ('\u{1d185}', '\u{1d18b}', 0, 0), ('\u{1d1aa}', '\u{1d1ad}', 0, 0), ('\u{1d242}', - '\u{1d244}', 0, 0), ('\u{1da00}', '\u{1da36}', 0, 0), ('\u{1da3b}', '\u{1da6c}', 0, 0), - ('\u{1da75}', '\u{1da75}', 0, 0), ('\u{1da84}', '\u{1da84}', 0, 0), ('\u{1da9b}', - '\u{1da9f}', 0, 0), ('\u{1daa1}', '\u{1daaf}', 0, 0), ('\u{1e000}', '\u{1e006}', 0, 0), - ('\u{1e008}', '\u{1e018}', 0, 0), ('\u{1e01b}', '\u{1e021}', 0, 0), ('\u{1e023}', - '\u{1e024}', 0, 0), ('\u{1e026}', '\u{1e02a}', 0, 0), ('\u{1e130}', '\u{1e136}', 0, 0), - ('\u{1e2ae}', '\u{1e2ae}', 0, 0), ('\u{1e2ec}', '\u{1e2ef}', 0, 0), ('\u{1e8d0}', - '\u{1e8d6}', 0, 0), ('\u{1e944}', '\u{1e94a}', 0, 0), ('\u{1f004}', '\u{1f004}', 2, 2), - ('\u{1f0cf}', '\u{1f0cf}', 2, 2), ('\u{1f100}', '\u{1f10a}', 1, 2), ('\u{1f110}', - '\u{1f12d}', 1, 2), ('\u{1f130}', '\u{1f169}', 1, 2), ('\u{1f170}', '\u{1f18d}', 1, 2), - ('\u{1f18e}', '\u{1f18e}', 2, 2), ('\u{1f18f}', '\u{1f190}', 1, 2), ('\u{1f191}', - '\u{1f19a}', 2, 2), ('\u{1f19b}', '\u{1f1ac}', 1, 2), ('\u{1f200}', '\u{1f202}', 2, 2), - ('\u{1f210}', '\u{1f23b}', 2, 2), ('\u{1f240}', '\u{1f248}', 2, 2), ('\u{1f250}', - '\u{1f251}', 2, 2), ('\u{1f260}', '\u{1f265}', 2, 2), ('\u{1f300}', '\u{1f320}', 2, 2), - ('\u{1f32d}', '\u{1f335}', 2, 2), ('\u{1f337}', '\u{1f37c}', 2, 2), ('\u{1f37e}', - '\u{1f393}', 2, 2), ('\u{1f3a0}', '\u{1f3ca}', 2, 2), ('\u{1f3cf}', '\u{1f3d3}', 2, 2), - ('\u{1f3e0}', '\u{1f3f0}', 2, 2), ('\u{1f3f4}', '\u{1f3f4}', 2, 2), ('\u{1f3f8}', - '\u{1f43e}', 2, 2), ('\u{1f440}', '\u{1f440}', 2, 2), ('\u{1f442}', '\u{1f4fc}', 2, 2), - ('\u{1f4ff}', '\u{1f53d}', 2, 2), ('\u{1f54b}', '\u{1f54e}', 2, 2), ('\u{1f550}', - '\u{1f567}', 2, 2), ('\u{1f57a}', '\u{1f57a}', 2, 2), ('\u{1f595}', '\u{1f596}', 2, 2), - ('\u{1f5a4}', '\u{1f5a4}', 2, 2), ('\u{1f5fb}', '\u{1f64f}', 2, 2), ('\u{1f680}', - '\u{1f6c5}', 2, 2), ('\u{1f6cc}', '\u{1f6cc}', 2, 2), ('\u{1f6d0}', '\u{1f6d2}', 2, 2), - ('\u{1f6d5}', '\u{1f6d7}', 2, 2), ('\u{1f6dd}', '\u{1f6df}', 2, 2), ('\u{1f6eb}', - '\u{1f6ec}', 2, 2), ('\u{1f6f4}', '\u{1f6fc}', 2, 2), ('\u{1f7e0}', '\u{1f7eb}', 2, 2), - ('\u{1f7f0}', '\u{1f7f0}', 2, 2), ('\u{1f90c}', '\u{1f93a}', 2, 2), ('\u{1f93c}', - '\u{1f945}', 2, 2), ('\u{1f947}', '\u{1f9ff}', 2, 2), ('\u{1fa70}', '\u{1fa74}', 2, 2), - ('\u{1fa78}', '\u{1fa7c}', 2, 2), ('\u{1fa80}', '\u{1fa86}', 2, 2), ('\u{1fa90}', - '\u{1faac}', 2, 2), ('\u{1fab0}', '\u{1faba}', 2, 2), ('\u{1fac0}', '\u{1fac5}', 2, 2), - ('\u{1fad0}', '\u{1fad9}', 2, 2), ('\u{1fae0}', '\u{1fae7}', 2, 2), ('\u{1faf0}', - '\u{1faf6}', 2, 2), ('\u{20000}', '\u{2fffd}', 2, 2), ('\u{30000}', '\u{3fffd}', 2, 2), - ('\u{e0001}', '\u{e0001}', 0, 0), ('\u{e0020}', '\u{e007f}', 0, 0), ('\u{e0100}', - '\u{e01ef}', 0, 0), ('\u{f0000}', '\u{ffffd}', 1, 2), ('\u{100000}', '\u{10fffd}', 1, 2) + /// Autogenerated. 1 sub-table(s). Consult [`lookup_width`] for layout info. + static TABLES_0: [u8; 256] = [ + 0x00, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x10, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, ]; -} + /// Autogenerated. 19 sub-table(s). Consult [`lookup_width`] for layout info. + static TABLES_1: [u8; 2432] = [ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x06, 0x08, 0x06, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x06, 0x06, 0x06, 0x11, 0x12, 0x13, 0x14, 0x06, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x22, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2A, 0x25, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x06, 0x3B, 0x3C, 0x0A, 0x0A, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x3D, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x06, 0x43, 0x06, 0x44, 0x06, 0x06, 0x06, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x06, 0x06, 0x4E, 0x06, 0x06, 0x06, 0x0A, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x06, 0x5A, 0x06, 0x06, 0x5B, 0x06, 0x5C, 0x5D, 0x5E, 0x5D, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x69, 0x6A, 0x06, 0x06, 0x06, 0x06, 0x06, 0x6B, + 0x06, 0x01, 0x06, 0x6C, 0x06, 0x06, 0x6D, 0x6E, 0x3B, 0x3B, 0x3B, 0x6F, 0x70, 0x71, 0x72, + 0x3B, 0x73, 0x3B, 0x74, 0x75, 0x76, 0x77, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x06, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x78, 0x79, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7A, 0x7B, 0x7C, + 0x06, 0x06, 0x06, 0x06, 0x7D, 0x06, 0x06, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x86, 0x06, 0x06, 0x06, 0x87, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x88, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x89, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x8A, 0x8B, 0x06, 0x01, 0x71, 0x8C, 0x06, 0x8D, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x8E, 0x06, 0x06, 0x06, 0x8F, 0x06, 0x90, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x91, 0x06, 0x06, 0x92, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x93, 0x06, 0x06, 0x06, 0x06, 0x06, 0x94, 0x95, 0x06, 0x96, 0x97, 0x06, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0x2E, 0x06, 0xA1, 0x2C, 0xA2, 0x06, + 0x06, 0xA3, 0xA4, 0xA5, 0xA6, 0x06, 0x06, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x06, 0xAC, 0x06, + 0x06, 0x06, 0xAD, 0x06, 0x06, 0x06, 0xAE, 0xAF, 0x06, 0xB0, 0xB1, 0xB2, 0xB3, 0x06, 0x06, + 0x06, 0x06, 0x06, 0xB4, 0x06, 0xB5, 0x06, 0xB6, 0xB7, 0xB8, 0x06, 0x06, 0x06, 0x06, 0xB9, + 0xBA, 0xBB, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x47, 0xBC, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0xBD, 0xBE, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xBF, 0xC0, 0xC1, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0xC2, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0xC3, 0xC4, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xC5, 0x3B, 0x3B, 0x3B, 0x3B, 0xC6, + 0xC7, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0xC8, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0xC9, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xCA, + 0xCB, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xCC, 0xCD, 0x06, 0x06, 0xCE, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xCF, 0xD0, + 0xD1, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xD2, 0x06, 0xBF, 0x06, 0xBE, 0x06, 0x06, 0x06, + 0x06, 0x06, 0xD3, 0xD4, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xD4, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xD5, 0x06, 0xD6, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xD7, 0x06, 0x06, 0xD8, + 0xD9, 0xDA, 0xDB, 0x06, 0xDC, 0xDD, 0x06, 0x06, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0x3B, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0x3B, 0xE9, 0x3B, 0xEA, 0x06, 0x06, 0x06, 0xEB, 0x06, 0x06, + 0x06, 0x06, 0xEC, 0xED, 0x3B, 0x3B, 0x06, 0xEE, 0xEF, 0xF0, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0xE5, 0xF1, 0x0A, 0x06, 0x06, 0x0A, 0x0A, 0x0A, + 0x0B, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, + 0x5D, 0xF2, + ]; + /// Autogenerated. 243 sub-table(s). Consult [`lookup_width`] for layout info. + static TABLES_2: [u8; 3888] = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xD7, 0x77, 0x75, 0xFF, + 0xF7, 0x7F, 0xFF, 0x55, 0x75, 0x55, 0x55, 0x57, 0xD5, 0x57, 0xF5, 0x5F, 0x75, 0x7F, 0x5F, + 0xF7, 0xD5, 0x7F, 0x77, 0x5D, 0x55, 0x55, 0x55, 0xDD, 0x55, 0xD5, 0x55, 0x55, 0xF5, 0xD5, + 0x55, 0xFD, 0x55, 0x57, 0xD5, 0x7F, 0x57, 0xFF, 0x5D, 0xF5, 0x55, 0x55, 0x55, 0x55, 0xF5, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x75, 0x77, 0x77, 0x77, 0x57, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5D, 0x55, 0x55, + 0x55, 0x5D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xD7, 0xFD, 0x5D, 0x57, 0x55, + 0xFF, 0xDD, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0xFD, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x5F, 0x55, 0xFD, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, + 0x5F, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5D, + 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x15, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x41, 0x10, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x00, 0x50, 0x55, 0x55, 0x00, 0x00, 0x40, 0x54, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, + 0x55, 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x00, 0x10, 0x00, + 0x14, 0x04, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x51, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x05, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x05, 0x10, 0x00, 0x00, 0x01, 0x01, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x50, 0x55, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, + 0x54, 0x01, 0x00, 0x54, 0x51, 0x01, 0x00, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x54, 0x01, 0x54, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x45, 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0x41, 0x15, 0x14, 0x50, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x50, 0x51, 0x55, 0x55, 0x01, 0x10, 0x54, 0x51, 0x55, 0x55, 0x55, 0x55, 0x05, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x00, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x14, 0x01, 0x54, 0x55, 0x51, 0x55, 0x41, 0x55, + 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x55, 0x51, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x54, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x04, 0x54, 0x05, 0x04, + 0x50, 0x55, 0x41, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, + 0x55, 0x50, 0x55, 0x55, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x54, + 0x01, 0x54, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x45, 0x55, 0x05, 0x44, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x51, 0x00, 0x40, 0x55, 0x55, 0x15, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x51, 0x00, 0x00, 0x54, 0x55, 0x55, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x11, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x00, 0x00, 0x40, 0x00, 0x04, 0x55, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x45, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x04, 0x00, 0x41, 0x41, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x50, 0x05, 0x54, 0x55, 0x55, 0x55, 0x01, 0x54, 0x55, 0x55, 0x45, 0x41, + 0x55, 0x51, 0x55, 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x10, 0x00, 0x50, 0x55, 0x45, 0x01, 0x00, 0x00, 0x55, 0x55, 0x51, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x40, 0x15, 0x54, 0x55, 0x45, 0x55, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, + 0x14, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x45, 0x00, 0x40, 0x44, 0x01, 0x00, 0x54, 0x15, 0x00, 0x00, 0x14, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x04, 0x40, 0x54, 0x45, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x55, 0x55, 0x55, + 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x50, 0x10, 0x50, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, 0x50, 0x11, 0x50, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, + 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x54, 0x51, + 0x55, 0x54, 0x50, 0x55, 0x55, 0x55, 0x15, 0x00, 0xD7, 0x7F, 0x5F, 0x5F, 0x7F, 0xFF, 0x05, + 0x40, 0xF7, 0x5D, 0xD5, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x04, + 0x00, 0x00, 0x55, 0x57, 0x55, 0xD5, 0xFD, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0xD5, 0x5D, 0x5D, 0x55, 0xD5, 0x75, 0x55, + 0x55, 0x7D, 0x75, 0xD5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xD5, 0x57, + 0xD5, 0x7F, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0x5F, 0x55, 0x55, 0x55, 0x5D, 0x55, 0xFF, + 0xFF, 0x5F, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5F, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x75, 0x57, 0x55, 0x55, 0x55, 0xD5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xF7, 0xD5, 0xD7, + 0xD5, 0x5D, 0x5D, 0x75, 0xFD, 0xD7, 0xDD, 0xFF, 0x77, 0x55, 0xFF, 0x55, 0x5F, 0x55, 0x55, + 0x57, 0x57, 0x75, 0x55, 0x55, 0x55, 0x5F, 0xFF, 0xF5, 0xF5, 0x55, 0x55, 0x55, 0x55, 0xF5, + 0xF5, 0x55, 0x55, 0x55, 0x5D, 0x5D, 0x55, 0x55, 0x5D, 0x55, 0x55, 0x55, 0x55, 0x55, 0xD5, + 0x55, 0x55, 0x55, 0x55, 0x75, 0x55, 0xA5, 0x55, 0x55, 0x55, 0x69, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xA9, 0x56, 0x96, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x5F, 0x55, 0x55, 0xDF, + 0xFF, 0x5F, 0x55, 0xF5, 0xF5, 0x55, 0x5F, 0x5F, 0xF5, 0xD7, 0xF5, 0x5F, 0x55, 0x55, 0x55, + 0xF5, 0x5F, 0x55, 0xD5, 0x55, 0x55, 0x55, 0x69, 0x55, 0x7D, 0x5D, 0xF5, 0x55, 0x5A, 0x55, + 0x77, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x77, 0x55, 0xAA, 0xAA, 0xAA, 0x55, + 0x55, 0x55, 0xDF, 0xDF, 0x7F, 0xDF, 0x55, 0x55, 0x55, 0x95, 0x55, 0x55, 0x55, 0x55, 0x95, + 0x55, 0x55, 0xF5, 0x59, 0x55, 0xA5, 0x55, 0x55, 0x55, 0x55, 0xE9, 0x55, 0xFA, 0xFF, 0xEF, + 0xFF, 0xFE, 0xFF, 0xFF, 0xDF, 0x55, 0xEF, 0xFF, 0xAF, 0xFB, 0xEF, 0xFB, 0x55, 0x59, 0xA5, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x55, 0x55, 0x55, 0x55, 0x5D, 0x55, 0x55, + 0x55, 0x66, 0x95, 0x9A, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xF5, 0xFF, 0xFF, 0x55, + 0x55, 0x55, 0x55, 0x55, 0xA9, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x55, 0x55, 0x95, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x95, 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0xF9, 0x5F, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x50, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x5A, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0x0A, 0xA0, 0xAA, 0xAA, 0xAA, 0x6A, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, + 0x81, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0xA9, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0x56, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0x6A, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x40, + 0x00, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x50, 0x55, 0x55, 0x55, 0x45, 0x45, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x41, + 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x55, 0x55, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x05, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x50, 0x55, 0x55, + 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x56, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x05, 0x50, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x40, 0x41, 0x41, 0x55, 0x55, 0x15, 0x55, 0x55, + 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x04, 0x14, 0x54, 0x05, 0x51, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x55, 0x45, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x51, 0x54, 0x51, 0x55, 0x55, 0x55, + 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0x5A, 0x55, 0x00, 0x00, 0x00, 0x00, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, 0xAA, + 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x56, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, + 0x6A, 0x55, 0x55, 0x55, 0x55, 0x01, 0x5D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x40, 0x55, 0x01, 0x41, 0x55, 0x00, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x15, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, + 0x55, 0x05, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x05, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x00, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x14, 0x54, 0x55, 0x15, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x15, 0x40, 0x41, 0x51, 0x45, 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x15, 0x00, 0x01, 0x00, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x15, 0x55, 0x55, 0x55, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x14, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x50, 0x04, 0x55, 0x45, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x15, 0x15, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x00, 0x54, 0x00, 0x54, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x05, + 0x44, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x44, + 0x15, 0x04, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, + 0x50, 0x55, 0x10, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x15, 0x00, 0x40, 0x11, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x15, 0x51, 0x00, 0x10, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, + 0x05, 0x10, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x44, 0x15, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x00, 0x05, 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x00, 0x40, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x14, 0x40, 0x55, 0x15, + 0x55, 0x55, 0x01, 0x40, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x05, 0x00, 0x00, 0x40, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x40, 0x00, + 0x10, 0x55, 0x55, 0x55, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x41, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, + 0x40, 0x45, 0x10, 0x00, 0x10, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x15, 0x54, 0x55, 0x55, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x05, 0x40, 0x55, 0x44, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x15, 0x00, 0x00, 0x00, 0x50, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x15, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0x54, 0x55, 0x55, 0x5A, 0x55, 0x55, 0x55, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x5A, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0xAA, 0xAA, 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, + 0xA9, 0xAA, 0x69, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, 0x55, 0x55, 0x55, + 0x65, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x6A, 0x59, 0x55, 0x55, 0x55, 0xAA, 0x55, + 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x41, 0x00, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x15, 0x50, 0x55, 0x15, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x05, 0x50, 0x55, 0x55, 0x55, 0x55, 0x05, 0x54, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x51, 0x55, 0x55, 0x55, + 0x54, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x01, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x04, 0x40, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x45, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x95, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0x7F, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x5F, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xAB, 0xAA, + 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0x57, 0x55, 0x55, 0x55, 0x55, 0x6A, 0x55, 0x55, 0x55, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0xAA, 0xAA, 0x56, 0x55, + 0x5A, 0x55, 0x55, 0x55, 0xAA, 0x5A, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x56, 0x55, 0x55, 0xA9, 0xAA, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA6, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0x6A, 0x95, 0xAA, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x56, 0x56, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0x6A, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0x96, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0x5A, 0x55, 0x55, 0x95, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0x55, 0x55, 0x55, 0x55, 0x65, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x69, 0x55, 0x55, 0x55, + 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x95, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0x5A, 0x55, 0x56, 0x6A, 0xA9, + 0x55, 0xAA, 0x55, 0x55, 0x95, 0x56, 0x55, 0xAA, 0xAA, 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0x55, 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, 0xAA, 0xAA, 0x9A, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0x56, 0xAA, + 0xAA, 0x56, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x9A, + 0xAA, 0x5A, 0x55, 0xA5, 0xAA, 0xAA, 0xAA, 0x55, 0xAA, 0xAA, 0x56, 0x55, 0xAA, 0xAA, 0x56, + 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x5F, + ]; +} diff --git a/vendor/unicode-width/src/tests.rs b/vendor/unicode-width/src/tests.rs index 72808c64f..e49b1bfbe 100644 --- a/vendor/unicode-width/src/tests.rs +++ b/vendor/unicode-width/src/tests.rs @@ -13,7 +13,7 @@ use std::iter; #[cfg(feature = "bench")] use test::{self, Bencher}; #[cfg(feature = "bench")] -use super::UnicodeWidthChar; +use super::{UnicodeWidthChar, UnicodeWidthStr}; use std::prelude::v1::*; @@ -93,7 +93,23 @@ fn simple_width_match(c: char) -> Option { _ => UnicodeWidthChar::width(c) } } - +#[cfg(all(feature = "bench", not(feature = "no_std")))] +#[bench] +fn enwik8(b: &mut Bencher) { + // To benchmark, download & unzip `enwik8` from https://data.deepai.org/enwik8.zip + let data_path = "bench_data/enwik8"; + let string = std::fs::read_to_string(data_path).unwrap_or_default(); + b.iter(|| test::black_box(UnicodeWidthStr::width(string.as_str()))); +} +#[cfg(all(feature = "bench", not(feature = "no_std")))] +#[bench] +fn jawiki(b: &mut Bencher) { + // To benchmark, download & extract `jawiki-20220501-pages-articles-multistream-index.txt` from + // https://dumps.wikimedia.org/jawiki/20220501/jawiki-20220501-pages-articles-multistream-index.txt.bz2 + let data_path = "bench_data/jawiki-20220501-pages-articles-multistream-index.txt"; + let string = std::fs::read_to_string(data_path).unwrap_or_default(); + b.iter(|| test::black_box(UnicodeWidthStr::width(string.as_str()))); +} #[test] fn test_str() { use super::UnicodeWidthStr; diff --git a/vendor/unicode-xid/.cargo-checksum.json b/vendor/unicode-xid/.cargo-checksum.json index 0f93609e5..be3630543 100644 --- a/vendor/unicode-xid/.cargo-checksum.json +++ b/vendor/unicode-xid/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"50d9e34c8bf5a28d7e160844ed52b641c7975414e8be75166a8979710c17bcf2","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"2d01a2c43c4ec10fb3b74bf84fe06995d3d53d06c968fb4e27e64682058ba9e3","benches/xid.rs":"a2986ce1df5d93bff51e73dc234bffb341d4fe5d749247296f02396dde16a72b","src/lib.rs":"3cdd204115af45e9ece70db737d711e1798eac40eaa6cc4e8280bb3342e1408e","src/tables.rs":"1c8650d5bed6c75c4071f5cac2127aaab578d887622d2fdde8808492caec5c91","src/tests.rs":"b866f890acd631e667635785c34b1723709f10a9515ca525b41de8a062c7b204","tests/exhaustive_tests.rs":"ec91e9124d61e5b3e2fbbbf37a2fd30d6c7a8fa22639d6720b416d9ebc1007c5"},"package":"957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"} \ No newline at end of file +{"files":{"COPYRIGHT":"23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d","Cargo.toml":"289ae8b5c1859b5556dd663b31efae72255f69e3c05408ce7a51c8ba65573677","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"d13b0abf515d4b41b684a2255169f4340c32256c91e6a4835cafaec2161b5e5f","benches/xid.rs":"a2986ce1df5d93bff51e73dc234bffb341d4fe5d749247296f02396dde16a72b","src/lib.rs":"3cdd204115af45e9ece70db737d711e1798eac40eaa6cc4e8280bb3342e1408e","src/tables.rs":"e4c2e9b70f45d262b78fde8435a969eb2478ca6d9dacd061953f54cf344f0f4d","src/tests.rs":"b866f890acd631e667635785c34b1723709f10a9515ca525b41de8a062c7b204","tests/exhaustive_tests.rs":"ec91e9124d61e5b3e2fbbbf37a2fd30d6c7a8fa22639d6720b416d9ebc1007c5"},"package":"f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"} \ No newline at end of file diff --git a/vendor/unicode-xid/Cargo.toml b/vendor/unicode-xid/Cargo.toml index 04afa4c60..817a4f42f 100644 --- a/vendor/unicode-xid/Cargo.toml +++ b/vendor/unicode-xid/Cargo.toml @@ -12,7 +12,7 @@ [package] rust-version = "1.17" name = "unicode-xid" -version = "0.2.3" +version = "0.2.4" authors = [ "erick.tryzelaar ", "kwantam ", diff --git a/vendor/unicode-xid/README.md b/vendor/unicode-xid/README.md index 325d35e95..747684303 100644 --- a/vendor/unicode-xid/README.md +++ b/vendor/unicode-xid/README.md @@ -26,6 +26,15 @@ on std, and instead uses equivalent functions from core. # changelog +## 0.2.4 + +- Update to Unicode 15.0.0 +- Replace `const` tables with `static` tables. + +## 0.2.3 + +- Update to Unicode 14.0.0 + ## 0.2.2 - Add an ASCII fast-path diff --git a/vendor/unicode-xid/src/tables.rs b/vendor/unicode-xid/src/tables.rs index a4a072f36..c12e76c0b 100644 --- a/vendor/unicode-xid/src/tables.rs +++ b/vendor/unicode-xid/src/tables.rs @@ -14,7 +14,7 @@ /// The version of [Unicode](http://www.unicode.org/) /// that this version of unicode-xid is based on. -pub const UNICODE_VERSION: (u64, u64, u64) = (14, 0, 0); +pub const UNICODE_VERSION: (u64, u64, u64) = (15, 0, 0); fn bsearch_range_table(c: char, r: &[(char, char)]) -> bool { use core::cmp::Ordering::{Equal, Greater, Less}; @@ -37,7 +37,7 @@ fn bsearch_range_table(c: char, r: &[(char, char)]) -> bool { } pub mod derived_property { - pub const XID_Continue_table: &[(char, char)] = &[ + static XID_Continue_table: &[(char, char)] = &[ ('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), @@ -196,7 +196,7 @@ pub mod derived_property { ('\u{cdd}', '\u{cde}'), ('\u{ce0}', '\u{ce3}'), ('\u{ce6}', '\u{cef}'), - ('\u{cf1}', '\u{cf2}'), + ('\u{cf1}', '\u{cf3}'), ('\u{d00}', '\u{d0c}'), ('\u{d0e}', '\u{d10}'), ('\u{d12}', '\u{d44}'), @@ -229,7 +229,7 @@ pub mod derived_property { ('\u{ea7}', '\u{ebd}'), ('\u{ec0}', '\u{ec4}'), ('\u{ec6}', '\u{ec6}'), - ('\u{ec8}', '\u{ecd}'), + ('\u{ec8}', '\u{ece}'), ('\u{ed0}', '\u{ed9}'), ('\u{edc}', '\u{edf}'), ('\u{f00}', '\u{f00}'), @@ -549,7 +549,7 @@ pub mod derived_property { ('\u{10e80}', '\u{10ea9}'), ('\u{10eab}', '\u{10eac}'), ('\u{10eb0}', '\u{10eb1}'), - ('\u{10f00}', '\u{10f1c}'), + ('\u{10efd}', '\u{10f1c}'), ('\u{10f27}', '\u{10f27}'), ('\u{10f30}', '\u{10f50}'), ('\u{10f70}', '\u{10f85}'), @@ -572,7 +572,7 @@ pub mod derived_property { ('\u{111dc}', '\u{111dc}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{11237}'), - ('\u{1123e}', '\u{1123e}'), + ('\u{1123e}', '\u{11241}'), ('\u{11280}', '\u{11286}'), ('\u{11288}', '\u{11288}'), ('\u{1128a}', '\u{1128d}'), @@ -653,12 +653,17 @@ pub mod derived_property { ('\u{11d93}', '\u{11d98}'), ('\u{11da0}', '\u{11da9}'), ('\u{11ee0}', '\u{11ef6}'), + ('\u{11f00}', '\u{11f10}'), + ('\u{11f12}', '\u{11f3a}'), + ('\u{11f3e}', '\u{11f42}'), + ('\u{11f50}', '\u{11f59}'), ('\u{11fb0}', '\u{11fb0}'), ('\u{12000}', '\u{12399}'), ('\u{12400}', '\u{1246e}'), ('\u{12480}', '\u{12543}'), ('\u{12f90}', '\u{12ff0}'), - ('\u{13000}', '\u{1342e}'), + ('\u{13000}', '\u{1342f}'), + ('\u{13440}', '\u{13455}'), ('\u{14400}', '\u{14646}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), @@ -686,7 +691,9 @@ pub mod derived_property { ('\u{1aff5}', '\u{1affb}'), ('\u{1affd}', '\u{1affe}'), ('\u{1b000}', '\u{1b122}'), + ('\u{1b132}', '\u{1b132}'), ('\u{1b150}', '\u{1b152}'), + ('\u{1b155}', '\u{1b155}'), ('\u{1b164}', '\u{1b167}'), ('\u{1b170}', '\u{1b2fb}'), ('\u{1bc00}', '\u{1bc6a}'), @@ -740,17 +747,21 @@ pub mod derived_property { ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'), ('\u{1df00}', '\u{1df1e}'), + ('\u{1df25}', '\u{1df2a}'), ('\u{1e000}', '\u{1e006}'), ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'), + ('\u{1e030}', '\u{1e06d}'), + ('\u{1e08f}', '\u{1e08f}'), ('\u{1e100}', '\u{1e12c}'), ('\u{1e130}', '\u{1e13d}'), ('\u{1e140}', '\u{1e149}'), ('\u{1e14e}', '\u{1e14e}'), ('\u{1e290}', '\u{1e2ae}'), ('\u{1e2c0}', '\u{1e2f9}'), + ('\u{1e4d0}', '\u{1e4f9}'), ('\u{1e7e0}', '\u{1e7e6}'), ('\u{1e7e8}', '\u{1e7eb}'), ('\u{1e7ed}', '\u{1e7ee}'), @@ -794,12 +805,13 @@ pub mod derived_property { ('\u{1eeab}', '\u{1eebb}'), ('\u{1fbf0}', '\u{1fbf9}'), ('\u{20000}', '\u{2a6df}'), - ('\u{2a700}', '\u{2b738}'), + ('\u{2a700}', '\u{2b739}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2b820}', '\u{2cea1}'), ('\u{2ceb0}', '\u{2ebe0}'), ('\u{2f800}', '\u{2fa1d}'), ('\u{30000}', '\u{3134a}'), + ('\u{31350}', '\u{323af}'), ('\u{e0100}', '\u{e01ef}'), ]; @@ -807,7 +819,7 @@ pub mod derived_property { super::bsearch_range_table(c, XID_Continue_table) } - pub const XID_Start_table: &[(char, char)] = &[ + static XID_Start_table: &[(char, char)] = &[ ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), @@ -1283,6 +1295,7 @@ pub mod derived_property { ('\u{111dc}', '\u{111dc}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'), + ('\u{1123f}', '\u{11240}'), ('\u{11280}', '\u{11286}'), ('\u{11288}', '\u{11288}'), ('\u{1128a}', '\u{1128d}'), @@ -1345,12 +1358,16 @@ pub mod derived_property { ('\u{11d6a}', '\u{11d89}'), ('\u{11d98}', '\u{11d98}'), ('\u{11ee0}', '\u{11ef2}'), + ('\u{11f02}', '\u{11f02}'), + ('\u{11f04}', '\u{11f10}'), + ('\u{11f12}', '\u{11f33}'), ('\u{11fb0}', '\u{11fb0}'), ('\u{12000}', '\u{12399}'), ('\u{12400}', '\u{1246e}'), ('\u{12480}', '\u{12543}'), ('\u{12f90}', '\u{12ff0}'), - ('\u{13000}', '\u{1342e}'), + ('\u{13000}', '\u{1342f}'), + ('\u{13441}', '\u{13446}'), ('\u{14400}', '\u{14646}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), @@ -1373,7 +1390,9 @@ pub mod derived_property { ('\u{1aff5}', '\u{1affb}'), ('\u{1affd}', '\u{1affe}'), ('\u{1b000}', '\u{1b122}'), + ('\u{1b132}', '\u{1b132}'), ('\u{1b150}', '\u{1b152}'), + ('\u{1b155}', '\u{1b155}'), ('\u{1b164}', '\u{1b167}'), ('\u{1b170}', '\u{1b2fb}'), ('\u{1bc00}', '\u{1bc6a}'), @@ -1411,11 +1430,14 @@ pub mod derived_property { ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'), ('\u{1df00}', '\u{1df1e}'), + ('\u{1df25}', '\u{1df2a}'), + ('\u{1e030}', '\u{1e06d}'), ('\u{1e100}', '\u{1e12c}'), ('\u{1e137}', '\u{1e13d}'), ('\u{1e14e}', '\u{1e14e}'), ('\u{1e290}', '\u{1e2ad}'), ('\u{1e2c0}', '\u{1e2eb}'), + ('\u{1e4d0}', '\u{1e4eb}'), ('\u{1e7e0}', '\u{1e7e6}'), ('\u{1e7e8}', '\u{1e7eb}'), ('\u{1e7ed}', '\u{1e7ee}'), @@ -1457,12 +1479,13 @@ pub mod derived_property { ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{2a6df}'), - ('\u{2a700}', '\u{2b738}'), + ('\u{2a700}', '\u{2b739}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2b820}', '\u{2cea1}'), ('\u{2ceb0}', '\u{2ebe0}'), ('\u{2f800}', '\u{2fa1d}'), ('\u{30000}', '\u{3134a}'), + ('\u{31350}', '\u{323af}'), ]; pub fn XID_Start(c: char) -> bool { diff --git a/vendor/url/.cargo-checksum.json b/vendor/url/.cargo-checksum.json index 2c03fac5f..8a659101a 100644 --- a/vendor/url/.cargo-checksum.json +++ b/vendor/url/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"9814ea7672535568bb8c84b23512fe0119f85a14a2cc84d2f7f0b3848c61a65c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","src/host.rs":"88adbe3a8dc691a4e32d7ed664dc7f17f8a1a863ffa4cde4d618032a00ec6653","src/lib.rs":"30372556e2352f93fa56178b85174eb0c3a819e87b12c288b67a101f7535a712","src/origin.rs":"2b967dd04fa5852b4a89f13cc628f3bfd84d1432e9447b2d3cbc6fee8aba3738","src/parser.rs":"eab4f6c7bffc021e9722375447a259683b8257dc6dff784c715032c39d4b4923","src/path_segments.rs":"dd6b637245b2ad77ce96221df3f80c8b4ad858cd52aecc86b97166dec386882a","src/quirks.rs":"8a504a2eeb74429e3282f2628014f3af9a567284c2b08bd0360bfd72d3a17e43","src/slicing.rs":"25425fc5c4100a3a5da49d1e0b497f6536066afcc91c4ba4dff5ace0860acd40","tests/data.rs":"dace394aed466df0e8afea0037bb8c90306d30ce75efdaff39feb00dbd07fa79","tests/setters_tests.json":"486f6d129960d0d0d99b533caf9bef21113b31adcdb83296dfc4a59cd8431715","tests/unit.rs":"61e014d600aa558f4913ac7bc268d652eda67daead72b0b0cf288524b1d71d13","tests/urltestdata.json":"afe55dd9583d125305d31e152478de9cc19801006b413c5f4fb7d430c50b1d11"},"package":"a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"} \ No newline at end of file +{"files":{"Cargo.toml":"c861c99782bfd4be160167bf659e87792f00d7e1eb1ee072a59546143fa980f4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"76e972ac0f4ddb116e86e10100132a783931a596e7b9872eaa31be15cd4d751d","README.md":"71b01ec6f2f4ce47235ee430ba0c41afac563403a9dbcda23a584c3e915395ac","src/host.rs":"60cd21e0b4cbb208c36eec5d40628a8bbe1d7ef13e481479b33f89cef96277ec","src/lib.rs":"c48655bc0455efecb7f7e36dfee8b92f6d96d9a1fbc5b24890ef255fb7843956","src/origin.rs":"19a4b451e8615bfef7239d2fc719c489398fe5044edb0df7c84b54eef4ceba1b","src/parser.rs":"5c05f233722560fd21899e982b9defc828ba13fbe70e7cf157a439968716c6ae","src/path_segments.rs":"dd6b637245b2ad77ce96221df3f80c8b4ad858cd52aecc86b97166dec386882a","src/quirks.rs":"82903ff9c95604409cded330e36ebba0ede91c469d1aa40fb646186e2bef0769","src/slicing.rs":"25425fc5c4100a3a5da49d1e0b497f6536066afcc91c4ba4dff5ace0860acd40","tests/data.rs":"dbd795b25fe7869b242aeeb822c736167d5b4be1f6a867f563e23977d07c8fc5","tests/debugger_visualizer.rs":"d3a9466c636ee80ec9181817a8d30ea3e0cee699776ee4b805175981e4775448","tests/setters_tests.json":"486f6d129960d0d0d99b533caf9bef21113b31adcdb83296dfc4a59cd8431715","tests/unit.rs":"9707676cd80d7c8131b9c805f03b387a36ca2b1dda84a4d567788814c8afe59f","tests/urltestdata.json":"9dca78fbbcb6fceb0584f2fae7b3bb4e8a868750f2426c359c6694aed25f2682"},"package":"0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"} \ No newline at end of file diff --git a/vendor/url/Cargo.toml b/vendor/url/Cargo.toml index 108b1493e..4363ae58f 100644 --- a/vendor/url/Cargo.toml +++ b/vendor/url/Cargo.toml @@ -3,52 +3,81 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" +rust-version = "1.51" name = "url" -version = "2.2.2" +version = "2.3.1" authors = ["The rust-url developers"] -include = ["src/**/*", "LICENSE-*", "README.md", "tests/**"] +include = [ + "src/**/*", + "LICENSE-*", + "README.md", + "tests/**", +] description = "URL library for Rust, based on the WHATWG URL Standard" documentation = "https://docs.rs/url" -readme = "../README.md" -keywords = ["url", "parser"] -categories = ["parser-implementations", "web-programming", "encoding"] -license = "MIT/Apache-2.0" +readme = "README.md" +keywords = [ + "url", + "parser", +] +categories = [ + "parser-implementations", + "web-programming", + "encoding", +] +license = "MIT OR Apache-2.0" repository = "https://github.com/servo/rust-url" +[[test]] +name = "debugger_visualizer" +path = "tests/debugger_visualizer.rs" +test = false +required-features = ["debugger_visualizer"] + [[bench]] name = "parse_url" path = "benches/parse_url.rs" harness = false + [dependencies.form_urlencoded] -version = "1.0.0" +version = "1.1.0" [dependencies.idna] -version = "0.2.0" - -[dependencies.matches] -version = "0.1" +version = "0.3.0" [dependencies.percent-encoding] -version = "2.1.0" +version = "2.2.0" [dependencies.serde] version = "1.0" features = ["derive"] optional = true + [dev-dependencies.bencher] version = "0.1" +[dev-dependencies.debugger_test] +version = "0.1" + +[dev-dependencies.debugger_test_parser] +version = "0.1" + [dev-dependencies.serde_json] version = "1.0" + +[features] +debugger_visualizer = [] +default = [] +expose_internals = [] + [badges.appveyor] repository = "Manishearth/rust-url" diff --git a/vendor/url/LICENSE-MIT b/vendor/url/LICENSE-MIT index 24de6b418..51d5dc7eb 100644 --- a/vendor/url/LICENSE-MIT +++ b/vendor/url/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2013-2016 The rust-url developers +Copyright (c) 2013-2022 The rust-url developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/vendor/url/README.md b/vendor/url/README.md new file mode 100644 index 000000000..ab31bffc6 --- /dev/null +++ b/vendor/url/README.md @@ -0,0 +1,14 @@ +rust-url +======== + +[![Build status](https://github.com/servo/rust-url/workflows/CI/badge.svg)](https://github.com/servo/rust-url/actions?query=workflow%3ACI) +[![Coverage](https://codecov.io/gh/servo/rust-url/branch/master/graph/badge.svg)](https://codecov.io/gh/servo/rust-url) +[![Chat](https://img.shields.io/badge/chat-%23rust--url:mozilla.org-%2346BC99?logo=Matrix)](https://matrix.to/#/#rust-url:mozilla.org) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE-MIT) +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE-APACHE) + +URL library for Rust, based on the [URL Standard](https://url.spec.whatwg.org/). + +[Documentation](https://docs.rs/url/) + +Please see [UPGRADING.md](https://github.com/servo/rust-url/blob/master/UPGRADING.md) if you are upgrading from a previous version. diff --git a/vendor/url/src/host.rs b/vendor/url/src/host.rs index 953743649..f1921c654 100644 --- a/vendor/url/src/host.rs +++ b/vendor/url/src/host.rs @@ -82,7 +82,9 @@ impl Host { return parse_ipv6addr(&input[1..input.len() - 1]).map(Host::Ipv6); } let domain = percent_decode(input.as_bytes()).decode_utf8_lossy(); - let domain = idna::domain_to_ascii(&domain)?; + + let domain = Self::domain_to_ascii(&domain)?; + if domain.is_empty() { return Err(ParseError::EmptyHost); } @@ -90,9 +92,7 @@ impl Host { let is_invalid_domain_char = |c| { matches!( c, - '\0' | '\t' - | '\n' - | '\r' + '\0'..='\u{001F}' | ' ' | '#' | '%' @@ -106,12 +106,15 @@ impl Host { | '\\' | ']' | '^' + | '\u{007F}' + | '|' ) }; if domain.find(is_invalid_domain_char).is_some() { Err(ParseError::InvalidDomainCharacter) - } else if let Some(address) = parse_ipv4addr(&domain)? { + } else if ends_in_a_number(&domain) { + let address = parse_ipv4addr(&domain)?; Ok(Host::Ipv4(address)) } else { Ok(Host::Domain(domain)) @@ -145,6 +148,7 @@ impl Host { | '\\' | ']' | '^' + | '|' ) }; @@ -156,6 +160,11 @@ impl Host { )) } } + + /// convert domain with idna + fn domain_to_ascii(domain: &str) -> Result { + idna::domain_to_ascii(domain).map_err(Into::into) + } } impl> fmt::Display for Host { @@ -247,8 +256,33 @@ fn longest_zero_sequence(pieces: &[u16; 8]) -> (isize, isize) { } } +/// +fn ends_in_a_number(input: &str) -> bool { + let mut parts = input.rsplit('.'); + let last = parts.next().unwrap(); + let last = if last.is_empty() { + if let Some(last) = parts.next() { + last + } else { + return false; + } + } else { + last + }; + if !last.is_empty() && last.chars().all(|c| ('0'..='9').contains(&c)) { + return true; + } + + parse_ipv4number(last).is_ok() +} + /// +/// Ok(None) means the input is a valid number, but it overflows a `u32`. fn parse_ipv4number(mut input: &str) -> Result, ()> { + if input.is_empty() { + return Err(()); + } + let mut r = 10; if input.starts_with("0x") || input.starts_with("0X") { input = &input[2..]; @@ -258,10 +292,10 @@ fn parse_ipv4number(mut input: &str) -> Result, ()> { r = 8; } - // At the moment we can't know the reason why from_str_radix fails - // https://github.com/rust-lang/rust/issues/22639 - // So instead we check if the input looks like a real number and only return - // an error when it's an overflow. + if input.is_empty() { + return Ok(Some(0)); + } + let valid_number = match r { 8 => input.chars().all(|c| ('0'..='7').contains(&c)), 10 => input.chars().all(|c| ('0'..='9').contains(&c)), @@ -270,50 +304,34 @@ fn parse_ipv4number(mut input: &str) -> Result, ()> { }), _ => false, }; - if !valid_number { - return Ok(None); + return Err(()); } - if input.is_empty() { - return Ok(Some(0)); - } - if input.starts_with('+') { - return Ok(None); - } match u32::from_str_radix(input, r) { - Ok(number) => Ok(Some(number)), - Err(_) => Err(()), + Ok(num) => Ok(Some(num)), + Err(_) => Ok(None), // The only possible error kind here is an integer overflow. + // The validity of the chars in the input is checked above. } } /// -fn parse_ipv4addr(input: &str) -> ParseResult> { - if input.is_empty() { - return Ok(None); - } +fn parse_ipv4addr(input: &str) -> ParseResult { let mut parts: Vec<&str> = input.split('.').collect(); if parts.last() == Some(&"") { parts.pop(); } if parts.len() > 4 { - return Ok(None); + return Err(ParseError::InvalidIpv4Address); } let mut numbers: Vec = Vec::new(); - let mut overflow = false; for part in parts { - if part.is_empty() { - return Ok(None); - } match parse_ipv4number(part) { Ok(Some(n)) => numbers.push(n), - Ok(None) => return Ok(None), - Err(()) => overflow = true, + Ok(None) => return Err(ParseError::InvalidIpv4Address), // u32 overflow + Err(()) => return Err(ParseError::InvalidIpv4Address), }; } - if overflow { - return Err(ParseError::InvalidIpv4Address); - } let mut ipv4 = numbers.pop().expect("a non-empty list of numbers"); // Equivalent to: ipv4 >= 256 ** (4 − numbers.len()) if ipv4 > u32::max_value() >> (8 * numbers.len() as u32) { @@ -325,7 +343,7 @@ fn parse_ipv4addr(input: &str) -> ParseResult> { for (counter, n) in numbers.iter().enumerate() { ipv4 += n << (8 * (3 - counter as u32)) } - Ok(Some(Ipv4Addr::from(ipv4))) + Ok(Ipv4Addr::from(ipv4)) } /// diff --git a/vendor/url/src/lib.rs b/vendor/url/src/lib.rs index 42793cf48..6dc09d12f 100644 --- a/vendor/url/src/lib.rs +++ b/vendor/url/src/lib.rs @@ -118,12 +118,16 @@ See [serde documentation](https://serde.rs) for more information. ```toml url = { version = "2", features = ["serde"] } ``` + */ -#![doc(html_root_url = "https://docs.rs/url/2.2.2")] +#![doc(html_root_url = "https://docs.rs/url/2.3.1")] +#![cfg_attr( + feature = "debugger_visualizer", + feature(debugger_visualizer), + debugger_visualizer(natvis_file = "../../debug_metadata/url.natvis") +)] -#[macro_use] -extern crate matches; pub use form_urlencoded; #[cfg(feature = "serde")] @@ -460,7 +464,7 @@ impl Url { } // Add the filename if they are not the same - if base_filename != url_filename { + if !relative.is_empty() || base_filename != url_filename { // If the URIs filename is empty this means that it was a directory // so we'll have to append a '/'. // @@ -1234,14 +1238,9 @@ impl Url { /// # } /// # run().unwrap(); /// ``` - #[allow(clippy::manual_strip)] // introduced in 1.45, MSRV is 1.36 pub fn path_segments(&self) -> Option> { let path = self.path(); - if path.starts_with('/') { - Some(path[1..].split('/')) - } else { - None - } + path.strip_prefix('/').map(|remainder| remainder.split('/')) } /// Return this URL’s query string, if any, as a percent-encoded ASCII string. @@ -1304,7 +1303,7 @@ impl Url { /// # Ok(()) /// # } /// # run().unwrap(); - /// + /// ``` #[inline] pub fn query_pairs(&self) -> form_urlencoded::Parse<'_> { @@ -1351,7 +1350,7 @@ impl Url { } fn mutate) -> R, R>(&mut self, f: F) -> R { - let mut parser = Parser::for_setter(mem::replace(&mut self.serialization, String::new())); + let mut parser = Parser::for_setter(mem::take(&mut self.serialization)); let result = f(&mut parser); self.serialization = parser.serialization; result @@ -1541,6 +1540,19 @@ impl Url { /// url.set_path("data/report.csv"); /// assert_eq!(url.as_str(), "https://example.com/data/report.csv"); /// assert_eq!(url.path(), "/data/report.csv"); + /// + /// // `set_path` percent-encodes the given string if it's not already percent-encoded. + /// let mut url = Url::parse("https://example.com")?; + /// url.set_path("api/some comments"); + /// assert_eq!(url.as_str(), "https://example.com/api/some%20comments"); + /// assert_eq!(url.path(), "/api/some%20comments"); + /// + /// // `set_path` will not double percent-encode the string if it's already percent-encoded. + /// let mut url = Url::parse("https://example.com")?; + /// url.set_path("api/some%20comments"); + /// assert_eq!(url.as_str(), "https://example.com/api/some%20comments"); + /// assert_eq!(url.path(), "/api/some%20comments"); + /// /// # Ok(()) /// # } /// # run().unwrap(); @@ -1792,8 +1804,10 @@ impl Url { return Err(ParseError::SetHostOnCannotBeABaseUrl); } + let scheme_type = SchemeType::from(self.scheme()); + if let Some(host) = host { - if host.is_empty() && SchemeType::from(self.scheme()).is_special() { + if host.is_empty() && scheme_type.is_special() && !scheme_type.is_file() { return Err(ParseError::EmptyHost); } let mut host_substr = host; @@ -1817,15 +1831,20 @@ impl Url { self.set_host_internal(Host::parse_opaque(host_substr)?, None); } } else if self.has_host() { - let scheme_type = SchemeType::from(self.scheme()); - if scheme_type.is_special() { + if scheme_type.is_special() && !scheme_type.is_file() { return Err(ParseError::EmptyHost); } else if self.serialization.len() == self.path_start as usize { self.serialization.push('/'); } debug_assert!(self.byte_at(self.scheme_end) == b':'); debug_assert!(self.byte_at(self.path_start) == b'/'); - let new_path_start = self.scheme_end + 1; + + let new_path_start = if scheme_type.is_file() { + self.scheme_end + 3 + } else { + self.scheme_end + 1 + }; + self.serialization .drain(new_path_start as usize..self.path_start as usize); let offset = self.path_start - new_path_start; @@ -2127,7 +2146,7 @@ impl Url { /// /// # Examples /// - /// Change the URL’s scheme from `https` to `foo`: + /// Change the URL’s scheme from `https` to `http`: /// /// ``` /// use url::Url; @@ -2298,7 +2317,7 @@ impl Url { /// # run().unwrap(); /// # } /// ``` - #[cfg(any(unix, windows, target_os = "redox"))] + #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))] #[allow(clippy::result_unit_err)] pub fn from_file_path>(path: P) -> Result { let mut serialization = "file://".to_owned(); @@ -2335,7 +2354,7 @@ impl Url { /// /// Note that `std::path` does not consider trailing slashes significant /// and usually does not include them (e.g. in `Path::parent()`). - #[cfg(any(unix, windows, target_os = "redox"))] + #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))] #[allow(clippy::result_unit_err)] pub fn from_directory_path>(path: P) -> Result { let mut url = Url::from_file_path(path)?; @@ -2452,7 +2471,7 @@ impl Url { /// (That is, if the percent-decoded path contains a NUL byte or, /// for a Windows path, is not UTF-8.) #[inline] - #[cfg(any(unix, windows, target_os = "redox"))] + #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))] #[allow(clippy::result_unit_err)] pub fn to_file_path(&self) -> Result { if let Some(segments) = self.path_segments() { @@ -2511,7 +2530,7 @@ impl fmt::Display for Url { } } -/// String converstion. +/// String conversion. impl From for String { fn from(value: Url) -> String { value.serialization @@ -2656,12 +2675,15 @@ impl<'de> serde::Deserialize<'de> for Url { } } -#[cfg(any(unix, target_os = "redox"))] +#[cfg(any(unix, target_os = "redox", target_os = "wasi"))] fn path_to_file_url_segments( path: &Path, serialization: &mut String, ) -> Result<(u32, HostInternal), ()> { + #[cfg(any(unix, target_os = "redox"))] use std::os::unix::prelude::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::prelude::OsStrExt; if !path.is_absolute() { return Err(()); } @@ -2706,6 +2728,7 @@ fn path_to_file_url_segments_windows( let host_start = serialization.len() + 1; let host_end; let host_internal; + match components.next() { Some(Component::Prefix(ref p)) => match p.kind() { Prefix::Disk(letter) | Prefix::VerbatimDisk(letter) => { @@ -2726,7 +2749,6 @@ fn path_to_file_url_segments_windows( } _ => return Err(()), }, - _ => return Err(()), } @@ -2735,12 +2757,15 @@ fn path_to_file_url_segments_windows( if component == Component::RootDir { continue; } + path_only_has_prefix = false; // FIXME: somehow work with non-unicode? let component = component.as_os_str().to_str().ok_or(())?; + serialization.push('/'); serialization.extend(percent_encode(component.as_bytes(), PATH_SEGMENT)); } + // A windows drive letter must end with a slash. if serialization.len() > host_start && parser::is_windows_drive_letter(&serialization[host_start..]) @@ -2748,16 +2773,20 @@ fn path_to_file_url_segments_windows( { serialization.push('/'); } + Ok((host_end, host_internal)) } -#[cfg(any(unix, target_os = "redox"))] +#[cfg(any(unix, target_os = "redox", target_os = "wasi"))] fn file_url_segments_to_pathbuf( host: Option<&str>, segments: str::Split<'_, char>, ) -> Result { use std::ffi::OsStr; + #[cfg(any(unix, target_os = "redox"))] use std::os::unix::prelude::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::prelude::OsStrExt; if host.is_some() { return Err(()); @@ -2768,10 +2797,12 @@ fn file_url_segments_to_pathbuf( } else { Vec::new() }; + for segment in segments { bytes.push(b'/'); bytes.extend(percent_decode(segment.as_bytes())); } + // A windows drive letter must end with a slash. if bytes.len() > 2 && matches!(bytes[bytes.len() - 2], b'a'..=b'z' | b'A'..=b'Z') @@ -2779,12 +2810,15 @@ fn file_url_segments_to_pathbuf( { bytes.push(b'/'); } + let os_str = OsStr::from_bytes(&bytes); let path = PathBuf::from(os_str); + debug_assert!( path.is_absolute(), "to_file_path() failed to produce an absolute Path" ); + Ok(path) } diff --git a/vendor/url/src/origin.rs b/vendor/url/src/origin.rs index be2d948b8..81193f510 100644 --- a/vendor/url/src/origin.rs +++ b/vendor/url/src/origin.rs @@ -9,7 +9,6 @@ use crate::host::Host; use crate::parser::default_port; use crate::Url; -use idna::domain_to_unicode; use std::sync::atomic::{AtomicUsize, Ordering}; pub fn url_origin(url: &Url) -> Origin { @@ -93,7 +92,7 @@ impl Origin { Origin::Tuple(ref scheme, ref host, port) => { let host = match *host { Host::Domain(ref domain) => { - let (domain, _errors) = domain_to_unicode(domain); + let (domain, _errors) = idna::domain_to_unicode(domain); Host::Domain(domain) } _ => host.clone(), diff --git a/vendor/url/src/parser.rs b/vendor/url/src/parser.rs index 57be11052..f5438c505 100644 --- a/vendor/url/src/parser.rs +++ b/vendor/url/src/parser.rs @@ -52,15 +52,12 @@ macro_rules! simple_enum_error { /// /// This may be extended in the future so exhaustive matching is /// discouraged with an unused variant. - #[allow(clippy::manual_non_exhaustive)] // introduced in 1.40, MSRV is 1.36 #[derive(PartialEq, Eq, Clone, Copy, Debug)] + #[non_exhaustive] pub enum ParseError { $( $name, )+ - /// Unused variant enable non-exhaustive matching - #[doc(hidden)] - __FutureProof, } impl fmt::Display for ParseError { @@ -69,9 +66,6 @@ macro_rules! simple_enum_error { $( ParseError::$name => fmt.write_str($description), )+ - ParseError::__FutureProof => { - unreachable!("Don't abuse the FutureProof!"); - } } } } @@ -105,15 +99,12 @@ macro_rules! syntax_violation_enum { /// /// This may be extended in the future so exhaustive matching is /// discouraged with an unused variant. - #[allow(clippy::manual_non_exhaustive)] // introduced in 1.40, MSRV is 1.36 #[derive(PartialEq, Eq, Clone, Copy, Debug)] + #[non_exhaustive] pub enum SyntaxViolation { $( $name, )+ - /// Unused variant enable non-exhaustive matching - #[doc(hidden)] - __FutureProof, } impl SyntaxViolation { @@ -122,9 +113,6 @@ macro_rules! syntax_violation_enum { $( SyntaxViolation::$name => $description, )+ - SyntaxViolation::__FutureProof => { - unreachable!("Don't abuse the FutureProof!"); - } } } } @@ -154,7 +142,7 @@ impl fmt::Display for SyntaxViolation { } } -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] pub enum SchemeType { File, SpecialNotFile, @@ -1227,13 +1215,11 @@ impl<'a> Parser<'a> { } } } - // Going from &str to String to &str to please the 1.33.0 borrow checker - let before_slash_string = if ends_with_slash { - self.serialization[segment_start..self.serialization.len() - 1].to_owned() + let segment_before_slash = if ends_with_slash { + &self.serialization[segment_start..self.serialization.len() - 1] } else { - self.serialization[segment_start..self.serialization.len()].to_owned() + &self.serialization[segment_start..self.serialization.len()] }; - let segment_before_slash: &str = &before_slash_string; match segment_before_slash { // If buffer is a double-dot path segment, shorten url’s path, ".." | "%2e%2e" | "%2e%2E" | "%2E%2e" | "%2E%2E" | "%2e." | "%2E." | ".%2e" @@ -1292,7 +1278,7 @@ impl<'a> Parser<'a> { //FIXME: log violation let path = self.serialization.split_off(path_start); self.serialization.push('/'); - self.serialization.push_str(&path.trim_start_matches('/')); + self.serialization.push_str(path.trim_start_matches('/')); } input @@ -1423,7 +1409,8 @@ impl<'a> Parser<'a> { scheme_end: u32, mut input: Input<'i>, ) -> Option> { - let mut query = String::new(); // FIXME: use a streaming decoder instead + let len = input.chars.as_str().len(); + let mut query = String::with_capacity(len); // FIXME: use a streaming decoder instead let mut remaining = None; while let Some(c) = input.next() { if c == '#' && self.context == Context::UrlParser { @@ -1563,17 +1550,17 @@ fn is_normalized_windows_drive_letter(segment: &str) -> bool { is_windows_drive_letter(segment) && segment.as_bytes()[1] == b':' } -/// Wether the scheme is file:, the path has a single segment, and that segment +/// Whether the scheme is file:, the path has a single segment, and that segment /// is a Windows drive letter #[inline] pub fn is_windows_drive_letter(segment: &str) -> bool { segment.len() == 2 && starts_with_windows_drive_letter(segment) } -/// Wether path starts with a root slash +/// Whether path starts with a root slash /// and a windows drive letter eg: "/c:" or "/a:/" fn path_starts_with_windows_drive_letter(s: &str) -> bool { - if let Some(c) = s.as_bytes().get(0) { + if let Some(c) = s.as_bytes().first() { matches!(c, b'/' | b'\\' | b'?' | b'#') && starts_with_windows_drive_letter(&s[1..]) } else { false diff --git a/vendor/url/src/quirks.rs b/vendor/url/src/quirks.rs index 0dbc6eb44..0674ebb62 100644 --- a/vendor/url/src/quirks.rs +++ b/vendor/url/src/quirks.rs @@ -14,6 +14,49 @@ use crate::parser::{default_port, Context, Input, Parser, SchemeType}; use crate::{Host, ParseError, Position, Url}; +/// Internal components / offsets of a URL. +/// +/// https://user@pass:example.com:1234/foo/bar?baz#quux +/// | | | | ^^^^| | | +/// | | | | | | | `----- fragment_start +/// | | | | | | `--------- query_start +/// | | | | | `----------------- path_start +/// | | | | `--------------------- port +/// | | | `----------------------- host_end +/// | | `---------------------------------- host_start +/// | `--------------------------------------- username_end +/// `---------------------------------------------- scheme_end +#[derive(Copy, Clone)] +#[cfg(feature = "expose_internals")] +pub struct InternalComponents { + pub scheme_end: u32, + pub username_end: u32, + pub host_start: u32, + pub host_end: u32, + pub port: Option, + pub path_start: u32, + pub query_start: Option, + pub fragment_start: Option, +} + +/// Internal component / parsed offsets of the URL. +/// +/// This can be useful for implementing efficient serialization +/// for the URL. +#[cfg(feature = "expose_internals")] +pub fn internal_components(url: &Url) -> InternalComponents { + InternalComponents { + scheme_end: url.scheme_end, + username_end: url.username_end, + host_start: url.host_start, + host_end: url.host_end, + port: url.port, + path_start: url.path_start, + query_start: url.query_start, + fragment_start: url.fragment_start, + } +} + /// https://url.spec.whatwg.org/#dom-url-domaintoascii pub fn domain_to_ascii(domain: &str) -> String { match Host::parse(domain) { @@ -138,14 +181,10 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> { } } // Make sure we won't set an empty host to a url with a username or a port - if host == Host::Domain("".to_string()) { - if !username(&url).is_empty() { - return Err(()); - } else if let Some(Some(_)) = opt_port { - return Err(()); - } else if url.port().is_some() { - return Err(()); - } + if host == Host::Domain("".to_string()) + && (!username(url).is_empty() || matches!(opt_port, Some(Some(_))) || url.port().is_some()) + { + return Err(()); } url.set_host_internal(host, opt_port); Ok(()) @@ -177,10 +216,10 @@ pub fn set_hostname(url: &mut Url, new_hostname: &str) -> Result<(), ()> { // Empty host on special not file url if SchemeType::from(url.scheme()) == SchemeType::SpecialNotFile // Port with an empty host - ||!port(&url).is_empty() + ||!port(url).is_empty() // Empty host that includes credentials || !url.username().is_empty() - || !url.password().unwrap_or(&"").is_empty() + || !url.password().unwrap_or("").is_empty() { return Err(()); } diff --git a/vendor/url/tests/data.rs b/vendor/url/tests/data.rs index b72c33306..f4001ca2b 100644 --- a/vendor/url/tests/data.rs +++ b/vendor/url/tests/data.rs @@ -8,7 +8,6 @@ //! Data-driven tests -use std::ops::Deref; use std::str::FromStr; use serde_json::Value; @@ -16,7 +15,20 @@ use url::{quirks, Url}; #[test] fn urltestdata() { - // Copied form https://github.com/w3c/web-platform-tests/blob/master/url/ + let idna_skip_inputs = [ + "http://www.foo。bar.com", + "http://Go.com", + "http://你好你好", + "https://faß.ExAmPlE/", + "http://0Xc0.0250.01", + "ftp://%e2%98%83", + "https://%e2%98%83", + "file://a\u{ad}b/p", + "file://a%C2%ADb/p", + "http://GOO\u{200b}\u{2060}\u{feff}goo.com", + ]; + + // Copied from https://github.com/web-platform-tests/wpt/blob/master/url/ let mut json = Value::from_str(include_str!("urltestdata.json")) .expect("JSON parse error in urltestdata.json"); @@ -26,25 +38,39 @@ fn urltestdata() { continue; // ignore comments } - let base = entry.take_string("base"); + let maybe_base = entry + .take_key("base") + .expect("missing base key") + .maybe_string(); let input = entry.take_string("input"); let failure = entry.take_key("failure").is_some(); - let base = match Url::parse(&base) { - Ok(base) => base, - Err(_) if failure => continue, - Err(message) => { - eprint_failure( - format!(" failed: error parsing base {:?}: {}", base, message), - &format!("parse base for {:?}", input), - None, - ); - passed = false; + { + if idna_skip_inputs.contains(&input.as_str()) { continue; } + } + + let res = if let Some(base) = maybe_base { + let base = match Url::parse(&base) { + Ok(base) => base, + Err(_) if failure => continue, + Err(message) => { + eprint_failure( + format!(" failed: error parsing base {:?}: {}", base, message), + &format!("parse base for {:?}", input), + None, + ); + passed = false; + continue; + } + }; + base.join(&input) + } else { + Url::parse(&input) }; - let url = match (base.join(&input), failure) { + let url = match (res, failure) { (Ok(url), false) => url, (Err(_), true) => continue, (Err(message), false) => { @@ -91,7 +117,6 @@ fn urltestdata() { assert!(passed) } -#[allow(clippy::option_as_ref_deref)] // introduced in 1.40, MSRV is 1.36 #[test] fn setters_tests() { let mut json = Value::from_str(include_str!("setters_tests.json")) @@ -106,15 +131,22 @@ fn setters_tests() { let mut tests = json.take_key(attr).unwrap(); for mut test in tests.as_array_mut().unwrap().drain(..) { let comment = test.take_key("comment").map(|s| s.string()); + { + if let Some(comment) = comment.as_ref() { + if comment.starts_with("IDNA Nontransitional_Processing") { + continue; + } + } + } let href = test.take_string("href"); let new_value = test.take_string("new_value"); let name = format!("{:?}.{} = {:?}", href, attr, new_value); let mut expected = test.take_key("expected").unwrap(); let mut url = Url::parse(&href).unwrap(); - let comment_ref = comment.as_ref().map(|s| s.deref()); + let comment_ref = comment.as_deref(); passed &= check_invariants(&url, &name, comment_ref); - let _ = set(&mut url, attr, &new_value); + set(&mut url, attr, &new_value); for attr in ATTRIBS { if let Some(value) = expected.take_key(attr) { @@ -153,6 +185,7 @@ fn check_invariants(url: &Url, name: &str, comment: Option<&str>) -> bool { trait JsonExt { fn take_key(&mut self, key: &str) -> Option; fn string(self) -> String; + fn maybe_string(self) -> Option; fn take_string(&mut self, key: &str) -> String; } @@ -162,10 +195,14 @@ impl JsonExt for Value { } fn string(self) -> String { - if let Value::String(s) = self { - s - } else { - panic!("Not a Value::String") + self.maybe_string().expect("") + } + + fn maybe_string(self) -> Option { + match self { + Value::String(s) => Some(s), + Value::Null => None, + _ => panic!("Not a Value::String or Value::Null"), } } diff --git a/vendor/url/tests/debugger_visualizer.rs b/vendor/url/tests/debugger_visualizer.rs new file mode 100644 index 000000000..4558e0701 --- /dev/null +++ b/vendor/url/tests/debugger_visualizer.rs @@ -0,0 +1,102 @@ +use debugger_test::debugger_test; +use url::Url; + +#[inline(never)] +fn __break() {} + +#[debugger_test( + debugger = "cdb", + commands = " + .nvlist + + dx base_url + + dx url_with_non_special_scheme + + dx url_with_user_pass_port_query_fragments + + dx url_blob + + dx url_with_base + + dx url_with_base_replaced + + dx url_with_comma", + expected_statements = r#" + pattern:debugger_visualizer-.*\.exe \(embedded NatVis ".*-[0-9]+\.natvis"\) + + base_url : "http://example.org/foo/bar" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "http" + [host] : "example.org" + [path] : "/foo/bar" + + url_with_non_special_scheme : "non-special://test/x" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "non-special" + [host] : "test" + [path] : "/x" + + url_with_user_pass_port_query_fragments : "http://user:pass@foo:21/bar;par?b#c" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "http" + [username] : "user" + [host] : "foo" + [port] : 21 + [path] : "/bar;par" + [query] : "b" + [fragment] : "c" + + url_blob : "blob:https://example.com:443/" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "blob" + [path] : "https://example.com:443/" + + url_with_base : "http://example.org/a%2fc" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "http" + [host] : "example.org" + [path] : "/a%2fc" + + url_with_base_replaced : "http://[::7f00:1]/" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "http" + [host] : "[::7f00:1]" + [path] : "/" + + url_with_comma : "data:text/html,test#test" [Type: url::Url] + [] [Type: url::Url] + [scheme] : "data" + [path] : "text/html,test" + [fragment] : "test" + "# +)] +fn test_url_visualizer() { + // Copied from https://github.com/web-platform-tests/wpt/blob/master/url/ + let base_url = Url::parse("http://example.org/foo/bar").unwrap(); + assert_eq!(base_url.as_str(), "http://example.org/foo/bar"); + + let url_with_non_special_scheme = Url::parse("non-special://:@test/x").unwrap(); + assert_eq!(url_with_non_special_scheme.as_str(), "non-special://test/x"); + + let url_with_user_pass_port_query_fragments = + Url::parse("http://user:pass@foo:21/bar;par?b#c").unwrap(); + assert_eq!( + url_with_user_pass_port_query_fragments.as_str(), + "http://user:pass@foo:21/bar;par?b#c" + ); + + let url_blob = Url::parse("blob:https://example.com:443/").unwrap(); + assert_eq!(url_blob.as_str(), "blob:https://example.com:443/"); + + let url_with_base = base_url.join("/a%2fc").unwrap(); + assert_eq!(url_with_base.as_str(), "http://example.org/a%2fc"); + + let url_with_base_replaced = base_url.join("http://[::127.0.0.1]").unwrap(); + assert_eq!(url_with_base_replaced.as_str(), "http://[::7f00:1]/"); + + let url_with_comma = base_url.join("data:text/html,test#test").unwrap(); + assert_eq!(url_with_comma.as_str(), "data:text/html,test#test"); + + __break(); +} diff --git a/vendor/url/tests/unit.rs b/vendor/url/tests/unit.rs index 13055a473..55ff59ada 100644 --- a/vendor/url/tests/unit.rs +++ b/vendor/url/tests/unit.rs @@ -43,6 +43,14 @@ fn test_set_empty_host() { assert_eq!(base.as_str(), "moz:/baz"); base.set_host(Some("servo")).unwrap(); assert_eq!(base.as_str(), "moz://servo/baz"); + + let mut base: Url = "file://server/share/foo/bar".parse().unwrap(); + base.set_host(None).unwrap(); + assert_eq!(base.as_str(), "file:///share/foo/bar"); + + let mut base: Url = "file://server/share/foo/bar".parse().unwrap(); + base.set_host(Some("foo")).unwrap(); + assert_eq!(base.as_str(), "file://foo/share/foo/bar"); } #[test] @@ -256,7 +264,6 @@ fn host() { 0x2001, 0x0db8, 0x85a3, 0x08d3, 0x1319, 0x8a2e, 0x0370, 0x7344, )), ); - assert_host("http://1.35.+33.49", Host::Domain("1.35.+33.49")); assert_host( "http://[::]", Host::Ipv6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), @@ -271,7 +278,8 @@ fn host() { ); assert_host("http://0x1232131", Host::Ipv4(Ipv4Addr::new(1, 35, 33, 49))); assert_host("http://111", Host::Ipv4(Ipv4Addr::new(0, 0, 0, 111))); - assert_host("http://2..2.3", Host::Domain("2..2.3")); + assert!(Url::parse("http://1.35.+33.49").is_err()); + assert!(Url::parse("http://2..2.3").is_err()); assert!(Url::parse("http://42.0x1232131").is_err()); assert!(Url::parse("http://192.168.0.257").is_err()); @@ -720,6 +728,34 @@ fn test_domain_encoding_quirks() { } } +#[cfg(feature = "expose_internals")] +#[test] +fn test_expose_internals() { + use url::quirks::internal_components; + use url::quirks::InternalComponents; + + let url = Url::parse("https://example.com/path/file.ext?key=val&key2=val2#fragment").unwrap(); + let InternalComponents { + scheme_end, + username_end, + host_start, + host_end, + port, + path_start, + query_start, + fragment_start, + } = internal_components(&url); + + assert_eq!(scheme_end, 5); + assert_eq!(username_end, 8); + assert_eq!(host_start, 8); + assert_eq!(host_end, 19); + assert_eq!(port, None); + assert_eq!(path_start, 19); + assert_eq!(query_start, Some(33)); + assert_eq!(fragment_start, Some(51)); +} + #[test] fn test_windows_unc_path() { if !cfg!(windows) { @@ -796,7 +832,7 @@ fn test_syntax_violation_callback_types() { ("file:/foo.txt", ExpectedFileDoubleSlash, "expected // after file:"), ("file://mozilla.org/c:/file.txt", FileWithHostAndWindowsDrive, "file: with host and Windows drive letter"), ("http://mozilla.org/^", NonUrlCodePoint, "non-URL code point"), - ("http://mozilla.org/#\00", NullInFragment, "NULL characters are ignored in URL fragment identifiers"), + ("http://mozilla.org/#\x000", NullInFragment, "NULL characters are ignored in URL fragment identifiers"), ("http://mozilla.org/%1", PercentDecode, "expected 2 hex digits after %"), ("http://mozilla.org\t/foo", TabOrNewlineIgnored, "tabs or newlines are ignored in URLs"), ("http://user@:pass@mozilla.org", UnencodedAtSign, "unencoded @ sign in username or password") @@ -1081,6 +1117,16 @@ fn test_make_relative() { "http://127.0.0.1:8080/test/video?baz=meh#456", "video?baz=meh#456", ), + ( + "http://127.0.0.1:8080/file.txt", + "http://127.0.0.1:8080/test/file.txt", + "test/file.txt", + ), + ( + "http://127.0.0.1:8080/not_equal.txt", + "http://127.0.0.1:8080/test/file.txt", + "test/file.txt", + ), ]; for (base, uri, relative) in &tests { @@ -1093,7 +1139,7 @@ fn test_make_relative() { base, uri, relative ); assert_eq!( - base_uri.join(&relative).unwrap().as_str(), + base_uri.join(relative).unwrap().as_str(), *uri, "base: {}, uri: {}, relative: {}", base, diff --git a/vendor/url/tests/urltestdata.json b/vendor/url/tests/urltestdata.json index 554e61914..4265f5928 100644 --- a/vendor/url/tests/urltestdata.json +++ b/vendor/url/tests/urltestdata.json @@ -1,6 +1,6 @@ [ "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/segments.js", - "# AS OF https://github.com/jsdom/whatwg-url/commit/35f04dfd3048cf6362f4398745bb13375c5020c2", + "# AS OF https://github.com/web-platform-tests/wpt/commit/2a64dae4641fbd61bd4257df460e188f425b492e", { "input": "http://example\t.\norg", "base": "http://example.org/foo/bar", @@ -540,6 +540,36 @@ "search": "", "hash": "" }, + { + "input": "\\x", + "base": "http://example.org/foo/bar", + "href": "http://example.org/x", + "origin": "http://example.org", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/x", + "search": "", + "hash": "" + }, + { + "input": "\\\\x\\hello", + "base": "http://example.org/foo/bar", + "href": "http://x/hello", + "origin": "http://x", + "protocol": "http:", + "username": "", + "password": "", + "host": "x", + "hostname": "x", + "port": "", + "pathname": "/hello", + "search": "", + "hash": "" + }, { "input": "::", "base": "http://example.org/foo/bar", @@ -3157,7 +3187,8 @@ { "input": "http:/:@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http://user@/www.example.com", @@ -3167,12 +3198,14 @@ { "input": "http:@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http:/@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http://@/www.example.com", @@ -3182,17 +3215,20 @@ { "input": "https:@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http:a:b@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http:/a:b@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http://a:b@/www.example.com", @@ -3202,7 +3238,8 @@ { "input": "http::@/www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http:a:@www.example.com", @@ -3267,12 +3304,14 @@ { "input": "http:@:www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http:/@:www.example.com", "base": "about:blank", - "failure": true + "failure": true, + "inputCanBeRelative": true }, { "input": "http://@:www.example.com", @@ -3646,6 +3685,38 @@ "search": "?%EF%BF%BD", "hash": "#%EF%BF%BD" }, + "Domain is ASCII, but a label is invalid IDNA", + { + "input": "http://a.b.c.xn--pokxncvks", + "base": "about:blank", + "failure": true + }, + { + "input": "http://10.0.0.xn--pokxncvks", + "base": "about:blank", + "failure": true + }, + "IDNA labels should be matched case-insensitively", + { + "input": "http://a.b.c.XN--pokxncvks", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a.b.c.Xn--pokxncvks", + "base": "about:blank", + "failure": true + }, + { + "input": "http://10.0.0.XN--pokxncvks", + "base": "about:blank", + "failure": true + }, + { + "input": "http://10.0.0.xN--pokxncvks", + "base": "about:blank", + "failure": true + }, "Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.", { "input": "http://Go.com", @@ -3847,21 +3918,6 @@ "search": "", "hash": "" }, - { - "input": "http://0..0x300/", - "base": "about:blank", - "href": "http://0..0x300/", - "origin": "http://0..0x300", - "protocol": "http:", - "username": "", - "password": "", - "host": "0..0x300", - "hostname": "0..0x300", - "port": "", - "pathname": "/", - "search": "", - "hash": "" - }, "Broken IPv6", { "input": "http://[www.google.com]/", @@ -4482,16 +4538,6 @@ "search": "", "hash": "" }, - { - "input": "sc://\u0000/", - "base": "about:blank", - "failure": true - }, - { - "input": "sc:// /", - "base": "about:blank", - "failure": true - }, { "input": "sc://%/", "base": "about:blank", @@ -4526,21 +4572,6 @@ "base": "about:blank", "failure": true }, - { - "input": "sc://[/", - "base": "about:blank", - "failure": true - }, - { - "input": "sc://\\/", - "base": "about:blank", - "failure": true - }, - { - "input": "sc://]/", - "base": "about:blank", - "failure": true - }, { "input": "x", "base": "sc://ñ", @@ -4619,7 +4650,7 @@ "search": "", "hash": "" }, - "# unknown scheme with non-URL characters in the path", + "# unknown scheme with non-URL characters", { "input": "wow:\uFFFF", "base": "about:blank", @@ -4637,758 +4668,1620 @@ }, "Forbidden host code points", { - "input": "http://ab", + "input": "sc://a b/", "base": "about:blank", "failure": true }, { - "input": "http://a^b", + "input": "sc://ab", "base": "about:blank", "failure": true }, { - "input": "non-special://a>b", + "input": "sc://a[b/", "base": "about:blank", "failure": true }, { - "input": "non-special://a^b", + "input": "sc://a\\b/", "base": "about:blank", "failure": true }, - "Allowed host code points", { - "input": "http://\u001F!\"$&'()*+,-.;=_`{|}~/", + "input": "sc://a]b/", "base": "about:blank", - "href": "http://\u001F!\"$&'()*+,-.;=_`{|}~/", - "origin": "http://\u001F!\"$&'()*+,-.;=_`{|}~", - "protocol": "http:", - "username": "", + "failure": true + }, + { + "input": "sc://a^b", + "base": "about:blank", + "failure": true + }, + { + "input": "sc://a|b/", + "base": "about:blank", + "failure": true + }, + "Forbidden host codepoints: tabs and newlines are removed during preprocessing", + { + "input": "foo://ho\u0009st/", + "base": "about:blank", + "hash": "", + "host": "host", + "hostname": "host", + "href":"foo://host/", "password": "", - "host": "\u001F!\"$&'()*+,-.;=_`{|}~", - "hostname": "\u001F!\"$&'()*+,-.;=_`{|}~", - "port": "", "pathname": "/", + "port":"", + "protocol": "foo:", "search": "", - "hash": "" + "username": "" }, { - "input": "sc://\u001F!\"$&'()*+,-.;=_`{|}~/", + "input": "foo://ho\u000Ast/", "base": "about:blank", - "href": "sc://%1F!\"$&'()*+,-.;=_`{|}~/", - "origin": "null", - "protocol": "sc:", - "username": "", + "hash": "", + "host": "host", + "hostname": "host", + "href":"foo://host/", "password": "", - "host": "%1F!\"$&'()*+,-.;=_`{|}~", - "hostname": "%1F!\"$&'()*+,-.;=_`{|}~", - "port": "", "pathname": "/", + "port":"", + "protocol": "foo:", "search": "", - "hash": "" + "username": "" }, - "# Hosts and percent-encoding", { - "input": "ftp://example.com%80/", + "input": "foo://ho\u000Dst/", + "base": "about:blank", + "hash": "", + "host": "host", + "hostname": "host", + "href":"foo://host/", + "password": "", + "pathname": "/", + "port":"", + "protocol": "foo:", + "search": "", + "username": "" + }, + "Forbidden domain code-points", + { + "input": "http://a\u0000b/", "base": "about:blank", "failure": true }, { - "input": "ftp://example.com%A0/", + "input": "http://a\u0001b/", "base": "about:blank", "failure": true }, { - "input": "https://example.com%80/", + "input": "http://a\u0002b/", "base": "about:blank", "failure": true }, { - "input": "https://example.com%A0/", + "input": "http://a\u0003b/", "base": "about:blank", "failure": true }, { - "input": "ftp://%e2%98%83", + "input": "http://a\u0004b/", "base": "about:blank", - "href": "ftp://xn--n3h/", - "origin": "ftp://xn--n3h", - "protocol": "ftp:", - "username": "", - "password": "", - "host": "xn--n3h", - "hostname": "xn--n3h", - "port": "", - "pathname": "/", - "search": "", - "hash": "" + "failure": true }, { - "input": "https://%e2%98%83", + "input": "http://a\u0005b/", "base": "about:blank", - "href": "https://xn--n3h/", - "origin": "https://xn--n3h", - "protocol": "https:", - "username": "", - "password": "", - "host": "xn--n3h", - "hostname": "xn--n3h", - "port": "", - "pathname": "/", - "search": "", - "hash": "" + "failure": true }, - "# tests from jsdom/whatwg-url designed for code coverage", { - "input": "http://127.0.0.1:10100/relative_import.html", + "input": "http://a\u0006b/", "base": "about:blank", - "href": "http://127.0.0.1:10100/relative_import.html", - "origin": "http://127.0.0.1:10100", - "protocol": "http:", - "username": "", - "password": "", - "host": "127.0.0.1:10100", - "hostname": "127.0.0.1", - "port": "10100", - "pathname": "/relative_import.html", - "search": "", - "hash": "" + "failure": true }, { - "input": "http://facebook.com/?foo=%7B%22abc%22", + "input": "http://a\u0007b/", "base": "about:blank", - "href": "http://facebook.com/?foo=%7B%22abc%22", - "origin": "http://facebook.com", - "protocol": "http:", - "username": "", - "password": "", - "host": "facebook.com", - "hostname": "facebook.com", - "port": "", - "pathname": "/", - "search": "?foo=%7B%22abc%22", - "hash": "" + "failure": true }, { - "input": "https://localhost:3000/jqueryui@1.2.3", + "input": "http://a\u0008b/", "base": "about:blank", - "href": "https://localhost:3000/jqueryui@1.2.3", - "origin": "https://localhost:3000", - "protocol": "https:", - "username": "", - "password": "", - "host": "localhost:3000", - "hostname": "localhost", - "port": "3000", - "pathname": "/jqueryui@1.2.3", - "search": "", - "hash": "" + "failure": true }, - "# tab/LF/CR", { - "input": "h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg", + "input": "http://a\u000Bb/", "base": "about:blank", - "href": "http://host:9000/path?query#frag", - "origin": "http://host:9000", - "protocol": "http:", - "username": "", - "password": "", - "host": "host:9000", - "hostname": "host", - "port": "9000", - "pathname": "/path", - "search": "?query", - "hash": "#frag" + "failure": true }, - "# Stringification of URL.searchParams", { - "input": "?a=b&c=d", - "base": "http://example.org/foo/bar", - "href": "http://example.org/foo/bar?a=b&c=d", - "origin": "http://example.org", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/foo/bar", - "search": "?a=b&c=d", - "searchParams": "a=b&c=d", - "hash": "" + "input": "http://a\u000Cb/", + "base": "about:blank", + "failure": true }, { - "input": "??a=b&c=d", - "base": "http://example.org/foo/bar", - "href": "http://example.org/foo/bar??a=b&c=d", - "origin": "http://example.org", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/foo/bar", - "search": "??a=b&c=d", - "searchParams": "%3Fa=b&c=d", - "hash": "" + "input": "http://a\u000Eb/", + "base": "about:blank", + "failure": true }, - "# Scheme only", { - "input": "http:", - "base": "http://example.org/foo/bar", - "href": "http://example.org/foo/bar", - "origin": "http://example.org", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", + "input": "http://a\u000Fb/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0010b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0011b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0012b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0013b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0014b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0015b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0016b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0017b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0018b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u0019b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u001Ab/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u001Bb/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u001Cb/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u001Db/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u001Eb/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u001Fb/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a%b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ab", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a[b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a]b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a^b", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a|b/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://a\u007Fb/", + "base": "about:blank", + "failure": true + }, + "Forbidden domain codepoints: tabs and newlines are removed during preprocessing", + { + "input": "http://ho\u0009st/", + "base": "about:blank", + "hash": "", + "host": "host", + "hostname": "host", + "href":"http://host/", + "password": "", + "pathname": "/", + "port":"", + "protocol": "http:", + "search": "", + "username": "" + }, + { + "input": "http://ho\u000Ast/", + "base": "about:blank", + "hash": "", + "host": "host", + "hostname": "host", + "href":"http://host/", + "password": "", + "pathname": "/", + "port":"", + "protocol": "http:", + "search": "", + "username": "" + }, + { + "input": "http://ho\u000Dst/", + "base": "about:blank", + "hash": "", + "host": "host", + "hostname": "host", + "href":"http://host/", + "password": "", + "pathname": "/", + "port":"", + "protocol": "http:", + "search": "", + "username": "" + }, + "Encoded forbidden domain codepoints in special URLs", + { + "input": "http://ho%00st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%01st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%02st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%03st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%04st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%05st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%06st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%07st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%08st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%09st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%0Ast/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%0Bst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%0Cst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%0Dst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%0Est/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%0Fst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%10st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%11st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%12st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%13st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%14st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%15st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%16st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%17st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%18st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%19st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%1Ast/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%1Bst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%1Cst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%1Dst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%1Est/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%1Fst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%20st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%23st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%25st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%2Fst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%3Ast/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%3Cst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%3Est/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%3Fst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%40st/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%5Bst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%5Cst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%5Dst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%7Cst/", + "base": "about:blank", + "failure": true + }, + { + "input": "http://ho%7Fst/", + "base": "about:blank", + "failure": true + }, + "Allowed host/domain code points", + { + "input": "http://!\"$&'()*+,-.;=_`{}~/", + "base": "about:blank", + "href": "http://!\"$&'()*+,-.;=_`{}~/", + "origin": "http://!\"$&'()*+,-.;=_`{}~", + "protocol": "http:", + "username": "", + "password": "", + "host": "!\"$&'()*+,-.;=_`{}~", + "hostname": "!\"$&'()*+,-.;=_`{}~", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "sc://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$%&'()*+,-.;=_`{}~/", + "base": "about:blank", + "href": "sc://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~/", + "origin": "null", + "protocol": "sc:", + "username": "", + "password": "", + "host": "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~", + "hostname": "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + "# Hosts and percent-encoding", + { + "input": "ftp://example.com%80/", + "base": "about:blank", + "failure": true + }, + { + "input": "ftp://example.com%A0/", + "base": "about:blank", + "failure": true + }, + { + "input": "https://example.com%80/", + "base": "about:blank", + "failure": true + }, + { + "input": "https://example.com%A0/", + "base": "about:blank", + "failure": true + }, + { + "input": "ftp://%e2%98%83", + "base": "about:blank", + "href": "ftp://xn--n3h/", + "origin": "ftp://xn--n3h", + "protocol": "ftp:", + "username": "", + "password": "", + "host": "xn--n3h", + "hostname": "xn--n3h", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "https://%e2%98%83", + "base": "about:blank", + "href": "https://xn--n3h/", + "origin": "https://xn--n3h", + "protocol": "https:", + "username": "", + "password": "", + "host": "xn--n3h", + "hostname": "xn--n3h", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + "# tests from jsdom/whatwg-url designed for code coverage", + { + "input": "http://127.0.0.1:10100/relative_import.html", + "base": "about:blank", + "href": "http://127.0.0.1:10100/relative_import.html", + "origin": "http://127.0.0.1:10100", + "protocol": "http:", + "username": "", + "password": "", + "host": "127.0.0.1:10100", + "hostname": "127.0.0.1", + "port": "10100", + "pathname": "/relative_import.html", + "search": "", + "hash": "" + }, + { + "input": "http://facebook.com/?foo=%7B%22abc%22", + "base": "about:blank", + "href": "http://facebook.com/?foo=%7B%22abc%22", + "origin": "http://facebook.com", + "protocol": "http:", + "username": "", + "password": "", + "host": "facebook.com", + "hostname": "facebook.com", + "port": "", + "pathname": "/", + "search": "?foo=%7B%22abc%22", + "hash": "" + }, + { + "input": "https://localhost:3000/jqueryui@1.2.3", + "base": "about:blank", + "href": "https://localhost:3000/jqueryui@1.2.3", + "origin": "https://localhost:3000", + "protocol": "https:", + "username": "", + "password": "", + "host": "localhost:3000", + "hostname": "localhost", + "port": "3000", + "pathname": "/jqueryui@1.2.3", + "search": "", + "hash": "" + }, + "# tab/LF/CR", + { + "input": "h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg", + "base": "about:blank", + "href": "http://host:9000/path?query#frag", + "origin": "http://host:9000", + "protocol": "http:", + "username": "", + "password": "", + "host": "host:9000", + "hostname": "host", + "port": "9000", + "pathname": "/path", + "search": "?query", + "hash": "#frag" + }, + "# Stringification of URL.searchParams", + { + "input": "?a=b&c=d", + "base": "http://example.org/foo/bar", + "href": "http://example.org/foo/bar?a=b&c=d", + "origin": "http://example.org", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/foo/bar", + "search": "?a=b&c=d", + "searchParams": "a=b&c=d", + "hash": "" + }, + { + "input": "??a=b&c=d", + "base": "http://example.org/foo/bar", + "href": "http://example.org/foo/bar??a=b&c=d", + "origin": "http://example.org", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/foo/bar", + "search": "??a=b&c=d", + "searchParams": "%3Fa=b&c=d", + "hash": "" + }, + "# Scheme only", + { + "input": "http:", + "base": "http://example.org/foo/bar", + "href": "http://example.org/foo/bar", + "origin": "http://example.org", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", "pathname": "/foo/bar", "search": "", - "searchParams": "", + "searchParams": "", + "hash": "" + }, + { + "input": "http:", + "base": "https://example.org/foo/bar", + "failure": true + }, + { + "input": "sc:", + "base": "https://example.org/foo/bar", + "href": "sc:", + "origin": "null", + "protocol": "sc:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "", + "search": "", + "searchParams": "", + "hash": "" + }, + "# Percent encoding of fragments", + { + "input": "http://foo.bar/baz?qux#foo\bbar", + "base": "about:blank", + "href": "http://foo.bar/baz?qux#foo%08bar", + "origin": "http://foo.bar", + "protocol": "http:", + "username": "", + "password": "", + "host": "foo.bar", + "hostname": "foo.bar", + "port": "", + "pathname": "/baz", + "search": "?qux", + "searchParams": "qux=", + "hash": "#foo%08bar" + }, + { + "input": "http://foo.bar/baz?qux#foo\"bar", + "base": "about:blank", + "href": "http://foo.bar/baz?qux#foo%22bar", + "origin": "http://foo.bar", + "protocol": "http:", + "username": "", + "password": "", + "host": "foo.bar", + "hostname": "foo.bar", + "port": "", + "pathname": "/baz", + "search": "?qux", + "searchParams": "qux=", + "hash": "#foo%22bar" + }, + { + "input": "http://foo.bar/baz?qux#foobar", + "base": "about:blank", + "href": "http://foo.bar/baz?qux#foo%3Ebar", + "origin": "http://foo.bar", + "protocol": "http:", + "username": "", + "password": "", + "host": "foo.bar", + "hostname": "foo.bar", + "port": "", + "pathname": "/baz", + "search": "?qux", + "searchParams": "qux=", + "hash": "#foo%3Ebar" + }, + { + "input": "http://foo.bar/baz?qux#foo`bar", + "base": "about:blank", + "href": "http://foo.bar/baz?qux#foo%60bar", + "origin": "http://foo.bar", + "protocol": "http:", + "username": "", + "password": "", + "host": "foo.bar", + "hostname": "foo.bar", + "port": "", + "pathname": "/baz", + "search": "?qux", + "searchParams": "qux=", + "hash": "#foo%60bar" + }, + "# IPv4 parsing (via https://github.com/nodejs/node/pull/10317)", + { + "input": "http://1.2.3.4/", + "base": "http://other.com/", + "href": "http://1.2.3.4/", + "origin": "http://1.2.3.4", + "protocol": "http:", + "username": "", + "password": "", + "host": "1.2.3.4", + "hostname": "1.2.3.4", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://1.2.3.4./", + "base": "http://other.com/", + "href": "http://1.2.3.4/", + "origin": "http://1.2.3.4", + "protocol": "http:", + "username": "", + "password": "", + "host": "1.2.3.4", + "hostname": "1.2.3.4", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://192.168.257", + "base": "http://other.com/", + "href": "http://192.168.1.1/", + "origin": "http://192.168.1.1", + "protocol": "http:", + "username": "", + "password": "", + "host": "192.168.1.1", + "hostname": "192.168.1.1", + "port": "", + "pathname": "/", + "search": "", "hash": "" }, { - "input": "http:", - "base": "https://example.org/foo/bar", + "input": "http://192.168.257.", + "base": "http://other.com/", + "href": "http://192.168.1.1/", + "origin": "http://192.168.1.1", + "protocol": "http:", + "username": "", + "password": "", + "host": "192.168.1.1", + "hostname": "192.168.1.1", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://192.168.257.com", + "base": "http://other.com/", + "href": "http://192.168.257.com/", + "origin": "http://192.168.257.com", + "protocol": "http:", + "username": "", + "password": "", + "host": "192.168.257.com", + "hostname": "192.168.257.com", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://256", + "base": "http://other.com/", + "href": "http://0.0.1.0/", + "origin": "http://0.0.1.0", + "protocol": "http:", + "username": "", + "password": "", + "host": "0.0.1.0", + "hostname": "0.0.1.0", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://256.com", + "base": "http://other.com/", + "href": "http://256.com/", + "origin": "http://256.com", + "protocol": "http:", + "username": "", + "password": "", + "host": "256.com", + "hostname": "256.com", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://999999999", + "base": "http://other.com/", + "href": "http://59.154.201.255/", + "origin": "http://59.154.201.255", + "protocol": "http:", + "username": "", + "password": "", + "host": "59.154.201.255", + "hostname": "59.154.201.255", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://999999999.", + "base": "http://other.com/", + "href": "http://59.154.201.255/", + "origin": "http://59.154.201.255", + "protocol": "http:", + "username": "", + "password": "", + "host": "59.154.201.255", + "hostname": "59.154.201.255", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://999999999.com", + "base": "http://other.com/", + "href": "http://999999999.com/", + "origin": "http://999999999.com", + "protocol": "http:", + "username": "", + "password": "", + "host": "999999999.com", + "hostname": "999999999.com", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://10000000000", + "base": "http://other.com/", "failure": true }, { - "input": "sc:", - "base": "https://example.org/foo/bar", - "href": "sc:", - "origin": "null", - "protocol": "sc:", + "input": "http://10000000000.com", + "base": "http://other.com/", + "href": "http://10000000000.com/", + "origin": "http://10000000000.com", + "protocol": "http:", + "username": "", + "password": "", + "host": "10000000000.com", + "hostname": "10000000000.com", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://4294967295", + "base": "http://other.com/", + "href": "http://255.255.255.255/", + "origin": "http://255.255.255.255", + "protocol": "http:", + "username": "", + "password": "", + "host": "255.255.255.255", + "hostname": "255.255.255.255", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://4294967296", + "base": "http://other.com/", + "failure": true + }, + { + "input": "http://0xffffffff", + "base": "http://other.com/", + "href": "http://255.255.255.255/", + "origin": "http://255.255.255.255", + "protocol": "http:", + "username": "", + "password": "", + "host": "255.255.255.255", + "hostname": "255.255.255.255", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://0xffffffff1", + "base": "http://other.com/", + "failure": true + }, + { + "input": "http://256.256.256.256", + "base": "http://other.com/", + "failure": true + }, + { + "input": "https://0x.0x.0", + "base": "about:blank", + "href": "https://0.0.0.0/", + "origin": "https://0.0.0.0", + "protocol": "https:", + "username": "", + "password": "", + "host": "0.0.0.0", + "hostname": "0.0.0.0", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)", + { + "input": "https://0x100000000/test", + "base": "about:blank", + "failure": true + }, + { + "input": "https://256.0.0.1/test", + "base": "about:blank", + "failure": true + }, + "# file URLs containing percent-encoded Windows drive letters (shouldn't work)", + { + "input": "file:///C%3A/", + "base": "about:blank", + "href": "file:///C%3A/", + "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "", + "pathname": "/C%3A/", "search": "", - "searchParams": "", "hash": "" }, - "# Percent encoding of fragments", { - "input": "http://foo.bar/baz?qux#foo\bbar", + "input": "file:///C%7C/", "base": "about:blank", - "href": "http://foo.bar/baz?qux#foo%08bar", - "origin": "http://foo.bar", - "protocol": "http:", + "href": "file:///C%7C/", + "protocol": "file:", "username": "", "password": "", - "host": "foo.bar", - "hostname": "foo.bar", + "host": "", + "hostname": "", "port": "", - "pathname": "/baz", - "search": "?qux", - "searchParams": "qux=", - "hash": "#foo%08bar" + "pathname": "/C%7C/", + "search": "", + "hash": "" + }, + { + "input": "file://%43%3A", + "base": "about:blank", + "failure": true + }, + { + "input": "file://%43%7C", + "base": "about:blank", + "failure": true + }, + { + "input": "file://%43|", + "base": "about:blank", + "failure": true + }, + { + "input": "file://C%7C", + "base": "about:blank", + "failure": true + }, + { + "input": "file://%43%7C/", + "base": "about:blank", + "failure": true + }, + { + "input": "https://%43%7C/", + "base": "about:blank", + "failure": true }, { - "input": "http://foo.bar/baz?qux#foo\"bar", + "input": "asdf://%43|/", "base": "about:blank", - "href": "http://foo.bar/baz?qux#foo%22bar", - "origin": "http://foo.bar", - "protocol": "http:", - "username": "", - "password": "", - "host": "foo.bar", - "hostname": "foo.bar", - "port": "", - "pathname": "/baz", - "search": "?qux", - "searchParams": "qux=", - "hash": "#foo%22bar" + "failure": true }, { - "input": "http://foo.bar/baz?qux#foobar", - "base": "about:blank", - "href": "http://foo.bar/baz?qux#foo%3Ebar", - "origin": "http://foo.bar", - "protocol": "http:", + "input": "pix/submit.gif", + "base": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html", + "href": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", + "protocol": "file:", "username": "", "password": "", - "host": "foo.bar", - "hostname": "foo.bar", + "host": "", + "hostname": "", "port": "", - "pathname": "/baz", - "search": "?qux", - "searchParams": "qux=", - "hash": "#foo%3Ebar" + "pathname": "/C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", + "search": "", + "hash": "" }, { - "input": "http://foo.bar/baz?qux#foo`bar", - "base": "about:blank", - "href": "http://foo.bar/baz?qux#foo%60bar", - "origin": "http://foo.bar", - "protocol": "http:", + "input": "..", + "base": "file:///C:/", + "href": "file:///C:/", + "protocol": "file:", "username": "", "password": "", - "host": "foo.bar", - "hostname": "foo.bar", + "host": "", + "hostname": "", "port": "", - "pathname": "/baz", - "search": "?qux", - "searchParams": "qux=", - "hash": "#foo%60bar" + "pathname": "/C:/", + "search": "", + "hash": "" }, - "# IPv4 parsing (via https://github.com/nodejs/node/pull/10317)", { - "input": "http://192.168.257", - "base": "http://other.com/", - "href": "http://192.168.1.1/", - "origin": "http://192.168.1.1", - "protocol": "http:", + "input": "..", + "base": "file:///", + "href": "file:///", + "protocol": "file:", "username": "", "password": "", - "host": "192.168.1.1", - "hostname": "192.168.1.1", + "host": "", + "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, + "# More file URL tests by zcorpan and annevk", { - "input": "http://192.168.257.com", - "base": "http://other.com/", - "href": "http://192.168.257.com/", - "origin": "http://192.168.257.com", - "protocol": "http:", + "input": "/", + "base": "file:///C:/a/b", + "href": "file:///C:/", + "protocol": "file:", "username": "", "password": "", - "host": "192.168.257.com", - "hostname": "192.168.257.com", + "host": "", + "hostname": "", "port": "", - "pathname": "/", + "pathname": "/C:/", "search": "", "hash": "" }, { - "input": "http://256", - "base": "http://other.com/", - "href": "http://0.0.1.0/", - "origin": "http://0.0.1.0", - "protocol": "http:", + "input": "/", + "base": "file://h/a/b", + "href": "file://h/", + "protocol": "file:", "username": "", "password": "", - "host": "0.0.1.0", - "hostname": "0.0.1.0", + "host": "h", + "hostname": "h", "port": "", "pathname": "/", "search": "", "hash": "" }, { - "input": "http://256.com", - "base": "http://other.com/", - "href": "http://256.com/", - "origin": "http://256.com", - "protocol": "http:", + "input": "//d:", + "base": "file:///C:/a/b", + "href": "file:///d:", + "protocol": "file:", "username": "", "password": "", - "host": "256.com", - "hostname": "256.com", + "host": "", + "hostname": "", "port": "", - "pathname": "/", + "pathname": "/d:", "search": "", "hash": "" }, { - "input": "http://999999999", - "base": "http://other.com/", - "href": "http://59.154.201.255/", - "origin": "http://59.154.201.255", - "protocol": "http:", + "input": "//d:/..", + "base": "file:///C:/a/b", + "href": "file:///d:/", + "protocol": "file:", "username": "", "password": "", - "host": "59.154.201.255", - "hostname": "59.154.201.255", + "host": "", + "hostname": "", "port": "", - "pathname": "/", + "pathname": "/d:/", "search": "", "hash": "" }, { - "input": "http://999999999.com", - "base": "http://other.com/", - "href": "http://999999999.com/", - "origin": "http://999999999.com", - "protocol": "http:", + "input": "..", + "base": "file:///ab:/", + "href": "file:///", + "protocol": "file:", "username": "", "password": "", - "host": "999999999.com", - "hostname": "999999999.com", + "host": "", + "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { - "input": "http://10000000000", - "base": "http://other.com/", - "failure": true - }, - { - "input": "http://10000000000.com", - "base": "http://other.com/", - "href": "http://10000000000.com/", - "origin": "http://10000000000.com", - "protocol": "http:", + "input": "..", + "base": "file:///1:/", + "href": "file:///", + "protocol": "file:", "username": "", "password": "", - "host": "10000000000.com", - "hostname": "10000000000.com", + "host": "", + "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { - "input": "http://4294967295", - "base": "http://other.com/", - "href": "http://255.255.255.255/", - "origin": "http://255.255.255.255", - "protocol": "http:", + "input": "", + "base": "file:///test?test#test", + "href": "file:///test?test", + "protocol": "file:", "username": "", "password": "", - "host": "255.255.255.255", - "hostname": "255.255.255.255", + "host": "", + "hostname": "", "port": "", - "pathname": "/", - "search": "", + "pathname": "/test", + "search": "?test", "hash": "" }, { - "input": "http://4294967296", - "base": "http://other.com/", - "failure": true - }, - { - "input": "http://0xffffffff", - "base": "http://other.com/", - "href": "http://255.255.255.255/", - "origin": "http://255.255.255.255", - "protocol": "http:", + "input": "file:", + "base": "file:///test?test#test", + "href": "file:///test?test", + "protocol": "file:", "username": "", "password": "", - "host": "255.255.255.255", - "hostname": "255.255.255.255", + "host": "", + "hostname": "", "port": "", - "pathname": "/", - "search": "", + "pathname": "/test", + "search": "?test", "hash": "" }, { - "input": "http://0xffffffff1", - "base": "http://other.com/", - "failure": true - }, - { - "input": "http://256.256.256.256", - "base": "http://other.com/", - "failure": true + "input": "?x", + "base": "file:///test?test#test", + "href": "file:///test?x", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/test", + "search": "?x", + "hash": "" }, { - "input": "http://256.256.256.256.256", - "base": "http://other.com/", - "href": "http://256.256.256.256.256/", - "origin": "http://256.256.256.256.256", - "protocol": "http:", + "input": "file:?x", + "base": "file:///test?test#test", + "href": "file:///test?x", + "protocol": "file:", "username": "", "password": "", - "host": "256.256.256.256.256", - "hostname": "256.256.256.256.256", + "host": "", + "hostname": "", "port": "", - "pathname": "/", - "search": "", + "pathname": "/test", + "search": "?x", "hash": "" }, { - "input": "https://0x.0x.0", - "base": "about:blank", - "href": "https://0.0.0.0/", - "origin": "https://0.0.0.0", - "protocol": "https:", + "input": "#x", + "base": "file:///test?test#test", + "href": "file:///test?test#x", + "protocol": "file:", "username": "", "password": "", - "host": "0.0.0.0", - "hostname": "0.0.0.0", + "host": "", + "hostname": "", "port": "", - "pathname": "/", - "search": "", - "hash": "" - }, - "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)", - { - "input": "https://0x100000000/test", - "base": "about:blank", - "failure": true + "pathname": "/test", + "search": "?test", + "hash": "#x" }, { - "input": "https://256.0.0.1/test", - "base": "about:blank", - "failure": true + "input": "file:#x", + "base": "file:///test?test#test", + "href": "file:///test?test#x", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/test", + "search": "?test", + "hash": "#x" }, - "# file URLs containing percent-encoded Windows drive letters (shouldn't work)", + "# File URLs and many (back)slashes", { - "input": "file:///C%3A/", + "input": "file:///localhost//cat", "base": "about:blank", - "href": "file:///C%3A/", + "href": "file:///localhost//cat", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/C%3A/", + "pathname": "/localhost//cat", "search": "", "hash": "" }, { - "input": "file:///C%7C/", - "base": "about:blank", - "href": "file:///C%7C/", + "input": "\\//pig", + "base": "file://lion/", + "href": "file:///pig", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/C%7C/", + "pathname": "/pig", "search": "", "hash": "" }, - "# file URLs relative to other file URLs (via https://github.com/jsdom/whatwg-url/pull/60)", { - "input": "pix/submit.gif", - "base": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html", - "href": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", + "input": "file://", + "base": "file://ape/", + "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", + "pathname": "/", "search": "", "hash": "" }, + "# File URLs with non-empty hosts", { - "input": "..", - "base": "file:///C:/", - "href": "file:///C:/", + "input": "/rooibos", + "base": "file://tea/", + "href": "file://tea/rooibos", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "tea", + "hostname": "tea", "port": "", - "pathname": "/C:/", + "pathname": "/rooibos", "search": "", "hash": "" }, { - "input": "..", - "base": "file:///", - "href": "file:///", + "input": "/?chai", + "base": "file://tea/", + "href": "file://tea/?chai", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "tea", + "hostname": "tea", "port": "", "pathname": "/", - "search": "", + "search": "?chai", "hash": "" }, - "# More file URL tests by zcorpan and annevk", + "# Windows drive letter handling with the 'file:' base URL", { - "input": "/", - "base": "file:///C:/a/b", - "href": "file:///C:/", + "input": "C", + "base": "file://host/dir/file", + "href": "file://host/dir/C", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", - "pathname": "/C:/", + "pathname": "/dir/C", "search": "", "hash": "" }, { - "input": "//d:", - "base": "file:///C:/a/b", - "href": "file:///d:", + "input": "C|a", + "base": "file://host/dir/file", + "href": "file://host/dir/C|a", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "host", + "hostname": "host", "port": "", - "pathname": "/d:", + "pathname": "/dir/C|a", "search": "", "hash": "" }, + "# Windows drive letter quirk in the file slash state", { - "input": "//d:/..", - "base": "file:///C:/a/b", - "href": "file:///d:/", + "input": "/c:/foo/bar", + "base": "file:///c:/baz/qux", + "href": "file:///c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/d:/", + "pathname": "/c:/foo/bar", "search": "", "hash": "" }, { - "input": "..", - "base": "file:///ab:/", - "href": "file:///", + "input": "/c|/foo/bar", + "base": "file:///c:/baz/qux", + "href": "file:///c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "/c:/foo/bar", "search": "", "hash": "" }, { - "input": "..", - "base": "file:///1:/", - "href": "file:///", + "input": "file:\\c:\\foo\\bar", + "base": "file:///c:/baz/qux", + "href": "file:///c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "/c:/foo/bar", "search": "", "hash": "" }, + "# Copy the empty host from the input in the following cases", { - "input": "", - "base": "file:///test?test#test", - "href": "file:///test?test", + "input": "//C:/", + "base": "file://host/", + "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/test", - "search": "?test", + "pathname": "/C:/", + "search": "", "hash": "" }, { - "input": "file:", - "base": "file:///test?test#test", - "href": "file:///test?test", + "input": "file://C:/", + "base": "file://host/", + "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/test", - "search": "?test", + "pathname": "/C:/", + "search": "", "hash": "" }, { - "input": "?x", - "base": "file:///test?test#test", - "href": "file:///test?x", + "input": "///C:/", + "base": "file://host/", + "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/test", - "search": "?x", + "pathname": "/C:/", + "search": "", "hash": "" }, { - "input": "file:?x", - "base": "file:///test?test#test", - "href": "file:///test?x", + "input": "file:///C:/", + "base": "file://host/", + "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/test", - "search": "?x", + "pathname": "/C:/", + "search": "", "hash": "" }, + "# Windows drive letter quirk (no host)", { - "input": "#x", - "base": "file:///test?test#test", - "href": "file:///test?test#x", + "input": "file:/C|/", + "base": "about:blank", + "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/test", - "search": "?test", - "hash": "#x" + "pathname": "/C:/", + "search": "", + "hash": "" }, { - "input": "file:#x", - "base": "file:///test?test#test", - "href": "file:///test?test#x", + "input": "file://C|/", + "base": "about:blank", + "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/test", - "search": "?test", - "hash": "#x" + "pathname": "/C:/", + "search": "", + "hash": "" }, - "# File URLs and many (back)slashes", + "# file URLs without base URL by Rimas Misevičius", { - "input": "file:\\\\//", + "input": "file:", "base": "about:blank", "href": "file:///", "protocol": "file:", @@ -5402,9 +6295,9 @@ "hash": "" }, { - "input": "file:\\\\\\\\", + "input": "file:?q=v", "base": "about:blank", - "href": "file:///", + "href": "file:///?q=v", "protocol": "file:", "username": "", "password": "", @@ -5412,13 +6305,13 @@ "hostname": "", "port": "", "pathname": "/", - "search": "", + "search": "?q=v", "hash": "" }, { - "input": "file:\\\\\\\\?fox", + "input": "file:#frag", "base": "about:blank", - "href": "file:///?fox", + "href": "file:///#frag", "protocol": "file:", "username": "", "password": "", @@ -5426,1566 +6319,1590 @@ "hostname": "", "port": "", "pathname": "/", - "search": "?fox", - "hash": "" + "search": "", + "hash": "#frag" }, + "# file: drive letter cases from https://crbug.com/1078698", { - "input": "file:\\\\\\\\#guppy", + "input": "file:///Y:", "base": "about:blank", - "href": "file:///#guppy", + "href": "file:///Y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "/Y:", "search": "", - "hash": "#guppy" + "hash": "" }, { - "input": "file://spider///", + "input": "file:///Y:/", "base": "about:blank", - "href": "file://spider/", + "href": "file:///Y:/", "protocol": "file:", "username": "", "password": "", - "host": "spider", - "hostname": "spider", + "host": "", + "hostname": "", "port": "", - "pathname": "/", + "pathname": "/Y:/", "search": "", "hash": "" }, { - "input": "file:\\\\localhost//", + "input": "file:///./Y", "base": "about:blank", - "href": "file:///", + "href": "file:///Y", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "/Y", "search": "", "hash": "" }, { - "input": "file:///localhost//cat", + "input": "file:///./Y:", "base": "about:blank", - "href": "file:///localhost//cat", + "href": "file:///Y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/localhost//cat", + "pathname": "/Y:", "search": "", "hash": "" }, { - "input": "file://\\/localhost//cat", + "input": "\\\\\\.\\Y:", "base": "about:blank", - "href": "file:///localhost//cat", + "failure": true, + "inputCanBeRelative": true + }, + "# file: drive letter cases from https://crbug.com/1078698 but lowercased", + { + "input": "file:///y:", + "base": "about:blank", + "href": "file:///y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/localhost//cat", + "pathname": "/y:", "search": "", "hash": "" }, { - "input": "file://localhost//a//../..//", + "input": "file:///y:/", "base": "about:blank", - "href": "file:///", + "href": "file:///y:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "/y:/", "search": "", "hash": "" }, { - "input": "/////mouse", - "base": "file:///elephant", - "href": "file:///mouse", + "input": "file:///./y", + "base": "about:blank", + "href": "file:///y", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/mouse", + "pathname": "/y", "search": "", "hash": "" }, { - "input": "\\//pig", - "base": "file://lion/", - "href": "file:///pig", + "input": "file:///./y:", + "base": "about:blank", + "href": "file:///y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/pig", + "pathname": "/y:", "search": "", "hash": "" }, { - "input": "\\/localhost//pig", - "base": "file://lion/", - "href": "file:///pig", + "input": "\\\\\\.\\y:", + "base": "about:blank", + "failure": true, + "inputCanBeRelative": true + }, + "# Additional file URL tests for (https://github.com/whatwg/url/issues/405)", + { + "input": "file:///one/two", + "base": "file:///", + "href": "file:///one/two", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/pig", + "pathname": "/one/two", "search": "", "hash": "" }, { - "input": "//localhost//pig", - "base": "file://lion/", - "href": "file:///pig", + "input": "//one/two", + "base": "file:///", + "href": "file://one/two", "protocol": "file:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "one", + "hostname": "one", "port": "", - "pathname": "/pig", + "pathname": "/two", "search": "", "hash": "" }, { - "input": "/..//localhost//pig", - "base": "file://lion/", - "href": "file://lion/localhost//pig", + "input": "///one/two", + "base": "file:///", + "href": "file:///one/two", "protocol": "file:", "username": "", "password": "", - "host": "lion", - "hostname": "lion", + "host": "", + "hostname": "", "port": "", - "pathname": "/localhost//pig", + "pathname": "/one/two", "search": "", "hash": "" }, + "# IPv6 tests", { - "input": "file://", - "base": "file://ape/", - "href": "file:///", - "protocol": "file:", + "input": "http://[1:0::]", + "base": "http://example.net/", + "href": "http://[1::]/", + "origin": "http://[1::]", + "protocol": "http:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "[1::]", + "hostname": "[1::]", "port": "", "pathname": "/", "search": "", "hash": "" }, - "# File URLs with non-empty hosts", { - "input": "/rooibos", - "base": "file://tea/", - "href": "file://tea/rooibos", - "protocol": "file:", + "input": "http://[0:1:2:3:4:5:6:7:8]", + "base": "http://example.net/", + "failure": true + }, + { + "input": "https://[0::0::0]", + "base": "about:blank", + "failure": true + }, + { + "input": "https://[0:.0]", + "base": "about:blank", + "failure": true + }, + { + "input": "https://[0:0:]", + "base": "about:blank", + "failure": true + }, + { + "input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]", + "base": "about:blank", + "failure": true + }, + { + "input": "https://[0:1.00.0.0.0]", + "base": "about:blank", + "failure": true + }, + { + "input": "https://[0:1.290.0.0.0]", + "base": "about:blank", + "failure": true + }, + { + "input": "https://[0:1.23.23]", + "base": "about:blank", + "failure": true + }, + "# Empty host", + { + "input": "http://?", + "base": "about:blank", + "failure": true + }, + { + "input": "http://#", + "base": "about:blank", + "failure": true + }, + "Port overflow (2^32 + 81)", + { + "input": "http://f:4294967377/c", + "base": "http://example.org/", + "failure": true + }, + "Port overflow (2^64 + 81)", + { + "input": "http://f:18446744073709551697/c", + "base": "http://example.org/", + "failure": true + }, + "Port overflow (2^128 + 81)", + { + "input": "http://f:340282366920938463463374607431768211537/c", + "base": "http://example.org/", + "failure": true + }, + "# Non-special-URL path tests", + { + "input": "sc://ñ", + "base": "about:blank", + "href": "sc://%C3%B1", + "origin": "null", + "protocol": "sc:", "username": "", "password": "", - "host": "tea", - "hostname": "tea", + "host": "%C3%B1", + "hostname": "%C3%B1", "port": "", - "pathname": "/rooibos", + "pathname": "", "search": "", "hash": "" }, { - "input": "/?chai", - "base": "file://tea/", - "href": "file://tea/?chai", - "protocol": "file:", + "input": "sc://ñ?x", + "base": "about:blank", + "href": "sc://%C3%B1?x", + "origin": "null", + "protocol": "sc:", "username": "", "password": "", - "host": "tea", - "hostname": "tea", + "host": "%C3%B1", + "hostname": "%C3%B1", "port": "", - "pathname": "/", - "search": "?chai", + "pathname": "", + "search": "?x", "hash": "" }, - "# Windows drive letter handling with the 'file:' base URL", { - "input": "C|", - "base": "file://host/dir/file", - "href": "file:///C:", - "protocol": "file:", + "input": "sc://ñ#x", + "base": "about:blank", + "href": "sc://%C3%B1#x", + "origin": "null", + "protocol": "sc:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "%C3%B1", + "hostname": "%C3%B1", "port": "", - "pathname": "/C:", + "pathname": "", "search": "", - "hash": "" + "hash": "#x" }, { - "input": "C|#", - "base": "file://host/dir/file", - "href": "file:///C:#", - "protocol": "file:", + "input": "#x", + "base": "sc://ñ", + "href": "sc://%C3%B1#x", + "origin": "null", + "protocol": "sc:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "%C3%B1", + "hostname": "%C3%B1", "port": "", - "pathname": "/C:", + "pathname": "", "search": "", - "hash": "" + "hash": "#x" }, { - "input": "C|?", - "base": "file://host/dir/file", - "href": "file:///C:?", - "protocol": "file:", + "input": "?x", + "base": "sc://ñ", + "href": "sc://%C3%B1?x", + "origin": "null", + "protocol": "sc:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "%C3%B1", + "hostname": "%C3%B1", "port": "", - "pathname": "/C:", - "search": "", + "pathname": "", + "search": "?x", "hash": "" }, { - "input": "C|/", - "base": "file://host/dir/file", - "href": "file:///C:/", - "protocol": "file:", + "input": "sc://?", + "base": "about:blank", + "href": "sc://?", + "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/C:/", + "pathname": "", "search": "", "hash": "" }, { - "input": "C|\n/", - "base": "file://host/dir/file", - "href": "file:///C:/", - "protocol": "file:", + "input": "sc://#", + "base": "about:blank", + "href": "sc://#", + "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/C:/", + "pathname": "", "search": "", "hash": "" }, { - "input": "C|\\", - "base": "file://host/dir/file", - "href": "file:///C:/", - "protocol": "file:", + "input": "///", + "base": "sc://x/", + "href": "sc:///", + "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/C:/", + "pathname": "/", "search": "", "hash": "" }, { - "input": "C", - "base": "file://host/dir/file", - "href": "file://host/dir/C", - "protocol": "file:", + "input": "////", + "base": "sc://x/", + "href": "sc:////", + "protocol": "sc:", "username": "", "password": "", - "host": "host", - "hostname": "host", + "host": "", + "hostname": "", "port": "", - "pathname": "/dir/C", + "pathname": "//", "search": "", "hash": "" }, { - "input": "C|a", - "base": "file://host/dir/file", - "href": "file://host/dir/C|a", - "protocol": "file:", + "input": "////x/", + "base": "sc://x/", + "href": "sc:////x/", + "protocol": "sc:", "username": "", "password": "", - "host": "host", - "hostname": "host", + "host": "", + "hostname": "", "port": "", - "pathname": "/dir/C|a", + "pathname": "//x/", "search": "", "hash": "" }, - "# Windows drive letter quirk in the file slash state", { - "input": "/c:/foo/bar", - "base": "file:///c:/baz/qux", - "href": "file:///c:/foo/bar", - "protocol": "file:", + "input": "tftp://foobar.com/someconfig;mode=netascii", + "base": "about:blank", + "href": "tftp://foobar.com/someconfig;mode=netascii", + "origin": "null", + "protocol": "tftp:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "foobar.com", + "hostname": "foobar.com", "port": "", - "pathname": "/c:/foo/bar", + "pathname": "/someconfig;mode=netascii", "search": "", "hash": "" }, { - "input": "/c|/foo/bar", - "base": "file:///c:/baz/qux", - "href": "file:///c:/foo/bar", - "protocol": "file:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/c:/foo/bar", + "input": "telnet://user:pass@foobar.com:23/", + "base": "about:blank", + "href": "telnet://user:pass@foobar.com:23/", + "origin": "null", + "protocol": "telnet:", + "username": "user", + "password": "pass", + "host": "foobar.com:23", + "hostname": "foobar.com", + "port": "23", + "pathname": "/", "search": "", "hash": "" }, { - "input": "file:\\c:\\foo\\bar", - "base": "file:///c:/baz/qux", - "href": "file:///c:/foo/bar", - "protocol": "file:", + "input": "ut2004://10.10.10.10:7777/Index.ut2", + "base": "about:blank", + "href": "ut2004://10.10.10.10:7777/Index.ut2", + "origin": "null", + "protocol": "ut2004:", "username": "", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/c:/foo/bar", + "host": "10.10.10.10:7777", + "hostname": "10.10.10.10", + "port": "7777", + "pathname": "/Index.ut2", "search": "", "hash": "" }, { - "input": "/c:/foo/bar", - "base": "file://host/path", - "href": "file:///c:/foo/bar", - "protocol": "file:", - "username": "", + "input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", + "base": "about:blank", + "href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", + "origin": "null", + "protocol": "redis:", + "username": "foo", + "password": "bar", + "host": "somehost:6379", + "hostname": "somehost", + "port": "6379", + "pathname": "/0", + "search": "?baz=bam&qux=baz", + "hash": "" + }, + { + "input": "rsync://foo@host:911/sup", + "base": "about:blank", + "href": "rsync://foo@host:911/sup", + "origin": "null", + "protocol": "rsync:", + "username": "foo", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/c:/foo/bar", + "host": "host:911", + "hostname": "host", + "port": "911", + "pathname": "/sup", "search": "", "hash": "" }, - "# Windows drive letter quirk with not empty host", { - "input": "file://example.net/C:/", + "input": "git://github.com/foo/bar.git", "base": "about:blank", - "href": "file:///C:/", - "protocol": "file:", + "href": "git://github.com/foo/bar.git", + "origin": "null", + "protocol": "git:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "github.com", + "hostname": "github.com", "port": "", - "pathname": "/C:/", + "pathname": "/foo/bar.git", "search": "", "hash": "" }, { - "input": "file://1.2.3.4/C:/", + "input": "irc://myserver.com:6999/channel?passwd", "base": "about:blank", - "href": "file:///C:/", - "protocol": "file:", + "href": "irc://myserver.com:6999/channel?passwd", + "origin": "null", + "protocol": "irc:", "username": "", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/C:/", - "search": "", + "host": "myserver.com:6999", + "hostname": "myserver.com", + "port": "6999", + "pathname": "/channel", + "search": "?passwd", "hash": "" }, { - "input": "file://[1::8]/C:/", + "input": "dns://fw.example.org:9999/foo.bar.org?type=TXT", "base": "about:blank", - "href": "file:///C:/", - "protocol": "file:", + "href": "dns://fw.example.org:9999/foo.bar.org?type=TXT", + "origin": "null", + "protocol": "dns:", "username": "", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/C:/", - "search": "", + "host": "fw.example.org:9999", + "hostname": "fw.example.org", + "port": "9999", + "pathname": "/foo.bar.org", + "search": "?type=TXT", "hash": "" }, - "# Windows drive letter quirk (no host)", { - "input": "file:/C|/", + "input": "ldap://localhost:389/ou=People,o=JNDITutorial", "base": "about:blank", - "href": "file:///C:/", - "protocol": "file:", + "href": "ldap://localhost:389/ou=People,o=JNDITutorial", + "origin": "null", + "protocol": "ldap:", "username": "", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/C:/", + "host": "localhost:389", + "hostname": "localhost", + "port": "389", + "pathname": "/ou=People,o=JNDITutorial", "search": "", "hash": "" }, { - "input": "file://C|/", + "input": "git+https://github.com/foo/bar", "base": "about:blank", - "href": "file:///C:/", - "protocol": "file:", + "href": "git+https://github.com/foo/bar", + "origin": "null", + "protocol": "git+https:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "github.com", + "hostname": "github.com", "port": "", - "pathname": "/C:/", + "pathname": "/foo/bar", "search": "", "hash": "" }, - "# file URLs without base URL by Rimas Misevičius", { - "input": "file:", + "input": "urn:ietf:rfc:2648", "base": "about:blank", - "href": "file:///", - "protocol": "file:", + "href": "urn:ietf:rfc:2648", + "origin": "null", + "protocol": "urn:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "ietf:rfc:2648", "search": "", "hash": "" }, { - "input": "file:?q=v", + "input": "tag:joe@example.org,2001:foo/bar", "base": "about:blank", - "href": "file:///?q=v", - "protocol": "file:", + "href": "tag:joe@example.org,2001:foo/bar", + "origin": "null", + "protocol": "tag:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", - "search": "?q=v", + "pathname": "joe@example.org,2001:foo/bar", + "search": "", "hash": "" }, + "# percent encoded hosts in non-special-URLs", { - "input": "file:#frag", + "input": "non-special://%E2%80%A0/", "base": "about:blank", - "href": "file:///#frag", - "protocol": "file:", + "href": "non-special://%E2%80%A0/", + "protocol": "non-special:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "%E2%80%A0", + "hostname": "%E2%80%A0", "port": "", "pathname": "/", "search": "", - "hash": "#frag" + "hash": "" }, - "# file: drive letter cases from https://crbug.com/1078698", { - "input": "file:///Y:", + "input": "non-special://H%4fSt/path", "base": "about:blank", - "href": "file:///Y:", - "protocol": "file:", + "href": "non-special://H%4fSt/path", + "protocol": "non-special:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "H%4fSt", + "hostname": "H%4fSt", "port": "", - "pathname": "/Y:", + "pathname": "/path", "search": "", "hash": "" }, + "# IPv6 in non-special-URLs", { - "input": "file:///Y:/", + "input": "non-special://[1:2:0:0:5:0:0:0]/", "base": "about:blank", - "href": "file:///Y:/", - "protocol": "file:", + "href": "non-special://[1:2:0:0:5::]/", + "protocol": "non-special:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "[1:2:0:0:5::]", + "hostname": "[1:2:0:0:5::]", "port": "", - "pathname": "/Y:/", + "pathname": "/", "search": "", "hash": "" }, { - "input": "file:///./Y", + "input": "non-special://[1:2:0:0:0:0:0:3]/", "base": "about:blank", - "href": "file:///Y", - "protocol": "file:", + "href": "non-special://[1:2::3]/", + "protocol": "non-special:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "[1:2::3]", + "hostname": "[1:2::3]", "port": "", - "pathname": "/Y", + "pathname": "/", "search": "", "hash": "" }, { - "input": "file:///./Y:", + "input": "non-special://[1:2::3]:80/", "base": "about:blank", - "href": "file:///Y:", - "protocol": "file:", + "href": "non-special://[1:2::3]:80/", + "protocol": "non-special:", "username": "", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/Y:", + "host": "[1:2::3]:80", + "hostname": "[1:2::3]", + "port": "80", + "pathname": "/", "search": "", "hash": "" }, { - "input": "\\\\\\.\\Y:", + "input": "non-special://[:80/", "base": "about:blank", "failure": true }, - "# file: drive letter cases from https://crbug.com/1078698 but lowercased", - { - "input": "file:///y:", - "base": "about:blank", - "href": "file:///y:", - "protocol": "file:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/y:", - "search": "", - "hash": "" - }, { - "input": "file:///y:/", + "input": "blob:https://example.com:443/", "base": "about:blank", - "href": "file:///y:/", - "protocol": "file:", + "href": "blob:https://example.com:443/", + "origin": "https://example.com", + "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/y:/", + "pathname": "https://example.com:443/", "search": "", "hash": "" }, { - "input": "file:///./y", + "input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", "base": "about:blank", - "href": "file:///y", - "protocol": "file:", + "href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", + "origin": "null", + "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/y", + "pathname": "d3958f5c-0777-0845-9dcf-2cb28783acaf", "search": "", "hash": "" }, { - "input": "file:///./y:", + "input": "blob:", "base": "about:blank", - "href": "file:///y:", - "protocol": "file:", + "href": "blob:", + "origin": "null", + "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/y:", + "pathname": "", "search": "", "hash": "" }, + "Invalid IPv4 radix digits", { - "input": "\\\\\\.\\y:", + "input": "http://0x7f.0.0.0x7g", "base": "about:blank", - "failure": true - }, - "# IPv6 tests", - { - "input": "http://[1:0::]", - "base": "http://example.net/", - "href": "http://[1::]/", - "origin": "http://[1::]", + "href": "http://0x7f.0.0.0x7g/", "protocol": "http:", "username": "", "password": "", - "host": "[1::]", - "hostname": "[1::]", + "host": "0x7f.0.0.0x7g", + "hostname": "0x7f.0.0.0x7g", "port": "", "pathname": "/", "search": "", "hash": "" }, { - "input": "http://[0:1:2:3:4:5:6:7:8]", - "base": "http://example.net/", - "failure": true - }, - { - "input": "https://[0::0::0]", - "base": "about:blank", - "failure": true - }, - { - "input": "https://[0:.0]", - "base": "about:blank", - "failure": true - }, - { - "input": "https://[0:0:]", + "input": "http://0X7F.0.0.0X7G", "base": "about:blank", - "failure": true + "href": "http://0x7f.0.0.0x7g/", + "protocol": "http:", + "username": "", + "password": "", + "host": "0x7f.0.0.0x7g", + "hostname": "0x7f.0.0.0x7g", + "port": "", + "pathname": "/", + "search": "", + "hash": "" }, + "Invalid IPv4 portion of IPv6 address", { - "input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]", + "input": "http://[::127.0.0.0.1]", "base": "about:blank", "failure": true }, + "Uncompressed IPv6 addresses with 0", { - "input": "https://[0:1.00.0.0.0]", + "input": "http://[0:1:0:1:0:1:0:1]", "base": "about:blank", - "failure": true + "href": "http://[0:1:0:1:0:1:0:1]/", + "protocol": "http:", + "username": "", + "password": "", + "host": "[0:1:0:1:0:1:0:1]", + "hostname": "[0:1:0:1:0:1:0:1]", + "port": "", + "pathname": "/", + "search": "", + "hash": "" }, { - "input": "https://[0:1.290.0.0.0]", + "input": "http://[1:0:1:0:1:0:1:0]", "base": "about:blank", - "failure": true + "href": "http://[1:0:1:0:1:0:1:0]/", + "protocol": "http:", + "username": "", + "password": "", + "host": "[1:0:1:0:1:0:1:0]", + "hostname": "[1:0:1:0:1:0:1:0]", + "port": "", + "pathname": "/", + "search": "", + "hash": "" }, + "Percent-encoded query and fragment", { - "input": "https://[0:1.23.23]", + "input": "http://example.org/test?\u0022", "base": "about:blank", - "failure": true + "href": "http://example.org/test?%22", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/test", + "search": "?%22", + "hash": "" }, - "# Empty host", { - "input": "http://?", + "input": "http://example.org/test?\u0023", "base": "about:blank", - "failure": true + "href": "http://example.org/test?#", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/test", + "search": "", + "hash": "" }, { - "input": "http://#", + "input": "http://example.org/test?\u003C", "base": "about:blank", - "failure": true - }, - "Port overflow (2^32 + 81)", - { - "input": "http://f:4294967377/c", - "base": "http://example.org/", - "failure": true - }, - "Port overflow (2^64 + 81)", - { - "input": "http://f:18446744073709551697/c", - "base": "http://example.org/", - "failure": true - }, - "Port overflow (2^128 + 81)", - { - "input": "http://f:340282366920938463463374607431768211537/c", - "base": "http://example.org/", - "failure": true + "href": "http://example.org/test?%3C", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/test", + "search": "?%3C", + "hash": "" }, - "# Non-special-URL path tests", { - "input": "sc://ñ", + "input": "http://example.org/test?\u003E", "base": "about:blank", - "href": "sc://%C3%B1", - "origin": "null", - "protocol": "sc:", + "href": "http://example.org/test?%3E", + "protocol": "http:", "username": "", "password": "", - "host": "%C3%B1", - "hostname": "%C3%B1", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "", - "search": "", + "pathname": "/test", + "search": "?%3E", "hash": "" }, { - "input": "sc://ñ?x", + "input": "http://example.org/test?\u2323", "base": "about:blank", - "href": "sc://%C3%B1?x", - "origin": "null", - "protocol": "sc:", + "href": "http://example.org/test?%E2%8C%A3", + "protocol": "http:", "username": "", "password": "", - "host": "%C3%B1", - "hostname": "%C3%B1", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "", - "search": "?x", + "pathname": "/test", + "search": "?%E2%8C%A3", "hash": "" }, { - "input": "sc://ñ#x", + "input": "http://example.org/test?%23%23", "base": "about:blank", - "href": "sc://%C3%B1#x", - "origin": "null", - "protocol": "sc:", + "href": "http://example.org/test?%23%23", + "protocol": "http:", "username": "", "password": "", - "host": "%C3%B1", - "hostname": "%C3%B1", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "", - "search": "", - "hash": "#x" + "pathname": "/test", + "search": "?%23%23", + "hash": "" }, { - "input": "#x", - "base": "sc://ñ", - "href": "sc://%C3%B1#x", - "origin": "null", - "protocol": "sc:", + "input": "http://example.org/test?%GH", + "base": "about:blank", + "href": "http://example.org/test?%GH", + "protocol": "http:", "username": "", "password": "", - "host": "%C3%B1", - "hostname": "%C3%B1", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "", - "search": "", - "hash": "#x" + "pathname": "/test", + "search": "?%GH", + "hash": "" }, { - "input": "?x", - "base": "sc://ñ", - "href": "sc://%C3%B1?x", - "origin": "null", - "protocol": "sc:", + "input": "http://example.org/test?a#%EF", + "base": "about:blank", + "href": "http://example.org/test?a#%EF", + "protocol": "http:", "username": "", "password": "", - "host": "%C3%B1", - "hostname": "%C3%B1", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "", - "search": "?x", - "hash": "" + "pathname": "/test", + "search": "?a", + "hash": "#%EF" }, { - "input": "sc://?", + "input": "http://example.org/test?a#%GH", "base": "about:blank", - "href": "sc://?", - "protocol": "sc:", + "href": "http://example.org/test?a#%GH", + "protocol": "http:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "", - "search": "", - "hash": "" + "pathname": "/test", + "search": "?a", + "hash": "#%GH" + }, + "URLs that require a non-about:blank base. (Also serve as invalid base tests.)", + { + "input": "a", + "base": "about:blank", + "failure": true, + "inputCanBeRelative": true + }, + { + "input": "a/", + "base": "about:blank", + "failure": true, + "inputCanBeRelative": true + }, + { + "input": "a//", + "base": "about:blank", + "failure": true, + "inputCanBeRelative": true + }, + "Bases that don't fail to parse but fail to be bases", + { + "input": "test-a-colon.html", + "base": "a:", + "failure": true }, { - "input": "sc://#", - "base": "about:blank", - "href": "sc://#", - "protocol": "sc:", + "input": "test-a-colon-b.html", + "base": "a:b", + "failure": true + }, + "Other base URL tests, that must succeed", + { + "input": "test-a-colon-slash.html", + "base": "a:/", + "href": "a:/test-a-colon-slash.html", + "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "", + "pathname": "/test-a-colon-slash.html", "search": "", "hash": "" }, { - "input": "///", - "base": "sc://x/", - "href": "sc:///", - "protocol": "sc:", + "input": "test-a-colon-slash-slash.html", + "base": "a://", + "href": "a:///test-a-colon-slash-slash.html", + "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "/", + "pathname": "/test-a-colon-slash-slash.html", "search": "", "hash": "" }, { - "input": "////", - "base": "sc://x/", - "href": "sc:////", - "protocol": "sc:", + "input": "test-a-colon-slash-b.html", + "base": "a:/b", + "href": "a:/test-a-colon-slash-b.html", + "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", - "pathname": "//", + "pathname": "/test-a-colon-slash-b.html", "search": "", "hash": "" }, { - "input": "////x/", - "base": "sc://x/", - "href": "sc:////x/", - "protocol": "sc:", + "input": "test-a-colon-slash-slash-b.html", + "base": "a://b", + "href": "a://b/test-a-colon-slash-slash-b.html", + "protocol": "a:", "username": "", "password": "", - "host": "", - "hostname": "", + "host": "b", + "hostname": "b", "port": "", - "pathname": "//x/", + "pathname": "/test-a-colon-slash-slash-b.html", "search": "", "hash": "" }, + "Null code point in fragment", { - "input": "tftp://foobar.com/someconfig;mode=netascii", + "input": "http://example.org/test?a#b\u0000c", "base": "about:blank", - "href": "tftp://foobar.com/someconfig;mode=netascii", - "origin": "null", - "protocol": "tftp:", + "href": "http://example.org/test?a#b%00c", + "protocol": "http:", "username": "", "password": "", - "host": "foobar.com", - "hostname": "foobar.com", + "host": "example.org", + "hostname": "example.org", "port": "", - "pathname": "/someconfig;mode=netascii", - "search": "", - "hash": "" - }, - { - "input": "telnet://user:pass@foobar.com:23/", - "base": "about:blank", - "href": "telnet://user:pass@foobar.com:23/", - "origin": "null", - "protocol": "telnet:", - "username": "user", - "password": "pass", - "host": "foobar.com:23", - "hostname": "foobar.com", - "port": "23", - "pathname": "/", - "search": "", - "hash": "" + "pathname": "/test", + "search": "?a", + "hash": "#b%00c" }, { - "input": "ut2004://10.10.10.10:7777/Index.ut2", + "input": "non-spec://example.org/test?a#b\u0000c", "base": "about:blank", - "href": "ut2004://10.10.10.10:7777/Index.ut2", - "origin": "null", - "protocol": "ut2004:", + "href": "non-spec://example.org/test?a#b%00c", + "protocol": "non-spec:", "username": "", "password": "", - "host": "10.10.10.10:7777", - "hostname": "10.10.10.10", - "port": "7777", - "pathname": "/Index.ut2", - "search": "", - "hash": "" - }, - { - "input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", - "base": "about:blank", - "href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", - "origin": "null", - "protocol": "redis:", - "username": "foo", - "password": "bar", - "host": "somehost:6379", - "hostname": "somehost", - "port": "6379", - "pathname": "/0", - "search": "?baz=bam&qux=baz", - "hash": "" + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/test", + "search": "?a", + "hash": "#b%00c" }, { - "input": "rsync://foo@host:911/sup", + "input": "non-spec:/test?a#b\u0000c", "base": "about:blank", - "href": "rsync://foo@host:911/sup", - "origin": "null", - "protocol": "rsync:", - "username": "foo", + "href": "non-spec:/test?a#b%00c", + "protocol": "non-spec:", + "username": "", "password": "", - "host": "host:911", - "hostname": "host", - "port": "911", - "pathname": "/sup", - "search": "", - "hash": "" + "host": "", + "hostname": "", + "port": "", + "pathname": "/test", + "search": "?a", + "hash": "#b%00c" }, + "First scheme char - not allowed: https://github.com/whatwg/url/issues/464", { - "input": "git://github.com/foo/bar.git", - "base": "about:blank", - "href": "git://github.com/foo/bar.git", - "origin": "null", - "protocol": "git:", + "input": "10.0.0.7:8080/foo.html", + "base": "file:///some/dir/bar.html", + "href": "file:///some/dir/10.0.0.7:8080/foo.html", + "protocol": "file:", "username": "", "password": "", - "host": "github.com", - "hostname": "github.com", + "host": "", + "hostname": "", "port": "", - "pathname": "/foo/bar.git", + "pathname": "/some/dir/10.0.0.7:8080/foo.html", "search": "", "hash": "" }, + "Subsequent scheme chars - not allowed", { - "input": "irc://myserver.com:6999/channel?passwd", - "base": "about:blank", - "href": "irc://myserver.com:6999/channel?passwd", - "origin": "null", - "protocol": "irc:", + "input": "a!@$*=/foo.html", + "base": "file:///some/dir/bar.html", + "href": "file:///some/dir/a!@$*=/foo.html", + "protocol": "file:", "username": "", "password": "", - "host": "myserver.com:6999", - "hostname": "myserver.com", - "port": "6999", - "pathname": "/channel", - "search": "?passwd", + "host": "", + "hostname": "", + "port": "", + "pathname": "/some/dir/a!@$*=/foo.html", + "search": "", "hash": "" }, + "First and subsequent scheme chars - allowed", { - "input": "dns://fw.example.org:9999/foo.bar.org?type=TXT", - "base": "about:blank", - "href": "dns://fw.example.org:9999/foo.bar.org?type=TXT", - "origin": "null", - "protocol": "dns:", + "input": "a1234567890-+.:foo/bar", + "base": "http://example.com/dir/file", + "href": "a1234567890-+.:foo/bar", + "protocol": "a1234567890-+.:", "username": "", "password": "", - "host": "fw.example.org:9999", - "hostname": "fw.example.org", - "port": "9999", - "pathname": "/foo.bar.org", - "search": "?type=TXT", + "host": "", + "hostname": "", + "port": "", + "pathname": "foo/bar", + "search": "", "hash": "" }, + "IDNA ignored code points in file URLs hosts", { - "input": "ldap://localhost:389/ou=People,o=JNDITutorial", + "input": "file://a\u00ADb/p", "base": "about:blank", - "href": "ldap://localhost:389/ou=People,o=JNDITutorial", - "origin": "null", - "protocol": "ldap:", + "href": "file://ab/p", + "protocol": "file:", "username": "", "password": "", - "host": "localhost:389", - "hostname": "localhost", - "port": "389", - "pathname": "/ou=People,o=JNDITutorial", + "host": "ab", + "hostname": "ab", + "port": "", + "pathname": "/p", "search": "", "hash": "" }, { - "input": "git+https://github.com/foo/bar", + "input": "file://a%C2%ADb/p", "base": "about:blank", - "href": "git+https://github.com/foo/bar", - "origin": "null", - "protocol": "git+https:", + "href": "file://ab/p", + "protocol": "file:", "username": "", "password": "", - "host": "github.com", - "hostname": "github.com", + "host": "ab", + "hostname": "ab", "port": "", - "pathname": "/foo/bar", + "pathname": "/p", "search": "", "hash": "" }, + "Empty host after the domain to ASCII", + { + "input": "file://\u00ad/p", + "base": "about:blank", + "failure": true + }, { - "input": "urn:ietf:rfc:2648", + "input": "file://%C2%AD/p", "base": "about:blank", - "href": "urn:ietf:rfc:2648", - "origin": "null", - "protocol": "urn:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "ietf:rfc:2648", - "search": "", - "hash": "" + "failure": true }, { - "input": "tag:joe@example.org,2001:foo/bar", + "input": "file://xn--/p", "base": "about:blank", - "href": "tag:joe@example.org,2001:foo/bar", - "origin": "null", - "protocol": "tag:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "joe@example.org,2001:foo/bar", - "search": "", - "hash": "" + "failure": true }, - "# percent encoded hosts in non-special-URLs", + "https://bugzilla.mozilla.org/show_bug.cgi?id=1647058", { - "input": "non-special://%E2%80%A0/", - "base": "about:blank", - "href": "non-special://%E2%80%A0/", - "protocol": "non-special:", + "input": "#link", + "base": "https://example.org/##link", + "href": "https://example.org/#link", + "protocol": "https:", "username": "", "password": "", - "host": "%E2%80%A0", - "hostname": "%E2%80%A0", + "host": "example.org", + "hostname": "example.org", "port": "", "pathname": "/", "search": "", - "hash": "" + "hash": "#link" }, + "UTF-8 percent-encode of C0 control percent-encode set and supersets", { - "input": "non-special://H%4fSt/path", + "input": "non-special:cannot-be-a-base-url-\u0000\u0001\u001F\u001E\u007E\u007F\u0080", "base": "about:blank", - "href": "non-special://H%4fSt/path", - "protocol": "non-special:", - "username": "", + "hash": "", + "host": "", + "hostname": "", + "href": "non-special:cannot-be-a-base-url-%00%01%1F%1E~%7F%C2%80", + "origin": "null", "password": "", - "host": "H%4fSt", - "hostname": "H%4fSt", + "pathname": "cannot-be-a-base-url-%00%01%1F%1E~%7F%C2%80", "port": "", - "pathname": "/path", + "protocol": "non-special:", "search": "", - "hash": "" + "username": "" }, - "# IPv6 in non-special-URLs", { - "input": "non-special://[1:2:0:0:5:0:0:0]/", + "input": "https://www.example.com/path{\u007Fpath.html?query'\u007F=query#fragment<\u007Ffragment", "base": "about:blank", - "href": "non-special://[1:2:0:0:5::]/", - "protocol": "non-special:", - "username": "", + "hash": "#fragment%3C%7Ffragment", + "host": "www.example.com", + "hostname": "www.example.com", + "href": "https://www.example.com/path%7B%7Fpath.html?query%27%7F=query#fragment%3C%7Ffragment", + "origin": "https://www.example.com", "password": "", - "host": "[1:2:0:0:5::]", - "hostname": "[1:2:0:0:5::]", + "pathname": "/path%7B%7Fpath.html", "port": "", - "pathname": "/", + "protocol": "https:", + "search": "?query%27%7F=query", + "username": "" + }, + { + "input": "https://user:pass[\u007F@foo/bar", + "base": "http://example.org", + "hash": "", + "host": "foo", + "hostname": "foo", + "href": "https://user:pass%5B%7F@foo/bar", + "origin": "https://foo", + "password": "pass%5B%7F", + "pathname": "/bar", + "port": "", + "protocol": "https:", "search": "", - "hash": "" + "username": "user" }, + "Tests for the distinct percent-encode sets", { - "input": "non-special://[1:2:0:0:0:0:0:3]/", + "input": "foo:// !\"$%&'()*+,-.;<=>@[\\]^_`{|}~@host/", "base": "about:blank", - "href": "non-special://[1:2::3]/", - "protocol": "non-special:", - "username": "", + "hash": "", + "host": "host", + "hostname": "host", + "href": "foo://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/", + "origin": "null", "password": "", - "host": "[1:2::3]", - "hostname": "[1:2::3]", - "port": "", "pathname": "/", + "port":"", + "protocol": "foo:", "search": "", - "hash": "" + "username": "%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~" }, { - "input": "non-special://[1:2::3]:80/", + "input": "wss:// !\"$%&'()*+,-.;<=>@[]^_`{|}~@host/", "base": "about:blank", - "href": "non-special://[1:2::3]:80/", - "protocol": "non-special:", - "username": "", + "hash": "", + "host": "host", + "hostname": "host", + "href": "wss://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/", + "origin": "wss://host", "password": "", - "host": "[1:2::3]:80", - "hostname": "[1:2::3]", - "port": "80", "pathname": "/", + "port":"", + "protocol": "wss:", "search": "", - "hash": "" + "username": "%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~" }, { - "input": "non-special://[:80/", + "input": "foo://joe: !\"$%&'()*+,-.:;<=>@[\\]^_`{|}~@host/", "base": "about:blank", - "failure": true + "hash": "", + "host": "host", + "hostname": "host", + "href": "foo://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/", + "origin": "null", + "password": "%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~", + "pathname": "/", + "port":"", + "protocol": "foo:", + "search": "", + "username": "joe" }, { - "input": "blob:https://example.com:443/", + "input": "wss://joe: !\"$%&'()*+,-.:;<=>@[]^_`{|}~@host/", "base": "about:blank", - "href": "blob:https://example.com:443/", - "protocol": "blob:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "https://example.com:443/", + "hash": "", + "host": "host", + "hostname": "host", + "href": "wss://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/", + "origin": "wss://host", + "password": "%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~", + "pathname": "/", + "port":"", + "protocol": "wss:", "search": "", - "hash": "" + "username": "joe" }, { - "input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", + "input": "foo://!\"$%&'()*+,-.;=_`{}~/", "base": "about:blank", - "href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", - "protocol": "blob:", - "username": "", + "hash": "", + "host": "!\"$%&'()*+,-.;=_`{}~", + "hostname": "!\"$%&'()*+,-.;=_`{}~", + "href":"foo://!\"$%&'()*+,-.;=_`{}~/", + "origin": "null", "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "d3958f5c-0777-0845-9dcf-2cb28783acaf", + "pathname": "/", + "port":"", + "protocol": "foo:", "search": "", - "hash": "" + "username": "" }, - "Invalid IPv4 radix digits", { - "input": "http://0177.0.0.0189", + "input": "wss://!\"$&'()*+,-.;=_`{}~/", "base": "about:blank", - "href": "http://0177.0.0.0189/", - "protocol": "http:", - "username": "", + "hash": "", + "host": "!\"$&'()*+,-.;=_`{}~", + "hostname": "!\"$&'()*+,-.;=_`{}~", + "href":"wss://!\"$&'()*+,-.;=_`{}~/", + "origin": "wss://!\"$&'()*+,-.;=_`{}~", "password": "", - "host": "0177.0.0.0189", - "hostname": "0177.0.0.0189", - "port": "", "pathname": "/", + "port":"", + "protocol": "wss:", "search": "", - "hash": "" + "username": "" }, { - "input": "http://0x7f.0.0.0x7g", + "input": "foo://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~", "base": "about:blank", - "href": "http://0x7f.0.0.0x7g/", - "protocol": "http:", - "username": "", + "hash": "", + "host": "host", + "hostname": "host", + "href": "foo://host/%20!%22$%&'()*+,-./:;%3C=%3E@[\\]^_%60%7B|%7D~", + "origin": "null", "password": "", - "host": "0x7f.0.0.0x7g", - "hostname": "0x7f.0.0.0x7g", - "port": "", - "pathname": "/", + "pathname": "/%20!%22$%&'()*+,-./:;%3C=%3E@[\\]^_%60%7B|%7D~", + "port":"", + "protocol": "foo:", "search": "", - "hash": "" + "username": "" }, { - "input": "http://0X7F.0.0.0X7G", + "input": "wss://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~", "base": "about:blank", - "href": "http://0x7f.0.0.0x7g/", - "protocol": "http:", - "username": "", + "hash": "", + "host": "host", + "hostname": "host", + "href": "wss://host/%20!%22$%&'()*+,-./:;%3C=%3E@[/]^_%60%7B|%7D~", + "origin": "wss://host", "password": "", - "host": "0x7f.0.0.0x7g", - "hostname": "0x7f.0.0.0x7g", - "port": "", - "pathname": "/", + "pathname": "/%20!%22$%&'()*+,-./:;%3C=%3E@[/]^_%60%7B|%7D~", + "port":"", + "protocol": "wss:", "search": "", - "hash": "" + "username": "" }, - "Invalid IPv4 portion of IPv6 address", { - "input": "http://[::127.0.0.0.1]", + "input": "foo://host/dir/? !\"$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": "about:blank", - "failure": true + "hash": "", + "host": "host", + "hostname": "host", + "href": "foo://host/dir/?%20!%22$%&'()*+,-./:;%3C=%3E?@[\\]^_`{|}~", + "origin": "null", + "password": "", + "pathname": "/dir/", + "port":"", + "protocol": "foo:", + "search": "?%20!%22$%&'()*+,-./:;%3C=%3E?@[\\]^_`{|}~", + "username": "" }, - "Uncompressed IPv6 addresses with 0", { - "input": "http://[0:1:0:1:0:1:0:1]", + "input": "wss://host/dir/? !\"$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": "about:blank", - "href": "http://[0:1:0:1:0:1:0:1]/", - "protocol": "http:", - "username": "", + "hash": "", + "host": "host", + "hostname": "host", + "href": "wss://host/dir/?%20!%22$%&%27()*+,-./:;%3C=%3E?@[\\]^_`{|}~", + "origin": "wss://host", "password": "", - "host": "[0:1:0:1:0:1:0:1]", - "hostname": "[0:1:0:1:0:1:0:1]", - "port": "", - "pathname": "/", - "search": "", - "hash": "" + "pathname": "/dir/", + "port":"", + "protocol": "wss:", + "search": "?%20!%22$%&%27()*+,-./:;%3C=%3E?@[\\]^_`{|}~", + "username": "" }, { - "input": "http://[1:0:1:0:1:0:1:0]", + "input": "foo://host/dir/# !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": "about:blank", - "href": "http://[1:0:1:0:1:0:1:0]/", - "protocol": "http:", - "username": "", + "hash": "#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", + "host": "host", + "hostname": "host", + "href": "foo://host/dir/#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", + "origin": "null", "password": "", - "host": "[1:0:1:0:1:0:1:0]", - "hostname": "[1:0:1:0:1:0:1:0]", - "port": "", - "pathname": "/", + "pathname": "/dir/", + "port":"", + "protocol": "foo:", "search": "", - "hash": "" + "username": "" }, - "Percent-encoded query and fragment", { - "input": "http://example.org/test?\u0022", + "input": "wss://host/dir/# !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": "about:blank", - "href": "http://example.org/test?%22", - "protocol": "http:", - "username": "", + "hash": "#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", + "host": "host", + "hostname": "host", + "href": "wss://host/dir/#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", + "origin": "wss://host", "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?%22", - "hash": "" + "pathname": "/dir/", + "port":"", + "protocol": "wss:", + "search": "", + "username": "" }, + "Ensure that input schemes are not ignored when resolving non-special URLs", { - "input": "http://example.org/test?\u0023", - "base": "about:blank", - "href": "http://example.org/test?#", - "protocol": "http:", - "username": "", + "input": "abc:rootless", + "base": "abc://host/path", + "hash": "", + "host": "", + "hostname": "", + "href":"abc:rootless", "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", + "pathname": "rootless", + "port":"", + "protocol": "abc:", "search": "", - "hash": "" + "username": "" }, { - "input": "http://example.org/test?\u003C", - "base": "about:blank", - "href": "http://example.org/test?%3C", - "protocol": "http:", - "username": "", + "input": "abc:rootless", + "base": "abc:/path", + "hash": "", + "host": "", + "hostname": "", + "href":"abc:rootless", "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?%3C", - "hash": "" + "pathname": "rootless", + "port":"", + "protocol": "abc:", + "search": "", + "username": "" }, { - "input": "http://example.org/test?\u003E", - "base": "about:blank", - "href": "http://example.org/test?%3E", - "protocol": "http:", - "username": "", + "input": "abc:rootless", + "base": "abc:path", + "hash": "", + "host": "", + "hostname": "", + "href":"abc:rootless", "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?%3E", - "hash": "" + "pathname": "rootless", + "port":"", + "protocol": "abc:", + "search": "", + "username": "" }, { - "input": "http://example.org/test?\u2323", - "base": "about:blank", - "href": "http://example.org/test?%E2%8C%A3", - "protocol": "http:", - "username": "", + "input": "abc:/rooted", + "base": "abc://host/path", + "hash": "", + "host": "", + "hostname": "", + "href":"abc:/rooted", "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?%E2%8C%A3", - "hash": "" + "pathname": "/rooted", + "port":"", + "protocol": "abc:", + "search": "", + "username": "" + }, + "Empty query and fragment with blank should throw an error", + { + "input": "#", + "base": null, + "failure": true + }, + { + "input": "?", + "base": null, + "failure": true + }, + "Last component looks like a number, but not valid IPv4", + { + "input": "http://1.2.3.4.5", + "base": "http://other.com/", + "failure": true + }, + { + "input": "http://1.2.3.4.5.", + "base": "http://other.com/", + "failure": true }, { - "input": "http://example.org/test?%23%23", + "input": "http://0..0x300/", "base": "about:blank", - "href": "http://example.org/test?%23%23", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?%23%23", - "hash": "" + "failure": true }, { - "input": "http://example.org/test?%GH", + "input": "http://0..0x300./", "base": "about:blank", - "href": "http://example.org/test?%GH", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?%GH", - "hash": "" + "failure": true }, { - "input": "http://example.org/test?a#%EF", + "input": "http://256.256.256.256.256", + "base": "http://other.com/", + "failure": true + }, + { + "input": "http://256.256.256.256.256.", + "base": "http://other.com/", + "failure": true + }, + { + "input": "http://1.2.3.08", "base": "about:blank", - "href": "http://example.org/test?a#%EF", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?a", - "hash": "#%EF" + "failure": true }, { - "input": "http://example.org/test?a#%GH", + "input": "http://1.2.3.08.", "base": "about:blank", - "href": "http://example.org/test?a#%GH", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?a", - "hash": "#%GH" + "failure": true }, - "URLs that require a non-about:blank base. (Also serve as invalid base tests.)", { - "input": "a", + "input": "http://1.2.3.09", "base": "about:blank", "failure": true }, { - "input": "a/", + "input": "http://09.2.3.4", "base": "about:blank", "failure": true }, { - "input": "a//", + "input": "http://09.2.3.4.", "base": "about:blank", "failure": true }, - "Bases that don't fail to parse but fail to be bases", { - "input": "test-a-colon.html", - "base": "a:", + "input": "http://01.2.3.4.5", + "base": "about:blank", "failure": true }, { - "input": "test-a-colon-b.html", - "base": "a:b", + "input": "http://01.2.3.4.5.", + "base": "about:blank", "failure": true }, - "Other base URL tests, that must succeed", { - "input": "test-a-colon-slash.html", - "base": "a:/", - "href": "a:/test-a-colon-slash.html", - "protocol": "a:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/test-a-colon-slash.html", - "search": "", - "hash": "" + "input": "http://0x100.2.3.4", + "base": "about:blank", + "failure": true }, { - "input": "test-a-colon-slash-slash.html", - "base": "a://", - "href": "a:///test-a-colon-slash-slash.html", - "protocol": "a:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/test-a-colon-slash-slash.html", - "search": "", - "hash": "" + "input": "http://0x100.2.3.4.", + "base": "about:blank", + "failure": true }, { - "input": "test-a-colon-slash-b.html", - "base": "a:/b", - "href": "a:/test-a-colon-slash-b.html", - "protocol": "a:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/test-a-colon-slash-b.html", - "search": "", - "hash": "" + "input": "http://0x1.2.3.4.5", + "base": "about:blank", + "failure": true }, { - "input": "test-a-colon-slash-slash-b.html", - "base": "a://b", - "href": "a://b/test-a-colon-slash-slash-b.html", - "protocol": "a:", - "username": "", - "password": "", - "host": "b", - "hostname": "b", - "port": "", - "pathname": "/test-a-colon-slash-slash-b.html", - "search": "", - "hash": "" + "input": "http://0x1.2.3.4.5.", + "base": "about:blank", + "failure": true }, - "Null code point in fragment", { - "input": "http://example.org/test?a#b\u0000c", + "input": "http://foo.1.2.3.4", "base": "about:blank", - "href": "http://example.org/test?a#b%00c", - "protocol": "http:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?a", - "hash": "#b%00c" + "failure": true }, { - "input": "non-spec://example.org/test?a#b\u0000c", + "input": "http://foo.1.2.3.4.", "base": "about:blank", - "href": "non-spec://example.org/test?a#b%00c", - "protocol": "non-spec:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/test", - "search": "?a", - "hash": "#b%00c" + "failure": true }, { - "input": "non-spec:/test?a#b\u0000c", + "input": "http://foo.2.3.4", "base": "about:blank", - "href": "non-spec:/test?a#b%00c", - "protocol": "non-spec:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/test", - "search": "?a", - "hash": "#b%00c" + "failure": true }, - "First scheme char - not allowed: https://github.com/whatwg/url/issues/464", { - "input": "10.0.0.7:8080/foo.html", - "base": "file:///some/dir/bar.html", - "href": "file:///some/dir/10.0.0.7:8080/foo.html", - "protocol": "file:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/some/dir/10.0.0.7:8080/foo.html", - "search": "", - "hash": "" + "input": "http://foo.2.3.4.", + "base": "about:blank", + "failure": true }, - "Subsequent scheme chars - not allowed", { - "input": "a!@$*=/foo.html", - "base": "file:///some/dir/bar.html", - "href": "file:///some/dir/a!@$*=/foo.html", - "protocol": "file:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "/some/dir/a!@$*=/foo.html", - "search": "", - "hash": "" + "input": "http://foo.09", + "base": "about:blank", + "failure": true }, - "First and subsequent scheme chars - allowed", { - "input": "a1234567890-+.:foo/bar", - "base": "http://example.com/dir/file", - "href": "a1234567890-+.:foo/bar", - "protocol": "a1234567890-+.:", - "username": "", - "password": "", - "host": "", - "hostname": "", - "port": "", - "pathname": "foo/bar", - "search": "", - "hash": "" + "input": "http://foo.09.", + "base": "about:blank", + "failure": true }, - "IDNA ignored code points in file URLs hosts", { - "input": "file://a\u00ADb/p", + "input": "http://foo.0x4", "base": "about:blank", - "href": "file://ab/p", - "protocol": "file:", - "username": "", - "password": "", - "host": "ab", - "hostname": "ab", - "port": "", - "pathname": "/p", - "search": "", - "hash": "" + "failure": true }, { - "input": "file://a%C2%ADb/p", + "input": "http://foo.0x4.", "base": "about:blank", - "href": "file://ab/p", - "protocol": "file:", - "username": "", + "failure": true + }, + { + "input": "http://foo.09..", + "base": "about:blank", + "hash": "", + "host": "foo.09..", + "hostname": "foo.09..", + "href":"http://foo.09../", "password": "", - "host": "ab", - "hostname": "ab", - "port": "", - "pathname": "/p", + "pathname": "/", + "port":"", + "protocol": "http:", "search": "", - "hash": "" + "username": "" }, - "Empty host after the domain to ASCII", { - "input": "file://\u00ad/p", + "input": "http://0999999999999999999/", "base": "about:blank", "failure": true }, { - "input": "file://%C2%AD/p", + "input": "http://foo.0x", "base": "about:blank", "failure": true }, { - "input": "file://xn--/p", + "input": "http://foo.0XFfFfFfFfFfFfFfFfFfAcE123", "base": "about:blank", "failure": true }, - "https://bugzilla.mozilla.org/show_bug.cgi?id=1647058", { - "input": "#link", - "base": "https://example.org/##link", - "href": "https://example.org/#link", - "protocol": "https:", - "username": "", - "password": "", - "host": "example.org", - "hostname": "example.org", - "port": "", - "pathname": "/", - "search": "", - "hash": "#link" + "input": "http://💩.123/", + "base": "about:blank", + "failure": true } ] diff --git a/vendor/xflags-macros/.cargo-checksum.json b/vendor/xflags-macros/.cargo-checksum.json index 98f5dfe97..fcc17d504 100644 --- a/vendor/xflags-macros/.cargo-checksum.json +++ b/vendor/xflags-macros/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"23f3d89d0198bfa3552286396432e2ace70627773527eaaf62ed4d3ef1b37166","src/ast.rs":"bf42c4e474893d5dbd4fa3c9b392d3f837219fabb2042cfc26acc08b2ddc6f4a","src/emit.rs":"390be2d24bc21d5644c9c69624fd263bfa7dc0f3081799481177a45952168d51","src/lib.rs":"f00a5c9e671a82263d4cf4cced2895bb93ae03220112bc385553573cf9c4cd05","src/parse.rs":"2c2c9118d1f0447a946a78753edb65edd6eeb4f2a27707f5601232c8880aba85","src/update.rs":"feb2cefca834dad6550b6539be7ec9b98fedb608cd09aeddf808350c638d67b8","tests/it/help.rs":"53dbb8b5c6e09649143dc8f9e5cd690db776271a1ea778726146fc04be8583f4","tests/it/main.rs":"3cde1afb05f2470642f0f590cbed24fb553bd0ac1da0fcae93a02ffe42247d97","tests/it/repeated_pos.rs":"1b2b922beb182899504cd36440fd1547026a8a5ef4f79b483a2695227f06c4a8","tests/it/smoke.rs":"5d304f8b24716d63081965914bf4bcf9fc8bfccf30d3f49fb9d71e3405917fd2","tests/it/src/help.rs":"7430f8773b5a8dc3607fbadc04d562f015f056062d373897675140e591da4b60","tests/it/src/repeated_pos.rs":"161b39be8e543ef6dd3f019162c85b9e6d22c30dcd6297e947a2872ed1bc3c5f","tests/it/src/smoke.rs":"f17d4ffb6177fc83aa7f0ad235a487a15490a9f646e7789af8a92db4ea9552fe","tests/it/src/subcommands.rs":"1147d1a7de73cb20d5604a3e08ce43b32a89dbb9ee37aa8c595f6138a083abb9","tests/it/subcommands.rs":"dab409a1b14755122ea42a3169d4a020ce1e548e52a56211874efeb73551de08"},"package":"45d11d5fc2a97287eded8b170ca80533b3c42646dd7fa386a5eb045817921022"} \ No newline at end of file +{"files":{"Cargo.toml":"dff52eef5d3a126eefb38eb66ecb194dd9ccd22a6e010df2b672d83264ac65a5","src/ast.rs":"1f3be0fa1c340dbd98f56fd1c10a43b081d4b9179b1666a3dd3f32d8082e452c","src/emit.rs":"03e692330adc927c1d7ea36faebec0df997dd2e6bfb4816661988078b59fdb0b","src/lib.rs":"ce57137b3db248a73b201a5add6b1ac5c80e431e2bc2947962d4b0b6f397a449","src/parse.rs":"15e860ce666b17228ae537b322c096a64696c83b620468a14112bab30c0432a8","src/update.rs":"133dbc864182808ea7679b815863117b51ccc59a0e43796321f9d5a2edcb3ed6","tests/data/help.rs":"a952a2f641fa6db5c7bd25d8480c1dff4f1146db21a0629e0506e4bc87c46d0c","tests/data/repeated_pos.rs":"60b7d6378583765ddda1be127d3f40aa34cf802c64008e9d3a456f5e20100290","tests/data/smoke.rs":"c5d626382c22f147deb0be9396bf4f8256d64618451f8c9b85002d3525c7fff6","tests/data/subcommands.rs":"c2020f895380c95ca6c97f124615ed64f838a6ee3d1bcce8842029c6cef55188","tests/it/help.rs":"d12aba6869f7d40984c9294591fb97fea7d8caf062969e5ae640ba21957a26c3","tests/it/main.rs":"08311bc06020d980867bd696040c6ddd4893700c7a181d4b9d256ef100945a46","tests/it/repeated_pos.rs":"f9acef062eda5ad43722cade6ebde4c0077174a0fae4e2c3c9555ad6dd490599","tests/it/smoke.rs":"3324c20e79258fca2dfe30a7312b5e192d09c104a30142b1362dd89e746d1306","tests/it/subcommands.rs":"900726a1309d753aa3b666c9b3051ec0b26cb1bf59c1d072704d8e497cfa18c4"},"package":"2afbd7f2039bb6cad2dd45f0c5dff49c0d4e26118398768b7a605524d4251809"} \ No newline at end of file diff --git a/vendor/xflags-macros/Cargo.toml b/vendor/xflags-macros/Cargo.toml index a224e51a6..70b748f0a 100644 --- a/vendor/xflags-macros/Cargo.toml +++ b/vendor/xflags-macros/Cargo.toml @@ -10,16 +10,18 @@ # See Cargo.toml.orig for the original contents. [package] -edition = "2018" +edition = "2021" name = "xflags-macros" -version = "0.2.4" +version = "0.3.0" authors = ["Aleksey Kladov "] description = "Private implementation details of xflags." license = "MIT OR Apache-2.0" repository = "https://github.com/matklad/xflags" +resolver = "1" [lib] proc-macro = true + [dev-dependencies.expect-test] version = "1" diff --git a/vendor/xflags-macros/src/ast.rs b/vendor/xflags-macros/src/ast.rs index 5ccebd951..7fb9df1e1 100644 --- a/vendor/xflags-macros/src/ast.rs +++ b/vendor/xflags-macros/src/ast.rs @@ -4,6 +4,12 @@ pub(crate) struct XFlags { pub(crate) cmd: Cmd, } +impl XFlags { + pub fn is_anon(&self) -> bool { + self.cmd.name.is_empty() + } +} + #[derive(Debug)] pub(crate) struct Cmd { pub(crate) name: String, @@ -12,6 +18,7 @@ pub(crate) struct Cmd { pub(crate) flags: Vec, pub(crate) subcommands: Vec, pub(crate) default: bool, + pub(crate) idx: u8, } #[derive(Debug)] @@ -30,6 +37,12 @@ pub(crate) struct Flag { pub(crate) val: Option, } +impl Flag { + pub(crate) fn is_help(&self) -> bool { + self.name == "help" + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum Arity { Optional, diff --git a/vendor/xflags-macros/src/emit.rs b/vendor/xflags-macros/src/emit.rs index 05d5f01dd..1f3d88ead 100644 --- a/vendor/xflags-macros/src/emit.rs +++ b/vendor/xflags-macros/src/emit.rs @@ -1,15 +1,25 @@ use crate::{ast, update}; -use std::{fmt::Write, path::Path}; +use std::{env, fmt::Write, path::Path}; + +macro_rules! w { + ($($tt:tt)*) => { + drop(write!($($tt)*)) + }; +} pub(crate) fn emit(xflags: &ast::XFlags) -> String { let mut buf = String::new(); + if xflags.is_anon() { + w!(buf, "{{\n"); + } + emit_cmd(&mut buf, &xflags.cmd); blank_line(&mut buf); emit_api(&mut buf, xflags); - if std::env::var("UPDATE_XFLAGS").is_ok() { + if !xflags.is_anon() && env::var("UPDATE_XFLAGS").is_ok() { if let Some(src) = &xflags.src { update::in_place(&buf, Path::new(src.as_str())) } else { @@ -22,22 +32,22 @@ pub(crate) fn emit(xflags: &ast::XFlags) -> String { } blank_line(&mut buf); - emit_impls(&mut buf, &xflags); + emit_impls(&mut buf, xflags); emit_help(&mut buf, xflags); - buf -} + if xflags.is_anon() { + w!(buf, "Flags::from_env_or_exit()"); + w!(buf, "}}\n"); + } -macro_rules! w { - ($($tt:tt)*) => { - drop(write!($($tt)*)) - }; + buf } fn emit_cmd(buf: &mut String, cmd: &ast::Cmd) { w!(buf, "#[derive(Debug)]\n"); w!(buf, "pub struct {}", cmd.ident()); - if cmd.args.is_empty() && cmd.flags.is_empty() && cmd.subcommands.is_empty() { + let flags = cmd.flags.iter().filter(|it| !it.is_help()).collect::>(); + if cmd.args.is_empty() && flags.is_empty() && cmd.subcommands.is_empty() { w!(buf, ";\n"); return; } @@ -45,16 +55,16 @@ fn emit_cmd(buf: &mut String, cmd: &ast::Cmd) { for arg in &cmd.args { let ty = gen_arg_ty(arg.arity, &arg.val.ty); - w!(buf, " pub {}: {},\n", arg.val.ident(), ty); + w!(buf, " pub {}: {ty},\n", arg.val.ident()); } - if !cmd.args.is_empty() && !cmd.flags.is_empty() { + if !cmd.args.is_empty() && !flags.is_empty() { blank_line(buf); } - for flag in &cmd.flags { + for flag in &flags { let ty = gen_flag_ty(flag.arity, flag.val.as_ref().map(|it| &it.ty)); - w!(buf, " pub {}: {},\n", flag.ident(), ty); + w!(buf, " pub {}: {ty},\n", flag.ident()); } if cmd.has_subcommands() { @@ -67,8 +77,8 @@ fn emit_cmd(buf: &mut String, cmd: &ast::Cmd) { w!(buf, "#[derive(Debug)]\n"); w!(buf, "pub enum {} {{\n", cmd.cmd_enum_ident()); for sub in &cmd.subcommands { - let name = camel(&sub.name); - w!(buf, " {}({}),\n", name, name); + let name = sub.ident(); + w!(buf, " {name}({name}),\n"); } w!(buf, "}}\n"); @@ -104,9 +114,12 @@ fn gen_arg_ty(arity: ast::Arity, ty: &ast::Ty) -> String { } fn emit_api(buf: &mut String, xflags: &ast::XFlags) { - w!(buf, "impl {} {{\n", camel(&xflags.cmd.name)); + w!(buf, "impl {} {{\n", xflags.cmd.ident()); - w!(buf, " pub const HELP: &'static str = Self::HELP_;\n"); + w!(buf, " #[allow(dead_code)]\n"); + w!(buf, " pub fn from_env_or_exit() -> Self {{\n"); + w!(buf, " Self::from_env_or_exit_()\n"); + w!(buf, " }}\n"); blank_line(buf); w!(buf, " #[allow(dead_code)]\n"); @@ -123,7 +136,10 @@ fn emit_api(buf: &mut String, xflags: &ast::XFlags) { } fn emit_impls(buf: &mut String, xflags: &ast::XFlags) -> () { - w!(buf, "impl {} {{\n", camel(&xflags.cmd.name)); + w!(buf, "impl {} {{\n", xflags.cmd.ident()); + w!(buf, " fn from_env_or_exit_() -> Self {{\n"); + w!(buf, " Self::from_env_().unwrap_or_else(|err| err.exit())\n"); + w!(buf, " }}\n"); w!(buf, " fn from_env_() -> xflags::Result {{\n"); w!(buf, " let mut p = xflags::rt::Parser::new_from_env();\n"); w!(buf, " Self::parse_(&mut p)\n"); @@ -134,101 +150,115 @@ fn emit_impls(buf: &mut String, xflags: &ast::XFlags) -> () { w!(buf, " }}\n"); w!(buf, "}}\n"); blank_line(buf); - emit_impls_rec(buf, &xflags.cmd) -} - -fn emit_impls_rec(buf: &mut String, cmd: &ast::Cmd) -> () { - emit_impl(buf, cmd); - for sub in &cmd.subcommands { - blank_line(buf); - emit_impls_rec(buf, sub); - } + emit_parse(buf, &xflags.cmd) } -fn emit_impl(buf: &mut String, cmd: &ast::Cmd) -> () { - w!(buf, "impl {} {{\n", camel(&cmd.name)); +fn emit_parse(buf: &mut String, cmd: &ast::Cmd) { + w!(buf, "impl {} {{\n", cmd.ident()); w!(buf, "fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result {{\n"); + w!(buf, "#![allow(non_snake_case)]\n"); - for flag in &cmd.flags { - w!(buf, "let mut {} = Vec::new();\n", flag.ident()); - } + let mut prefix = String::new(); + emit_locals_rec(buf, &mut prefix, cmd); blank_line(buf); + w!(buf, "let mut state_ = 0u8;\n"); + w!(buf, "while let Some(arg_) = p_.pop_flag() {{\n"); + w!(buf, "match arg_ {{\n"); + { + w!(buf, "Ok(flag_) => match (state_, flag_.as_str()) {{\n"); + emit_match_flag_rec(buf, &mut prefix, cmd); + w!(buf, "_ => return Err(p_.unexpected_flag(&flag_)),\n"); + w!(buf, "}}\n"); - if !cmd.args.is_empty() { - for arg in &cmd.args { - w!(buf, "let mut {} = (false, Vec::new());\n", arg.val.ident()); - } - blank_line(buf); + w!(buf, "Err(arg_) => match (state_, arg_.to_str().unwrap_or(\"\")) {{\n"); + emit_match_arg_rec(buf, &mut prefix, cmd); + w!(buf, "_ => return Err(p_.unexpected_arg(arg_)),\n"); + w!(buf, "}}\n"); } + w!(buf, "}}\n"); + w!(buf, "}}\n"); + emit_default_transitions(buf, cmd); - if cmd.has_subcommands() { - w!(buf, "let mut sub_ = None;"); - blank_line(buf); + w!(buf, "Ok("); + emit_record_rec(buf, &mut prefix, cmd); + w!(buf, ")"); + + w!(buf, "}}\n"); + w!(buf, "}}\n"); +} + +fn emit_locals_rec(buf: &mut String, prefix: &mut String, cmd: &ast::Cmd) { + for flag in &cmd.flags { + if !flag.is_help() { + w!(buf, "let mut {prefix}{} = Vec::new();\n", flag.ident()); + } + } + for arg in &cmd.args { + w!(buf, "let mut {prefix}{} = (false, Vec::new());\n", arg.val.ident()); + } + for sub in &cmd.subcommands { + let l = sub.push_prefix(prefix); + emit_locals_rec(buf, prefix, sub); + prefix.truncate(l); } +} - w!(buf, "while let Some(arg_) = p_.pop_flag() {{\n"); - w!(buf, "match arg_ {{\n"); - { - w!(buf, "Ok(flag_) => match flag_.as_str() {{\n"); - for flag in &cmd.flags { - w!(buf, "\"--{}\"", flag.name); - if let Some(short) = &flag.short { - w!(buf, "| \"-{}\"", short); - } - w!(buf, " => {}.push(", flag.ident()); +fn emit_match_flag_rec(buf: &mut String, prefix: &mut String, cmd: &ast::Cmd) { + for flag in &cmd.flags { + w!(buf, "("); + emit_all_ids_rec(buf, cmd); + w!(buf, ", \"--{}\"", flag.name); + if let Some(short) = &flag.short { + w!(buf, "| \"-{short}\""); + } + w!(buf, ") => "); + if flag.is_help() { + w!(buf, "return Err(p_.help(Self::HELP_)),"); + } else { + w!(buf, "{prefix}{}.push(", flag.ident()); match &flag.val { Some(val) => match &val.ty { ast::Ty::OsString | ast::Ty::PathBuf => { w!(buf, "p_.next_value(&flag_)?.into()") } ast::Ty::FromStr(ty) => { - w!(buf, "p_.next_value_from_str::<{}>(&flag_)?", ty) + w!(buf, "p_.next_value_from_str::<{ty}>(&flag_)?") } }, None => w!(buf, "()"), } w!(buf, "),"); } - if cmd.default_subcommand().is_some() { - w!(buf, "_ => {{ p_.push_back(Ok(flag_)); break; }}"); - } else { - w!(buf, "_ => return Err(p_.unexpected_flag(&flag_)),"); - } - w!(buf, "}}\n"); } - { - w!(buf, "Err(arg_) => {{\n"); - if cmd.has_subcommands() { - w!(buf, "match arg_.to_str().unwrap_or(\"\") {{\n"); - for sub in cmd.named_subcommands() { - w!(buf, "\"{}\" => {{\n", sub.name); - w!( - buf, - "sub_ = Some({}::{}({}::parse_(p_)?));", - cmd.cmd_enum_ident(), - sub.ident(), - sub.ident() - ); - w!(buf, "break;"); - w!(buf, "}}\n"); - } - w!(buf, "_ => (),\n"); - w!(buf, "}}\n"); - } + if let Some(sub) = cmd.default_subcommand() { + w!(buf, "({}, _) => {{ p_.push_back(Ok(flag_)); state_ = {}; }}", cmd.idx, sub.idx); + } + for sub in &cmd.subcommands { + let l = sub.push_prefix(prefix); + emit_match_flag_rec(buf, prefix, sub); + prefix.truncate(l); + } +} +fn emit_match_arg_rec(buf: &mut String, prefix: &mut String, cmd: &ast::Cmd) { + for sub in cmd.named_subcommands() { + w!(buf, "({}, \"{}\") => state_ = {},\n", cmd.idx, sub.name, sub.idx); + } + if !cmd.args.is_empty() || cmd.has_subcommands() { + w!(buf, "({}, _) => {{\n", cmd.idx); for arg in &cmd.args { let done = match arg.arity { ast::Arity::Optional | ast::Arity::Required => "done_ @ ", ast::Arity::Repeated => "", }; - w!(buf, "if let ({}false, buf_) = &mut {} {{\n", done, arg.val.ident()); + w!(buf, "if let ({done}false, buf_) = &mut {prefix}{} {{\n", arg.val.ident()); w!(buf, "buf_.push("); match &arg.val.ty { ast::Ty::OsString | ast::Ty::PathBuf => { w!(buf, "arg_.into()") } ast::Ty::FromStr(ty) => { - w!(buf, "p_.value_from_str::<{}>(\"{}\", arg_)?", ty, arg.val.name); + w!(buf, "p_.value_from_str::<{ty}>(\"{}\", arg_)?", arg.val.name); } } w!(buf, ");\n"); @@ -241,79 +271,110 @@ fn emit_impl(buf: &mut String, cmd: &ast::Cmd) -> () { w!(buf, "continue;\n"); w!(buf, "}}\n"); } - if cmd.default_subcommand().is_some() { - w!(buf, "p_.push_back(Err(arg_)); break;"); + + if let Some(sub) = cmd.default_subcommand() { + w!(buf, "p_.push_back(Err(arg_)); state_ = {};", sub.idx); } else { w!(buf, "return Err(p_.unexpected_arg(arg_));"); } w!(buf, "}}\n"); } - w!(buf, "}}\n"); - w!(buf, "}}\n"); - if let Some(sub) = cmd.default_subcommand() { - w!(buf, "if sub_.is_none() {{\n"); - w!( - buf, - "sub_ = Some({}::{}({}::parse_(p_)?));", - cmd.cmd_enum_ident(), - sub.ident(), - sub.ident() - ); - w!(buf, "}}\n"); + for sub in &cmd.subcommands { + let l = sub.push_prefix(prefix); + emit_match_arg_rec(buf, prefix, sub); + prefix.truncate(l); } +} - w!(buf, "Ok(Self {{\n"); - if !cmd.args.is_empty() { - for arg in &cmd.args { - let val = &arg.val; - w!(buf, "{}: ", val.ident()); - match arg.arity { - ast::Arity::Optional => { - w!(buf, "p_.optional(\"{}\", {}.1)?", val.name, val.ident()) - } - ast::Arity::Required => { - w!(buf, "p_.required(\"{}\", {}.1)?", val.name, val.ident()) - } - ast::Arity::Repeated => w!(buf, "{}.1", val.ident()), - } - w!(buf, ",\n"); - } - blank_line(buf); - } +fn emit_record_rec(buf: &mut String, prefix: &mut String, cmd: &ast::Cmd) { + w!(buf, "{} {{\n", cmd.ident()); for flag in &cmd.flags { + if flag.is_help() { + continue; + } w!(buf, "{}: ", flag.ident()); match &flag.val { Some(_val) => match flag.arity { ast::Arity::Optional => { - w!(buf, "p_.optional(\"--{}\", {})?", flag.name, flag.ident()) + w!(buf, "p_.optional(\"--{}\", {prefix}{})?", flag.name, flag.ident()) } ast::Arity::Required => { - w!(buf, "p_.required(\"--{}\", {})?", flag.name, flag.ident()) + w!(buf, "p_.required(\"--{}\", {prefix}{})?", flag.name, flag.ident()) } - ast::Arity::Repeated => w!(buf, "{}", flag.ident()), + ast::Arity::Repeated => w!(buf, "{prefix}{}", flag.ident()), }, None => match flag.arity { ast::Arity::Optional => { - w!(buf, "p_.optional(\"--{}\", {})?.is_some()", flag.name, flag.ident()) + w!(buf, "p_.optional(\"--{}\", {prefix}{})?.is_some()", flag.name, flag.ident()) } ast::Arity::Required => { - w!(buf, "p_.required(\"--{}\", {})?", flag.name, flag.ident()) + w!(buf, "p_.required(\"--{}\", {prefix}{})?", flag.name, flag.ident()) } - ast::Arity::Repeated => w!(buf, "{}.len() as u32", flag.ident()), + ast::Arity::Repeated => w!(buf, "{prefix}{}.len() as u32", flag.ident()), }, } w!(buf, ",\n"); } + for arg in &cmd.args { + let val = &arg.val; + w!(buf, "{}: ", val.ident()); + match arg.arity { + ast::Arity::Optional => { + w!(buf, "p_.optional(\"{}\", {prefix}{}.1)?", val.name, val.ident()) + } + ast::Arity::Required => { + w!(buf, "p_.required(\"{}\", {prefix}{}.1)?", val.name, val.ident()) + } + ast::Arity::Repeated => w!(buf, "{prefix}{}.1", val.ident()), + } + w!(buf, ",\n"); + } if cmd.has_subcommands() { - w!(buf, "subcommand: p_.subcommand(sub_)?,\n"); + w!(buf, "subcommand: match state_ {{\n"); + for sub in &cmd.subcommands { + emit_leaf_ids_rec(buf, sub); + w!(buf, " => {}::{}(", cmd.cmd_enum_ident(), sub.ident()); + let l = prefix.len(); + prefix.push_str(&snake(&sub.name)); + prefix.push_str("__"); + emit_record_rec(buf, prefix, sub); + prefix.truncate(l); + w!(buf, "),\n"); + } + w!(buf, "_ => return Err(p_.subcommand_required()),"); + w!(buf, "}}\n"); } - w!(buf, "}})\n"); - w!(buf, "}}\n"); - w!(buf, "}}\n"); + w!(buf, "}}"); +} + +fn emit_leaf_ids_rec(buf: &mut String, cmd: &ast::Cmd) { + if cmd.has_subcommands() { + for sub in &cmd.subcommands { + emit_leaf_ids_rec(buf, sub) + } + } else { + w!(buf, "| {}", cmd.idx) + } +} + +fn emit_all_ids_rec(buf: &mut String, cmd: &ast::Cmd) { + w!(buf, "| {}", cmd.idx); + for sub in &cmd.subcommands { + emit_all_ids_rec(buf, sub) + } +} + +fn emit_default_transitions(buf: &mut String, cmd: &ast::Cmd) { + if let Some(sub) = cmd.default_subcommand() { + w!(buf, "state_ = if state_ == {} {{ {} }} else {{ state_ }};", cmd.idx, sub.idx); + } + for sub in &cmd.subcommands { + emit_default_transitions(buf, sub); + } } fn emit_help(buf: &mut String, xflags: &ast::XFlags) { @@ -327,7 +388,7 @@ fn emit_help(buf: &mut String, xflags: &ast::XFlags) { let help = format!("{:?}", help); let help = help.replace("\\n", "\n").replacen("\"", "\"\\\n", 1); - w!(buf, "const HELP_: &'static str = {};", help); + w!(buf, "const HELP_: &'static str = {help};"); w!(buf, "}}\n"); } @@ -336,26 +397,34 @@ fn write_lines_indented(buf: &mut String, multiline_str: &str, indent: usize) { if line.is_empty() { w!(buf, "\n") } else { - w!(buf, "{blank:indent$}{}\n", line, indent = indent, blank = ""); + w!(buf, "{blank:indent$}{line}\n", blank = ""); } } } fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { - w!(buf, "{}{}\n", prefix, cmd.name); + let mut empty_help = true; + if !cmd.name.is_empty() { + empty_help = false; + w!(buf, "{}{}\n", prefix, cmd.name); + } if let Some(doc) = &cmd.doc { + empty_help = false; write_lines_indented(buf, doc, 2); } let indent = if prefix.is_empty() { "" } else { " " }; let args = cmd.args_with_default(); if !args.is_empty() { - blank_line(buf); + if !empty_help { + blank_line(buf); + } + empty_help = false; w!(buf, "{}ARGS:\n", indent); let mut blank = ""; for arg in &args { - w!(buf, "{}", blank); + w!(buf, "{blank}"); blank = "\n"; let (l, r) = match arg.arity { @@ -363,7 +432,7 @@ fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { ast::Arity::Required => ("<", ">"), ast::Arity::Repeated => ("<", ">..."), }; - w!(buf, " {}{}{}\n", l, arg.val.name, r); + w!(buf, " {l}{}{r}\n", arg.val.name); if let Some(doc) = &arg.doc { write_lines_indented(buf, doc, 6) } @@ -372,17 +441,19 @@ fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { let flags = cmd.flags_with_default(); if !flags.is_empty() { - blank_line(buf); - w!(buf, "{}OPTIONS:\n", indent); + if !empty_help { + blank_line(buf); + } + w!(buf, "{indent}OPTIONS:\n"); let mut blank = ""; for flag in &flags { - w!(buf, "{}", blank); + w!(buf, "{blank}",); blank = "\n"; - let short = flag.short.as_ref().map(|it| format!("-{}, ", it)).unwrap_or_default(); + let short = flag.short.as_ref().map(|it| format!("-{it}, ")).unwrap_or_default(); let value = flag.val.as_ref().map(|it| format!(" <{}>", it.name)).unwrap_or_default(); - w!(buf, " {}--{}{}\n", short, flag.name, value); + w!(buf, " {short}--{}{value}\n", flag.name); if let Some(doc) = &flag.doc { write_lines_indented(buf, doc, 6); } @@ -407,11 +478,20 @@ fn help_rec(buf: &mut String, prefix: &str, cmd: &ast::Cmd) { impl ast::Cmd { fn ident(&self) -> String { + if self.name.is_empty() { + return "Flags".to_string(); + } camel(&self.name) } fn cmd_enum_ident(&self) -> String { format!("{}Cmd", self.ident()) } + fn push_prefix(&self, buf: &mut String) -> usize { + let l = buf.len(); + buf.push_str(&snake(&self.name)); + buf.push_str("__"); + l + } fn has_subcommands(&self) -> bool { !self.subcommands.is_empty() } @@ -510,10 +590,10 @@ mod tests { #[test] fn gen_it() { - let test_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/it"); + let test_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests"); let mut did_update = false; - for entry in fs::read_dir(test_dir.join("src")).unwrap() { + for entry in fs::read_dir(test_dir.join("data")).unwrap() { let entry = entry.unwrap(); let text = fs::read_to_string(entry.path()).unwrap(); @@ -531,7 +611,7 @@ mod tests { ); let name = entry.file_name(); - did_update |= update_on_disk_if_different(&test_dir.join(name), code); + did_update |= update_on_disk_if_different(&test_dir.join("it").join(name), code); if fmt.is_none() { panic!("syntax error"); diff --git a/vendor/xflags-macros/src/lib.rs b/vendor/xflags-macros/src/lib.rs index 8fac00587..f1c0e0599 100644 --- a/vendor/xflags-macros/src/lib.rs +++ b/vendor/xflags-macros/src/lib.rs @@ -8,19 +8,39 @@ pub fn xflags(_ts: proc_macro::TokenStream) -> proc_macro::TokenStream { // Stub out the code, but let rust-analyzer resolve the invocation #[cfg(not(test))] { - let cmd = parse::parse(_ts).unwrap(); - let text = emit::emit(&cmd); + let text = match parse::xflags(_ts) { + Ok(cmd) => emit::emit(&cmd), + Err(err) => format!("compile_error!(\"invalid flags syntax, {err}\");"), + }; text.parse().unwrap() } #[cfg(test)] unimplemented!() } +#[proc_macro] +pub fn parse_or_exit(_ts: proc_macro::TokenStream) -> proc_macro::TokenStream { + // Stub out the code, but let rust-analyzer resolve the invocation + #[cfg(not(test))] + { + let text = match parse::parse_or_exit(_ts) { + Ok(cmd) => emit::emit(&cmd), + Err(err) => format!("compile_error!(\"invalid flags syntax, {err}\")"), + }; + text.parse().unwrap() + } + #[cfg(test)] + { + let _ = parse::parse_or_exit; + unimplemented!(); + } +} + #[cfg(test)] pub fn compile(src: &str) -> String { use proc_macro2::TokenStream; let ts = src.parse::().unwrap(); - let cmd = parse::parse(ts).unwrap(); + let cmd = parse::xflags(ts).unwrap(); emit::emit(&cmd) } diff --git a/vendor/xflags-macros/src/parse.rs b/vendor/xflags-macros/src/parse.rs index e9749b141..48f9588e9 100644 --- a/vendor/xflags-macros/src/parse.rs +++ b/vendor/xflags-macros/src/parse.rs @@ -1,4 +1,4 @@ -use std::mem; +use std::{fmt, mem}; #[cfg(not(test))] use proc_macro::{Delimiter, TokenStream, TokenTree}; @@ -16,15 +16,41 @@ pub(crate) struct Error { impl std::error::Error for Error {} -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.msg) +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.msg, f) } } -pub(crate) fn parse(ts: TokenStream) -> Result { - let mut p = Parser::new(ts); - xflags(&mut p) +pub(crate) fn xflags(ts: TokenStream) -> Result { + let p = &mut Parser::new(ts); + let src = if p.eat_keyword("src") { Some(p.expect_string()?) } else { None }; + let doc = opt_doc(p)?; + let mut cmd = cmd(p)?; + cmd.doc = doc; + add_help(&mut cmd); + let res = ast::XFlags { src, cmd }; + Ok(res) +} + +pub(crate) fn parse_or_exit(ts: TokenStream) -> Result { + let p = &mut Parser::new(ts); + let mut cmd = anon_cmd(p)?; + assert!(cmd.subcommands.is_empty()); + add_help(&mut cmd); + let res = ast::XFlags { src: None, cmd }; + Ok(res) +} + +fn add_help(cmd: &mut ast::Cmd) { + let help = ast::Flag { + arity: ast::Arity::Optional, + name: "help".to_string(), + short: Some("h".to_string()), + doc: Some("Prints help information.".to_string()), + val: None, + }; + cmd.flags.push(help); } macro_rules! format_err { @@ -40,19 +66,25 @@ macro_rules! bail { }; } -fn xflags(p: &mut Parser) -> Result { - let src = if p.eat_keyword("src") { Some(p.expect_string()?) } else { None }; - let doc = opt_doc(p)?; - let mut cmd = cmd(p)?; - cmd.doc = doc; - let res = ast::XFlags { src, cmd }; - Ok(res) +fn anon_cmd(p: &mut Parser) -> Result { + cmd_impl(p, true) } fn cmd(p: &mut Parser) -> Result { - p.expect_keyword("cmd")?; + cmd_impl(p, false) +} + +fn cmd_impl(p: &mut Parser, anon: bool) -> Result { + let name = if anon { + String::new() + } else { + p.expect_keyword("cmd")?; + cmd_name(p)? + }; + + let idx = p.idx; + p.idx += 1; - let name = cmd_name(p)?; let mut res = ast::Cmd { name, doc: None, @@ -60,25 +92,16 @@ fn cmd(p: &mut Parser) -> Result { flags: Vec::new(), subcommands: Vec::new(), default: false, + idx, }; - while !p.at_delim(Delimiter::Brace) { - let doc = opt_doc(p)?; - let arity = arity(p)?; - match opt_val(p)? { - Some(val) => { - let arg = ast::Arg { arity, doc, val }; - res.args.push(arg); - } - None => bail!("expected ident"), - } + if !anon { + p.enter_delim(Delimiter::Brace)?; } - - p.enter_delim(Delimiter::Brace)?; while !p.end() { let doc = opt_doc(p)?; - let default = p.eat_keyword("default"); - if default || p.at_keyword("cmd") { + let default = !anon && p.eat_keyword("default"); + if !anon && (default || p.at_keyword("cmd")) { let mut cmd = cmd(p)?; cmd.doc = doc; res.subcommands.push(cmd); @@ -90,35 +113,56 @@ fn cmd(p: &mut Parser) -> Result { res.subcommands.rotate_right(1); } } else { - let mut flag = flag(p)?; - flag.doc = doc; - res.flags.push(flag); + let arity = arity(p)?; + let is_val = p.lookahead_punct(':', 1); + let name = p.expect_name()?; + if name.starts_with('-') { + let mut flag = flag(p, name)?; + flag.doc = doc; + flag.arity = arity; + res.flags.push(flag) + } else if is_val { + p.expect_punct(':')?; + let ty = ty(p)?; + let val = ast::Val { name, ty }; + let arg = ast::Arg { arity, doc, val }; + res.args.push(arg); + } else { + bail!("expected `--flag` or `arg: Type`") + } } } - p.exit_delim()?; + if !anon { + p.exit_delim()?; + } Ok(res) } -fn flag(p: &mut Parser) -> Result { - let arity = arity(p)?; - - let mut short = None; - let mut name = flag_name(p)?; - if !name.starts_with("--") { +fn flag(p: &mut Parser, name: String) -> Result { + let short; + let long; + if name.starts_with("--") { + short = None; + long = name; + } else { short = Some(name); if !p.eat_punct(',') { bail!("long option is required for `{}`", short.unwrap()); } - name = flag_name(p)?; - if !name.starts_with("--") { - bail!("long name must begin with `--`: `{}`", name); + long = flag_name(p)?; + if !long.starts_with("--") { + bail!("long name must begin with `--`: `{long}`"); } } + if long == "--help" { + bail!("`--help` flag is generated automatically") + } + let val = opt_val(p)?; Ok(ast::Flag { - arity, - name: name[2..].to_string(), + arity: ast::Arity::Required, + name: long[2..].to_string(), short: short.map(|it| it[1..].to_string()), doc: None, val, @@ -148,7 +192,7 @@ fn arity(p: &mut Parser) -> Result { return Ok(ast::Arity::Repeated); } if let Some(name) = p.eat_name() { - bail!("expected one of `optional`, `required`, `repeated`, got `{}`", name) + bail!("expected one of `optional`, `required`, `repeated`, got `{name}`") } bail!("expected one of `optional`, `required`, `repeated`, got {:?}", p.ts.pop()) } @@ -193,7 +237,7 @@ fn opt_doc(p: &mut Parser) -> Result> { fn cmd_name(p: &mut Parser) -> Result { let name = p.expect_name()?; if name.starts_with('-') { - bail!("command name can't begin with `-`: `{}`", name); + bail!("command name can't begin with `-`: `{name}`"); } Ok(name) } @@ -201,7 +245,7 @@ fn cmd_name(p: &mut Parser) -> Result { fn flag_name(p: &mut Parser) -> Result { let name = p.expect_name()?; if !name.starts_with('-') { - bail!("flag name should begin with `-`: `{}`", name); + bail!("flag name should begin with `-`: `{name}`"); } Ok(name) } @@ -209,21 +253,16 @@ fn flag_name(p: &mut Parser) -> Result { struct Parser { stack: Vec>, ts: Vec, + idx: u8, } impl Parser { fn new(ts: TokenStream) -> Self { let mut ts = ts.into_iter().collect::>(); ts.reverse(); - Self { stack: Vec::new(), ts } + Self { stack: Vec::new(), ts, idx: 0 } } - fn at_delim(&mut self, delimiter: Delimiter) -> bool { - match self.ts.last() { - Some(TokenTree::Group(g)) => g.delimiter() == delimiter, - _ => false, - } - } fn enter_delim(&mut self, delimiter: Delimiter) -> Result<()> { match self.ts.pop() { Some(TokenTree::Group(g)) if g.delimiter() == delimiter => { @@ -249,7 +288,7 @@ impl Parser { fn expect_keyword(&mut self, kw: &str) -> Result<()> { if !self.eat_keyword(kw) { - bail!("expected `{}`", kw) + bail!("expected `{kw}`") } Ok(()) } @@ -271,7 +310,7 @@ impl Parser { fn expect_name(&mut self) -> Result { self.eat_name().ok_or_else(|| { let next = self.ts.pop().map(|it| it.to_string()).unwrap_or_default(); - format_err!("expected a name, got: `{}`", next) + format_err!("expected a name, got: `{next}`") }) } fn eat_name(&mut self) -> Option { @@ -307,7 +346,7 @@ impl Parser { fn expect_punct(&mut self, punct: char) -> Result<()> { if !self.eat_punct(punct) { - bail!("expected `{}`", punct) + bail!("expected `{punct}`") } Ok(()) } @@ -330,11 +369,18 @@ impl Parser { fn expect_string(&mut self) -> Result { match self.ts.pop() { Some(TokenTree::Literal(lit)) if lit.to_string().starts_with('"') => { - let text = lit.to_string(); - let res = text.trim_matches('"').to_string(); + let res = str_lit_value(lit.to_string()); Ok(res) } _ => bail!("expected a string"), } } } + +/// "Parser" a string literal into the corresponding value. +/// +/// Really needs support in the proc_macro library: +/// +fn str_lit_value(lit: String) -> String { + lit.trim_matches('"').replace("\\'", "'") +} diff --git a/vendor/xflags-macros/src/update.rs b/vendor/xflags-macros/src/update.rs index e476e37aa..83a404c93 100644 --- a/vendor/xflags-macros/src/update.rs +++ b/vendor/xflags-macros/src/update.rs @@ -6,8 +6,7 @@ pub(crate) fn in_place(api: &str, path: &Path) { Path::new(&dir).join(path) }; - let mut text = - fs::read_to_string(&path).unwrap_or_else(|_| panic!("failed to read {:?}", path)); + let mut text = fs::read_to_string(&path).unwrap_or_else(|_| panic!("failed to read {path:?}")); let (insert_to, indent) = locate(&text); diff --git a/vendor/xflags-macros/tests/data/help.rs b/vendor/xflags-macros/tests/data/help.rs new file mode 100644 index 000000000..f252e34fa --- /dev/null +++ b/vendor/xflags-macros/tests/data/help.rs @@ -0,0 +1,26 @@ +xflags! { + /// Does stuff + /// + /// Helpful stuff. + cmd helpful { + /// With an arg. + optional src: PathBuf + + /// Another arg. + /// + /// This time, we provide some extra info about the + /// arg. Maybe some caveats, or what kinds of + /// values are accepted. + optional extra: String + + /// And a switch. + required -s, --switch + + /// And even a subcommand! + cmd sub { + /// With an optional flag. This has a really long + /// description which spans multiple lines. + optional -f, --flag + } + } +} diff --git a/vendor/xflags-macros/tests/data/repeated_pos.rs b/vendor/xflags-macros/tests/data/repeated_pos.rs new file mode 100644 index 000000000..be7c552e0 --- /dev/null +++ b/vendor/xflags-macros/tests/data/repeated_pos.rs @@ -0,0 +1,8 @@ +xflags! { + cmd RepeatedPos { + required a: PathBuf + optional b: u32 + optional c: OsString + repeated rest: OsString + } +} diff --git a/vendor/xflags-macros/tests/data/smoke.rs b/vendor/xflags-macros/tests/data/smoke.rs new file mode 100644 index 000000000..55da2d3ef --- /dev/null +++ b/vendor/xflags-macros/tests/data/smoke.rs @@ -0,0 +1,14 @@ +xflags! { + /// LSP server for rust. + cmd rust-analyzer { + required workspace: PathBuf + /// Number of concurrent jobs. + optional jobs: u32 + /// Path to log file. By default, logs go to stderr. + optional --log-file path: PathBuf + repeated -v, --verbose + required -n, --number n: u32 + repeated --data value: OsString + optional --emoji + } +} diff --git a/vendor/xflags-macros/tests/data/subcommands.rs b/vendor/xflags-macros/tests/data/subcommands.rs new file mode 100644 index 000000000..45fab8232 --- /dev/null +++ b/vendor/xflags-macros/tests/data/subcommands.rs @@ -0,0 +1,19 @@ +xflags! { + cmd rust-analyzer { + repeated -v, --verbose + + cmd server { + optional --dir path:PathBuf + default cmd launch { + optional --log + } + cmd watch { + } + } + + cmd analysis-stats { + required path: PathBuf + optional --parallel + } + } +} diff --git a/vendor/xflags-macros/tests/it/help.rs b/vendor/xflags-macros/tests/it/help.rs index 36a966485..f17062988 100644 --- a/vendor/xflags-macros/tests/it/help.rs +++ b/vendor/xflags-macros/tests/it/help.rs @@ -21,7 +21,10 @@ pub struct Sub { } impl Helpful { - pub const HELP: &'static str = Self::HELP_; + #[allow(dead_code)] + pub fn from_env_or_exit() -> Self { + Self::from_env_or_exit_() + } #[allow(dead_code)] pub fn from_env() -> xflags::Result { @@ -35,6 +38,9 @@ impl Helpful { } impl Helpful { + fn from_env_or_exit_() -> Self { + Self::from_env_().unwrap_or_else(|err| err.exit()) + } fn from_env_() -> xflags::Result { let mut p = xflags::rt::Parser::new_from_env(); Self::parse_(&mut p) @@ -47,68 +53,51 @@ impl Helpful { impl Helpful { fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { + #![allow(non_snake_case)] let mut switch = Vec::new(); - let mut src = (false, Vec::new()); let mut extra = (false, Vec::new()); + let mut sub__flag = Vec::new(); - let mut sub_ = None; + let mut state_ = 0u8; while let Some(arg_) = p_.pop_flag() { match arg_ { - Ok(flag_) => match flag_.as_str() { - "--switch" | "-s" => switch.push(()), + Ok(flag_) => match (state_, flag_.as_str()) { + (0 | 1, "--switch" | "-s") => switch.push(()), + (0 | 1, "--help" | "-h") => return Err(p_.help(Self::HELP_)), + (1, "--flag" | "-f") => sub__flag.push(()), _ => return Err(p_.unexpected_flag(&flag_)), }, - Err(arg_) => { - match arg_.to_str().unwrap_or("") { - "sub" => { - sub_ = Some(HelpfulCmd::Sub(Sub::parse_(p_)?)); - break; + Err(arg_) => match (state_, arg_.to_str().unwrap_or("")) { + (0, "sub") => state_ = 1, + (0, _) => { + if let (done_ @ false, buf_) = &mut src { + buf_.push(arg_.into()); + *done_ = true; + continue; } - _ => (), - } - if let (done_ @ false, buf_) = &mut src { - buf_.push(arg_.into()); - *done_ = true; - continue; - } - if let (done_ @ false, buf_) = &mut extra { - buf_.push(p_.value_from_str::("extra", arg_)?); - *done_ = true; - continue; + if let (done_ @ false, buf_) = &mut extra { + buf_.push(p_.value_from_str::("extra", arg_)?); + *done_ = true; + continue; + } + return Err(p_.unexpected_arg(arg_)); } - return Err(p_.unexpected_arg(arg_)); - } + _ => return Err(p_.unexpected_arg(arg_)), + }, } } - Ok(Self { + Ok(Helpful { + switch: p_.required("--switch", switch)?, src: p_.optional("src", src.1)?, extra: p_.optional("extra", extra.1)?, - - switch: p_.required("--switch", switch)?, - subcommand: p_.subcommand(sub_)?, + subcommand: match state_ { + 1 => HelpfulCmd::Sub(Sub { flag: p_.optional("--flag", sub__flag)?.is_some() }), + _ => return Err(p_.subcommand_required()), + }, }) } } - -impl Sub { - fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { - let mut flag = Vec::new(); - - while let Some(arg_) = p_.pop_flag() { - match arg_ { - Ok(flag_) => match flag_.as_str() { - "--flag" | "-f" => flag.push(()), - _ => return Err(p_.unexpected_flag(&flag_)), - }, - Err(arg_) => { - return Err(p_.unexpected_arg(arg_)); - } - } - } - Ok(Self { flag: p_.optional("--flag", flag)?.is_some() }) - } -} impl Helpful { const HELP_: &'static str = "\ helpful @@ -131,6 +120,9 @@ OPTIONS: -s, --switch And a switch. + -h, --help + Prints help information. + SUBCOMMANDS: helpful sub diff --git a/vendor/xflags-macros/tests/it/main.rs b/vendor/xflags-macros/tests/it/main.rs index 1ce058814..7d77bda36 100644 --- a/vendor/xflags-macros/tests/it/main.rs +++ b/vendor/xflags-macros/tests/it/main.rs @@ -67,9 +67,10 @@ fn smoke() { "-n 92 --werbose", expect![[r#"unexpected flag: `--werbose`"#]], ); - check(smoke::RustAnalyzer::from_vec, "", expect![[r#"flag is required: `workspace`"#]]); + check(smoke::RustAnalyzer::from_vec, "", expect!["flag is required: `--number`"]); check(smoke::RustAnalyzer::from_vec, ".", expect![[r#"flag is required: `--number`"#]]); check(smoke::RustAnalyzer::from_vec, "-n", expect![[r#"expected a value for `-n`"#]]); + check(smoke::RustAnalyzer::from_vec, "-n 92", expect!["flag is required: `workspace`"]); check( smoke::RustAnalyzer::from_vec, "-n lol", @@ -196,3 +197,36 @@ fn subcommands() { check(subcommands::RustAnalyzer::from_vec, "", expect![[r#"subcommand is required"#]]); } + +#[test] +fn subcommand_flag_inheritance() { + check( + subcommands::RustAnalyzer::from_vec, + "server watch --verbose --dir .", + expect![[r#" + RustAnalyzer { + verbose: 1, + subcommand: Server( + Server { + dir: Some( + ".", + ), + subcommand: Watch( + Watch, + ), + }, + ), + } + "#]], + ); + check( + subcommands::RustAnalyzer::from_vec, + "analysis-stats --verbose --dir .", + expect!["unexpected flag: `--dir`"], + ); + check( + subcommands::RustAnalyzer::from_vec, + "--dir . server", + expect!["unexpected flag: `--dir`"], + ); +} diff --git a/vendor/xflags-macros/tests/it/repeated_pos.rs b/vendor/xflags-macros/tests/it/repeated_pos.rs index 334af371d..b11b90717 100644 --- a/vendor/xflags-macros/tests/it/repeated_pos.rs +++ b/vendor/xflags-macros/tests/it/repeated_pos.rs @@ -10,7 +10,10 @@ pub struct RepeatedPos { } impl RepeatedPos { - pub const HELP: &'static str = Self::HELP_; + #[allow(dead_code)] + pub fn from_env_or_exit() -> Self { + Self::from_env_or_exit_() + } #[allow(dead_code)] pub fn from_env() -> xflags::Result { @@ -24,6 +27,9 @@ impl RepeatedPos { } impl RepeatedPos { + fn from_env_or_exit_() -> Self { + Self::from_env_().unwrap_or_else(|err| err.exit()) + } fn from_env_() -> xflags::Result { let mut p = xflags::rt::Parser::new_from_env(); Self::parse_(&mut p) @@ -36,41 +42,47 @@ impl RepeatedPos { impl RepeatedPos { fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { + #![allow(non_snake_case)] let mut a = (false, Vec::new()); let mut b = (false, Vec::new()); let mut c = (false, Vec::new()); let mut rest = (false, Vec::new()); + let mut state_ = 0u8; while let Some(arg_) = p_.pop_flag() { match arg_ { - Ok(flag_) => match flag_.as_str() { + Ok(flag_) => match (state_, flag_.as_str()) { + (0, "--help" | "-h") => return Err(p_.help(Self::HELP_)), _ => return Err(p_.unexpected_flag(&flag_)), }, - Err(arg_) => { - if let (done_ @ false, buf_) = &mut a { - buf_.push(arg_.into()); - *done_ = true; - continue; - } - if let (done_ @ false, buf_) = &mut b { - buf_.push(p_.value_from_str::("b", arg_)?); - *done_ = true; - continue; + Err(arg_) => match (state_, arg_.to_str().unwrap_or("")) { + (0, _) => { + if let (done_ @ false, buf_) = &mut a { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut b { + buf_.push(p_.value_from_str::("b", arg_)?); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut c { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (false, buf_) = &mut rest { + buf_.push(arg_.into()); + continue; + } + return Err(p_.unexpected_arg(arg_)); } - if let (done_ @ false, buf_) = &mut c { - buf_.push(arg_.into()); - *done_ = true; - continue; - } - if let (false, buf_) = &mut rest { - buf_.push(arg_.into()); - continue; - } - return Err(p_.unexpected_arg(arg_)); - } + _ => return Err(p_.unexpected_arg(arg_)), + }, } } - Ok(Self { + Ok(RepeatedPos { a: p_.required("a", a.1)?, b: p_.optional("b", b.1)?, c: p_.optional("c", c.1)?, @@ -90,5 +102,9 @@ ARGS: [c] ... + +OPTIONS: + -h, --help + Prints help information. "; } diff --git a/vendor/xflags-macros/tests/it/smoke.rs b/vendor/xflags-macros/tests/it/smoke.rs index e22c4f1f6..f2ebbb712 100644 --- a/vendor/xflags-macros/tests/it/smoke.rs +++ b/vendor/xflags-macros/tests/it/smoke.rs @@ -14,7 +14,10 @@ pub struct RustAnalyzer { } impl RustAnalyzer { - pub const HELP: &'static str = Self::HELP_; + #[allow(dead_code)] + pub fn from_env_or_exit() -> Self { + Self::from_env_or_exit_() + } #[allow(dead_code)] pub fn from_env() -> xflags::Result { @@ -28,6 +31,9 @@ impl RustAnalyzer { } impl RustAnalyzer { + fn from_env_or_exit_() -> Self { + Self::from_env_().unwrap_or_else(|err| err.exit()) + } fn from_env_() -> xflags::Result { let mut p = xflags::rt::Parser::new_from_env(); Self::parse_(&mut p) @@ -40,49 +46,53 @@ impl RustAnalyzer { impl RustAnalyzer { fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { + #![allow(non_snake_case)] let mut log_file = Vec::new(); let mut verbose = Vec::new(); let mut number = Vec::new(); let mut data = Vec::new(); let mut emoji = Vec::new(); - let mut workspace = (false, Vec::new()); let mut jobs = (false, Vec::new()); + let mut state_ = 0u8; while let Some(arg_) = p_.pop_flag() { match arg_ { - Ok(flag_) => match flag_.as_str() { - "--log-file" => log_file.push(p_.next_value(&flag_)?.into()), - "--verbose" | "-v" => verbose.push(()), - "--number" | "-n" => number.push(p_.next_value_from_str::(&flag_)?), - "--data" => data.push(p_.next_value(&flag_)?.into()), - "--emoji" => emoji.push(()), + Ok(flag_) => match (state_, flag_.as_str()) { + (0, "--log-file") => log_file.push(p_.next_value(&flag_)?.into()), + (0, "--verbose" | "-v") => verbose.push(()), + (0, "--number" | "-n") => number.push(p_.next_value_from_str::(&flag_)?), + (0, "--data") => data.push(p_.next_value(&flag_)?.into()), + (0, "--emoji") => emoji.push(()), + (0, "--help" | "-h") => return Err(p_.help(Self::HELP_)), _ => return Err(p_.unexpected_flag(&flag_)), }, - Err(arg_) => { - if let (done_ @ false, buf_) = &mut workspace { - buf_.push(arg_.into()); - *done_ = true; - continue; - } - if let (done_ @ false, buf_) = &mut jobs { - buf_.push(p_.value_from_str::("jobs", arg_)?); - *done_ = true; - continue; + Err(arg_) => match (state_, arg_.to_str().unwrap_or("")) { + (0, _) => { + if let (done_ @ false, buf_) = &mut workspace { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut jobs { + buf_.push(p_.value_from_str::("jobs", arg_)?); + *done_ = true; + continue; + } + return Err(p_.unexpected_arg(arg_)); } - return Err(p_.unexpected_arg(arg_)); - } + _ => return Err(p_.unexpected_arg(arg_)), + }, } } - Ok(Self { - workspace: p_.required("workspace", workspace.1)?, - jobs: p_.optional("jobs", jobs.1)?, - + Ok(RustAnalyzer { log_file: p_.optional("--log-file", log_file)?, verbose: verbose.len() as u32, number: p_.required("--number", number)?, data: data, emoji: p_.optional("--emoji", emoji)?.is_some(), + workspace: p_.required("workspace", workspace.1)?, + jobs: p_.optional("jobs", jobs.1)?, }) } } @@ -108,5 +118,8 @@ OPTIONS: --data --emoji + + -h, --help + Prints help information. "; } diff --git a/vendor/xflags-macros/tests/it/src/help.rs b/vendor/xflags-macros/tests/it/src/help.rs deleted file mode 100644 index d552c1e63..000000000 --- a/vendor/xflags-macros/tests/it/src/help.rs +++ /dev/null @@ -1,25 +0,0 @@ -xflags! { - /// Does stuff - /// - /// Helpful stuff. - cmd helpful - /// With an arg. - optional src: PathBuf - /// Another arg. - /// - /// This time, we provide some extra info about the - /// arg. Maybe some caveats, or what kinds of - /// values are accepted. - optional extra: String - { - /// And a switch. - required -s, --switch - - /// And even a subcommand! - cmd sub { - /// With an optional flag. This has a really long - /// description which spans multiple lines. - optional -f, --flag - } - } -} diff --git a/vendor/xflags-macros/tests/it/src/repeated_pos.rs b/vendor/xflags-macros/tests/it/src/repeated_pos.rs deleted file mode 100644 index 4106c65eb..000000000 --- a/vendor/xflags-macros/tests/it/src/repeated_pos.rs +++ /dev/null @@ -1,9 +0,0 @@ -xflags! { - cmd RepeatedPos - required a: PathBuf - optional b: u32 - optional c: OsString - repeated rest: OsString - { - } -} diff --git a/vendor/xflags-macros/tests/it/src/smoke.rs b/vendor/xflags-macros/tests/it/src/smoke.rs deleted file mode 100644 index ae303779e..000000000 --- a/vendor/xflags-macros/tests/it/src/smoke.rs +++ /dev/null @@ -1,15 +0,0 @@ -xflags! { - /// LSP server for rust. - cmd rust-analyzer - required workspace: PathBuf - /// Number of concurrent jobs. - optional jobs: u32 - { - /// Path to log file. By default, logs go to stderr. - optional --log-file path: PathBuf - repeated -v, --verbose - required -n, --number n: u32 - repeated --data value: OsString - optional --emoji - } -} diff --git a/vendor/xflags-macros/tests/it/src/subcommands.rs b/vendor/xflags-macros/tests/it/src/subcommands.rs deleted file mode 100644 index 70a0a5049..000000000 --- a/vendor/xflags-macros/tests/it/src/subcommands.rs +++ /dev/null @@ -1,20 +0,0 @@ -xflags! { - cmd rust-analyzer { - repeated -v, --verbose - - cmd server { - optional --dir path:PathBuf - default cmd launch { - optional --log - } - cmd watch { - } - } - - cmd analysis-stats - required path: PathBuf - { - optional --parallel - } - } -} diff --git a/vendor/xflags-macros/tests/it/subcommands.rs b/vendor/xflags-macros/tests/it/subcommands.rs index 7941a395d..4d0a64923 100644 --- a/vendor/xflags-macros/tests/it/subcommands.rs +++ b/vendor/xflags-macros/tests/it/subcommands.rs @@ -41,7 +41,10 @@ pub struct AnalysisStats { } impl RustAnalyzer { - pub const HELP: &'static str = Self::HELP_; + #[allow(dead_code)] + pub fn from_env_or_exit() -> Self { + Self::from_env_or_exit_() + } #[allow(dead_code)] pub fn from_env() -> xflags::Result { @@ -55,6 +58,9 @@ impl RustAnalyzer { } impl RustAnalyzer { + fn from_env_or_exit_() -> Self { + Self::from_env_().unwrap_or_else(|err| err.exit()) + } fn from_env_() -> xflags::Result { let mut p = xflags::rt::Parser::new_from_env(); Self::parse_(&mut p) @@ -67,130 +73,71 @@ impl RustAnalyzer { impl RustAnalyzer { fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { + #![allow(non_snake_case)] let mut verbose = Vec::new(); + let mut server__dir = Vec::new(); + let mut server__launch__log = Vec::new(); + let mut analysis_stats__parallel = Vec::new(); + let mut analysis_stats__path = (false, Vec::new()); - let mut sub_ = None; + let mut state_ = 0u8; while let Some(arg_) = p_.pop_flag() { match arg_ { - Ok(flag_) => match flag_.as_str() { - "--verbose" | "-v" => verbose.push(()), + Ok(flag_) => match (state_, flag_.as_str()) { + (0 | 1 | 2 | 3 | 4, "--verbose" | "-v") => verbose.push(()), + (0 | 1 | 2 | 3 | 4, "--help" | "-h") => return Err(p_.help(Self::HELP_)), + (1 | 2 | 3, "--dir") => server__dir.push(p_.next_value(&flag_)?.into()), + (1, _) => { + p_.push_back(Ok(flag_)); + state_ = 2; + } + (2, "--log") => server__launch__log.push(()), + (4, "--parallel") => analysis_stats__parallel.push(()), _ => return Err(p_.unexpected_flag(&flag_)), }, - Err(arg_) => { - match arg_.to_str().unwrap_or("") { - "server" => { - sub_ = Some(RustAnalyzerCmd::Server(Server::parse_(p_)?)); - break; - } - "analysis-stats" => { - sub_ = Some(RustAnalyzerCmd::AnalysisStats(AnalysisStats::parse_(p_)?)); - break; - } - _ => (), + Err(arg_) => match (state_, arg_.to_str().unwrap_or("")) { + (0, "server") => state_ = 1, + (0, "analysis-stats") => state_ = 4, + (0, _) => { + return Err(p_.unexpected_arg(arg_)); } - return Err(p_.unexpected_arg(arg_)); - } - } - } - Ok(Self { verbose: verbose.len() as u32, subcommand: p_.subcommand(sub_)? }) - } -} - -impl Server { - fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { - let mut dir = Vec::new(); - - let mut sub_ = None; - while let Some(arg_) = p_.pop_flag() { - match arg_ { - Ok(flag_) => match flag_.as_str() { - "--dir" => dir.push(p_.next_value(&flag_)?.into()), - _ => { - p_.push_back(Ok(flag_)); - break; + (1, "watch") => state_ = 3, + (1, _) => { + p_.push_back(Err(arg_)); + state_ = 2; } - }, - Err(arg_) => { - match arg_.to_str().unwrap_or("") { - "watch" => { - sub_ = Some(ServerCmd::Watch(Watch::parse_(p_)?)); - break; + (4, _) => { + if let (done_ @ false, buf_) = &mut analysis_stats__path { + buf_.push(arg_.into()); + *done_ = true; + continue; } - _ => (), + return Err(p_.unexpected_arg(arg_)); } - p_.push_back(Err(arg_)); - break; - } - } - } - if sub_.is_none() { - sub_ = Some(ServerCmd::Launch(Launch::parse_(p_)?)); - } - Ok(Self { dir: p_.optional("--dir", dir)?, subcommand: p_.subcommand(sub_)? }) - } -} - -impl Launch { - fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { - let mut log = Vec::new(); - - while let Some(arg_) = p_.pop_flag() { - match arg_ { - Ok(flag_) => match flag_.as_str() { - "--log" => log.push(()), - _ => return Err(p_.unexpected_flag(&flag_)), - }, - Err(arg_) => { - return Err(p_.unexpected_arg(arg_)); - } - } - } - Ok(Self { log: p_.optional("--log", log)?.is_some() }) - } -} - -impl Watch { - fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { - while let Some(arg_) = p_.pop_flag() { - match arg_ { - Ok(flag_) => match flag_.as_str() { - _ => return Err(p_.unexpected_flag(&flag_)), + _ => return Err(p_.unexpected_arg(arg_)), }, - Err(arg_) => { - return Err(p_.unexpected_arg(arg_)); - } } } - Ok(Self {}) - } -} - -impl AnalysisStats { - fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result { - let mut parallel = Vec::new(); - - let mut path = (false, Vec::new()); - - while let Some(arg_) = p_.pop_flag() { - match arg_ { - Ok(flag_) => match flag_.as_str() { - "--parallel" => parallel.push(()), - _ => return Err(p_.unexpected_flag(&flag_)), - }, - Err(arg_) => { - if let (done_ @ false, buf_) = &mut path { - buf_.push(arg_.into()); - *done_ = true; - continue; - } - return Err(p_.unexpected_arg(arg_)); - } - } - } - Ok(Self { - path: p_.required("path", path.1)?, - - parallel: p_.optional("--parallel", parallel)?.is_some(), + state_ = if state_ == 1 { 2 } else { state_ }; + Ok(RustAnalyzer { + verbose: verbose.len() as u32, + subcommand: match state_ { + 2 | 3 => RustAnalyzerCmd::Server(Server { + dir: p_.optional("--dir", server__dir)?, + subcommand: match state_ { + 2 => ServerCmd::Launch(Launch { + log: p_.optional("--log", server__launch__log)?.is_some(), + }), + 3 => ServerCmd::Watch(Watch {}), + _ => return Err(p_.subcommand_required()), + }, + }), + 4 => RustAnalyzerCmd::AnalysisStats(AnalysisStats { + parallel: p_.optional("--parallel", analysis_stats__parallel)?.is_some(), + path: p_.required("path", analysis_stats__path.1)?, + }), + _ => return Err(p_.subcommand_required()), + }, }) } } @@ -201,6 +148,9 @@ rust-analyzer OPTIONS: -v, --verbose + -h, --help + Prints help information. + SUBCOMMANDS: rust-analyzer server diff --git a/vendor/xflags/.cargo-checksum.json b/vendor/xflags/.cargo-checksum.json index c5fd48200..1fa4dd9e5 100644 --- a/vendor/xflags/.cargo-checksum.json +++ b/vendor/xflags/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"76747bdf0a7c1643e62a7c8db6e65572906908415ba87daaa7444917cdf1d35b","Cargo.toml":"32dc60919f757b61d4a6602da24bdd59b77b76f284a1b55712a78e1159e2d249","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"d34d354ca65973ca9120ed16af11e188c91af2ede6894e0e842c10c874780f7b","examples/hello-generated.rs":"ac2d4864e238e664fb1b18db66aed75ac5a425877bc00729fed1135fb410b969","examples/hello.rs":"c1a5656bee529c3ef96a3afc3531e02bc9d5d309e1bcd60b76e6758fb4c2a95d","examples/longer.rs":"18ad0d00215fdf245830a581df32fbf9533f5ab47e736659e598b4ecd2d96e1a","examples/non-utf8.rs":"a9d4a03adb05c8b46c3251647b8dbf4e860277db995e14192cd8d445f3434186","src/lib.rs":"21843e64aba8010dcc877418927e5b0ad3615ff6e18020285849bbf4391f4ed0","src/rt.rs":"c3cb2d6c80ec9c0586a6e64441cee4c237d2fb420891dec2acb96d5b0c7d6937"},"package":"3f14fe1ed41a5a2b5ef3f565586c4a8a559ee55d3953faab360a771135bdee00"} \ No newline at end of file +{"files":{"Cargo.lock":"bff2ffbef3ca253bcde1624bfc2c2afd244ca39b44e7dd3f4b463873904129c7","Cargo.toml":"faa866c2c32635dfa6d600103595777c330520df5e73aa0461d6f34eb21bbd9a","examples/hello-generated.rs":"3bf7922435ae84e2b8ae022aba1d693fc4e523b354d3141cc62a183864531f31","examples/hello.rs":"235426d1a69eeba790d1e4fc2ac4fa8f30ca16952edb2a026cf6f4b8c78d6fec","examples/immediate-mode.rs":"dcae135769b6104801de7b91fd220fb28ddae097ba7b0474fe32c28a90c4dfef","examples/longer.rs":"b55684fdde16a8462e1c1afaa9f30e75e3472abfcabe950403733c767dd7de96","examples/non-utf8.rs":"23b563180d1d616f81e224890192799a06fdbc21f3ccb7e4234ca51b3c467a9a","src/lib.rs":"780d7be977abefaa4c7229733a916d88480c9228ddb0f9bc2a25aaa626f7f7d7","src/rt.rs":"b80e6b1e180b0bd0fd523a6bc74d6bba40da7af461de37c33c3735bfb3c66254"},"package":"cbf19f5031a1a812e96fede16f8161218883079946cea87619d3613db1efd268"} \ No newline at end of file diff --git a/vendor/xflags/Cargo.lock b/vendor/xflags/Cargo.lock index 37ff98bb9..e2020eb16 100644 --- a/vendor/xflags/Cargo.lock +++ b/vendor/xflags/Cargo.lock @@ -4,13 +4,13 @@ version = 3 [[package]] name = "xflags" -version = "0.2.4" +version = "0.3.0" dependencies = [ "xflags-macros", ] [[package]] name = "xflags-macros" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d11d5fc2a97287eded8b170ca80533b3c42646dd7fa386a5eb045817921022" +checksum = "2afbd7f2039bb6cad2dd45f0c5dff49c0d4e26118398768b7a605524d4251809" diff --git a/vendor/xflags/Cargo.toml b/vendor/xflags/Cargo.toml index 542701052..091002385 100644 --- a/vendor/xflags/Cargo.toml +++ b/vendor/xflags/Cargo.toml @@ -10,14 +10,15 @@ # See Cargo.toml.orig for the original contents. [package] -edition = "2018" +edition = "2021" name = "xflags" -version = "0.2.4" +version = "0.3.0" authors = ["Aleksey Kladov "] -exclude = [".github/", "bors.toml", "rustfmt.toml"] description = "Moderately simple command line arguments parser." categories = ["command-line-interface"] license = "MIT OR Apache-2.0" repository = "https://github.com/matklad/xflags" +resolver = "1" + [dependencies.xflags-macros] -version = "=0.2.4" +version = "=0.3.0" diff --git a/vendor/xflags/LICENSE-APACHE b/vendor/xflags/LICENSE-APACHE deleted file mode 100644 index 16fe87b06..000000000 --- a/vendor/xflags/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - 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 [yyyy] [name of copyright owner] - -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. diff --git a/vendor/xflags/LICENSE-MIT b/vendor/xflags/LICENSE-MIT deleted file mode 100644 index 31aa79387..000000000 --- a/vendor/xflags/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -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. diff --git a/vendor/xflags/README.md b/vendor/xflags/README.md deleted file mode 100644 index bfebfb0c8..000000000 --- a/vendor/xflags/README.md +++ /dev/null @@ -1,49 +0,0 @@ -[![API reference](https://docs.rs/once_cell/badge.svg)](https://docs.rs/xflags/) - -# xflags - -Moderately simple command line arguments parsing: - -```rust -mod flags { - use std::path::PathBuf; - - xflags::xflags! { - src "./examples/basic.rs" - - cmd my-command - required path: PathBuf - { - optional -v, --verbose - } - } - - // generated start - // The following code is generated by `xflags` macro. - // Run `env UPDATE_XFLAGS=1 cargo build` to regenerate. - #[derive(Debug)] - pub struct MyCommand { - pub path: PathBuf, - - pub verbose: bool, - } - - impl MyCommand { - pub const HELP: &'static str = Self::HELP_; - - pub fn from_env() -> xflags::Result { - Self::from_env_() - } - - pub fn from_vec(args: Vec) -> xflags::Result { - Self::from_vec_(args) - } - } - // generated end -} - -fn main() { - let flags = flags::MyCommand::from_env(); - println!("{:#?}", flags); -} -``` diff --git a/vendor/xflags/examples/hello-generated.rs b/vendor/xflags/examples/hello-generated.rs index b82884859..cb74acbd7 100644 --- a/vendor/xflags/examples/hello-generated.rs +++ b/vendor/xflags/examples/hello-generated.rs @@ -5,10 +5,10 @@ mod flags { src "./examples/hello-generated.rs" /// Prints a greeting. - cmd hello + cmd hello { /// Whom to greet. required name: String - { + /// Use non-ascii symbols in the output. optional -e, --emoji } @@ -25,12 +25,12 @@ mod flags { } impl Hello { - pub const HELP: &'static str = Self::HELP_; - + #[allow(dead_code)] pub fn from_env() -> xflags::Result { Self::from_env_() } + #[allow(dead_code)] pub fn from_vec(args: Vec) -> xflags::Result { Self::from_vec_(args) } @@ -44,9 +44,6 @@ fn main() { let bang = if flags.emoji { "❣️" } else { "!" }; println!("Hello {}{}", flags.name, bang); } - Err(err) => { - eprintln!("{}\n\n{}", err, flags::Hello::HELP); - std::process::exit(1) - } + Err(err) => err.exit(), } } diff --git a/vendor/xflags/examples/hello.rs b/vendor/xflags/examples/hello.rs index 98a19099f..91dc3fd8a 100644 --- a/vendor/xflags/examples/hello.rs +++ b/vendor/xflags/examples/hello.rs @@ -1,8 +1,7 @@ mod flags { xflags::xflags! { - cmd hello + cmd hello { required name: String - { optional -e, --emoji } } diff --git a/vendor/xflags/examples/immediate-mode.rs b/vendor/xflags/examples/immediate-mode.rs new file mode 100644 index 000000000..ee3baa3de --- /dev/null +++ b/vendor/xflags/examples/immediate-mode.rs @@ -0,0 +1,16 @@ +use std::path::PathBuf; + +fn main() { + let flags = xflags::parse_or_exit! { + /// Remove directories and their contents recursively. + optional -r,--recursive + /// File or directory to remove + required path: PathBuf + }; + + println!( + "removing {}{}", + flags.path.display(), + if flags.recursive { "recursively" } else { "" }, + ) +} diff --git a/vendor/xflags/examples/longer.rs b/vendor/xflags/examples/longer.rs index 7ea9e18d5..199cca042 100644 --- a/vendor/xflags/examples/longer.rs +++ b/vendor/xflags/examples/longer.rs @@ -24,10 +24,9 @@ mod flags { } /// Benchmark specific analysis operation - cmd analysis-bench + cmd analysis-bench { /// Directory with Cargo.toml optional path: PathBuf - { /// Compute syntax highlighting for this file required --highlight path: PathBuf /// Compute highlighting for this line @@ -72,12 +71,12 @@ mod flags { } impl RustAnalyzer { - pub const HELP: &'static str = Self::HELP_; - + #[allow(dead_code)] pub fn from_env() -> xflags::Result { Self::from_env_() } + #[allow(dead_code)] pub fn from_vec(args: Vec) -> xflags::Result { Self::from_vec_(args) } diff --git a/vendor/xflags/examples/non-utf8.rs b/vendor/xflags/examples/non-utf8.rs index d355b24f6..28b1e98be 100644 --- a/vendor/xflags/examples/non-utf8.rs +++ b/vendor/xflags/examples/non-utf8.rs @@ -4,11 +4,10 @@ mod flags { use std::{ffi::OsString, path::PathBuf}; xflags::xflags! { - cmd Cmd + cmd Cmd { required a: OsString required b: PathBuf required c: String - { } } } diff --git a/vendor/xflags/src/lib.rs b/vendor/xflags/src/lib.rs index ae347f511..0eda9dec4 100644 --- a/vendor/xflags/src/lib.rs +++ b/vendor/xflags/src/lib.rs @@ -1,12 +1,65 @@ -//! This crates provides a procedural macro for parsing command line arguments. +//! `xflags` provides a procedural macro for parsing command line arguments. //! //! It is intended for use in development tools, so it emphasizes fast compile //! times and convenience at the expense of features. //! -//! If you need something more fancy, consider using -//! [`clap`](https://docs.rs/clap/2.33.3/clap/) instead. +//! Rough decision tree for picking an argument parsing library: //! -//! ## Example +//! * if you need all of the features and don't care about minimalism, use +//! [clap](https://github.com/clap-rs/clap) +//! * if you want to be maximally minimal, need only basic features (eg, no help +//! generation), and want to be pedantically correct, use +//! [lexopt](https://github.com/blyxxyz/lexopt) +//! * if you want to get things done fast (eg, you want auto help, but not at +//! the cost of waiting for syn to compile), consider this crate. +//! +//! The secret sauce of xflags is that it is the opposite of a derive macro. +//! Rather than generating a command line grammar from a Rust struct, `xflags` +//! generates Rust structs based on input grammar. The grammar definition is +//! both shorter and simpler to write, and is lighter on compile times. +//! +//! Here's a complete example of `parse_or_exit!` macro which parses arguments +//! into an "anonymous" struct: +//! +//! ```no_run +//! use std::path::PathBuf; +//! +//! fn main() { +//! let flags = xflags::parse_or_exit! { +//! /// Remove directories and their contents recursively. +//! optional -r,--recursive +//! /// File or directory to remove +//! required path: PathBuf +//! }; +//! +//! println!( +//! "removing {}{}", +//! flags.path.display(), +//! if flags.recursive { "recursively" } else { "" }, +//! ) +//! } +//! ``` +//! +//! The above program, when run with `--help` argument, generates the following +//! help: +//! +//! ```text +//! ARGS: +//! +//! File or directory to remove +//! +//! OPTIONS: +//! -r, --recursive +//! Remove directories and their contents recursively. +//! +//! -h, --help +//! Prints help information. +//! ``` +//! +//! For larger programs, you'd typically want to use `xflags!` macro, which +//! generates _named_ structs for you. Unlike a typical macro, `xflags` writes +//! generated code into the source file, to make it easy to understand the rust +//! types at a glance. //! //! ``` //! mod flags { @@ -15,9 +68,8 @@ //! xflags::xflags! { //! src "./examples/basic.rs" //! -//! cmd my-command +//! cmd my-command { //! required path: PathBuf -//! { //! optional -v, --verbose //! } //! } @@ -28,17 +80,16 @@ //! #[derive(Debug)] //! pub struct MyCommand { //! pub path: PathBuf, -//! //! pub verbose: bool, //! } //! //! impl MyCommand { -//! pub const HELP: &'static str = Self::HELP_; -//! +//! pub fn from_env_or_exit() -> Self { +//! Self::from_env_or_exit_() +//! } //! pub fn from_env() -> xflags::Result { //! Self::from_env_() //! } -//! //! pub fn from_vec(args: Vec) -> xflags::Result { //! Self::from_vec_(args) //! } @@ -52,15 +103,15 @@ //! } //! ``` //! -//! To make the macro less opaque, `xflag` can generate `struct` describing the -//! CLI in-place. To disable this behavior, omit the `src` attribute. +//! If you'd rather use a typical proc-macro which generates hidden code, just +//! omit the src attribute. //! //! xflags correctly handles non-utf8 arguments. //! //! ## Syntax Reference //! -//! The **cmd** keyword introduces a command that accepts positional arguments -//! and switches. +//! The `xflags!` macro uses **cmd** keyword to introduce a command or +//! subcommand that accepts positional arguments and switches. //! //! ``` //! xflags::xflags! { @@ -75,9 +126,9 @@ //! ``` //! xflags::xflags! { //! cmd switches { -//! optional -h, --help -//! repeated --verbose +//! optional -q,--quiet //! required --pass-me +//! repeated --verbose //! } //! } //! ``` @@ -98,20 +149,21 @@ //! } //! ``` //! -//! Positional arguments are specified before the opening curly brace: +//! Arguments without `--` in then are are positional. //! //! ``` //! use std::{path::PathBuf, ffi::OsString}; //! //! xflags::xflags! { -//! cmd positional-arguments +//! cmd positional-arguments { //! required program: PathBuf //! repeated args: OsString -//! { } +//! } //! } //! ``` //! -//! Nesting **cmd** is allowed: +//! Nesting **cmd** is allowed. `xflag` automatically generates boilerplate +//! enums for subcommands: //! //! ```ignore //! xflags::xflags! { @@ -148,12 +200,12 @@ //! } //! //! impl App { -//! pub const HELP: &'static str = Self::HELP_; -//! +//! pub fn from_env_or_exit() -> Self { +//! Self::from_env_or_exit_() +//! } //! pub fn from_env() -> xflags::Result { //! Self::from_env_() //! } -//! //! pub fn from_vec(args: Vec) -> xflags::Result { //! Self::from_vec_(args) //! } @@ -161,6 +213,9 @@ //! // generated end //! ``` //! +//! Switches are always "inherited". Both `app -v foo` and `app foo -v` produce +//! the same result. +//! //! To make subcommand name optional use the **default** keyword to mark a //! subcommand to select if no subcommand name is passed. The name of the //! default subcommand affects only the name of the generated Rust struct, it @@ -176,8 +231,8 @@ //! } //! ``` //! -//! Commands, arguments, and switches can documented. Doc comments become a part -//! of generated help: +//! Commands, arguments, and switches can be documented. Doc comments become a +//! part of generated help: //! //! ``` //! mod flags { @@ -185,14 +240,11 @@ //! //! xflags::xflags! { //! /// Run basic system diagnostics. -//! cmd healthck +//! cmd healthck { //! /// Optional configuration file. //! optional config: PathBuf -//! { //! /// Verbosity level, can be repeated multiple times. //! repeated -v, --verbose -//! /// Print the help message. -//! optional -h, --help //! } //! } //! } @@ -200,24 +252,18 @@ //! fn main() { //! match flags::Healthck::from_env() { //! Ok(flags) => { -//! if flags.help { -//! println!("{}", flags::Healthck::HELP); -//! return; -//! } //! run_checks(flags.config, flags.verbose); //! } -//! Err(err) => { -//! eprintln!("{}", err); -//! } +//! Err(err) => err.exit() //! } //! } //! //! # fn run_checks(_config: Option, _verbosity: u32) {} //! ``` //! -//! The **src** keyword controlls how the code generation works. If it is -//! absent, `xflags` acts as a typical procedure macro, which generates a bunch -//! of structs and impls. +//! The **src** keyword controls how the code generation works. If it is absent, +//! `xflags` acts as a typical procedure macro, which generates a bunch of +//! structs and impls. //! //! If the **src** keyword is present, it should specify the path to the file //! with `xflags!` invocation. The path should be relative to the directory with @@ -226,7 +272,7 @@ //! directly to the specified file. //! //! By convention, `xflag!` macro should be invoked from the `flags` submodule. -//! The `flags::` preffix should be used to refer to command names. Additional +//! The `flags::` prefix should be used to refer to command names. Additional //! validation logic can go to the `flags` module: //! //! ``` @@ -250,21 +296,43 @@ //! } //! } //! ``` +//! +//! The `parse_or_exit!` macro is a syntactic sure for `xflags!`, which +//! immediately parses the argument, exiting the process if needed. +//! `parse_or_exit` only supports single top-level command and doesn't need the +//! `cmd` keyword. +//! +//! ## Limitations +//! +//! `xflags` follows +//! [Fuchsia](https://fuchsia.dev/fuchsia-src/development/api/cli#command_line_arguments) +//! conventions for command line arguments. GNU conventions such as grouping +//! short-flags (`-xyz`) or gluing short flag and a value `(-fVAL)` are not +//! supported. +//! +//! `xflags` requires the command line interface to be fully static. It's +//! impossible to include additional flags at runtime. +//! +//! Implementation is not fully robust, there might be some residual bugs in +//! edge cases. use std::fmt; /// Generates a parser for command line arguments from a DSL. /// /// See the module-level for detailed syntax specification. -pub use xflags_macros::xflags; +pub use xflags_macros::{parse_or_exit, xflags}; pub type Result = std::result::Result; -/// This type represents an error that can occur during command line argument -/// parsing. +/// An error occurred when parssing command line arguments. +/// +/// Either the command line was syntactically invalid, or `--help` was +/// explicitly requested. #[derive(Debug)] pub struct Error { msg: String, + help: bool, } impl fmt::Display for Error { @@ -280,7 +348,23 @@ impl Error { /// /// Use this to report custom validation errors. pub fn new(message: impl Into) -> Error { - Error { msg: message.into() } + Error { msg: message.into(), help: false } + } + + /// Error that carries `--help` message. + pub fn is_help(&self) -> bool { + self.help + } + + /// Prints the error and exists the process. + pub fn exit(self) -> ! { + if self.is_help() { + println!("{self}"); + std::process::exit(0) + } else { + eprintln!("{self}"); + std::process::exit(2) + } } } diff --git a/vendor/xflags/src/rt.rs b/vendor/xflags/src/rt.rs index 3c33196af..988e6cc23 100644 --- a/vendor/xflags/src/rt.rs +++ b/vendor/xflags/src/rt.rs @@ -4,7 +4,7 @@ use crate::{Error, Result}; macro_rules! format_err { ($($tt:tt)*) => { - Error { msg: format!($($tt)*) } + Error { msg: format!($($tt)*), help: false } }; } @@ -94,6 +94,14 @@ impl Parser { format_err!("unexpected argument: {:?}", arg) } + pub fn subcommand_required(&self) -> Error { + format_err!("subcommand is required") + } + + pub fn help(&self, help: &'static str) -> Error { + Error { msg: help.to_string(), help: true } + } + pub fn optional(&self, flag: &str, mut vals: Vec) -> Result> { if vals.len() > 1 { bail!("flag specified more than once: `{}`", flag) @@ -107,8 +115,4 @@ impl Parser { } vals.pop().ok_or_else(|| format_err!("flag is required: `{}`", flag)) } - - pub fn subcommand(&self, cmd: Option) -> Result { - cmd.ok_or_else(|| format_err!("subcommand is required")) - } } -- cgit v1.2.3

{} - - pub trait _ValueParserViaValueEnumSealed {} - impl _ValueParserViaValueEnumSealed for &_AutoValueParser {} - - pub trait _ValueParserViaFromStrSealed {} - impl _ValueParserViaFromStrSealed for _AutoValueParser - where - FromStr: std::str::FromStr + std::any::Any + Send + Sync + 'static, - ::Err: - Into>, - { - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn ensure_typed_applies_to_parse() { - fn parse(_: &str) -> Result { - Ok(10) - } - let cmd = crate::Command::new("cmd"); - let arg = None; - assert_eq!( - TypedValueParser::parse_ref(&parse, &cmd, arg, std::ffi::OsStr::new("foo")).unwrap(), - 10 - ); - } -} diff --git a/vendor/clap/src/derive.rs b/vendor/clap/src/derive.rs deleted file mode 100644 index b6ac04df6..000000000 --- a/vendor/clap/src/derive.rs +++ /dev/null @@ -1,577 +0,0 @@ -//! This module contains traits that are usable with the `#[derive(...)].` -//! macros in [`clap_derive`]. - -use crate::{ArgMatches, Command, Error, PossibleValue}; - -use std::ffi::OsString; - -/// Parse command-line arguments into `Self`. -/// -/// The primary one-stop-shop trait used to create an instance of a `clap` -/// [`Command`], conduct the parsing, and turn the resulting [`ArgMatches`] back -/// into concrete instance of the user struct. -/// -/// This trait is primarily a convenience on top of [`FromArgMatches`] + -/// [`CommandFactory`] which uses those two underlying traits to build the two -/// fundamental functions `parse` which uses the `std::env::args_os` iterator, -/// and `parse_from` which allows the consumer to supply the iterator (along -/// with fallible options for each). -/// -/// See also [`Subcommand`] and [`Args`]. -/// -/// See the [derive reference](crate::_derive) for attributes and best practices. -/// -/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] -/// -/// # Examples -/// -/// The following example creates a `Context` struct that would be used -/// throughout the application representing the normalized values coming from -/// the CLI. -/// -#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] -#[cfg_attr(feature = "derive", doc = " ```")] -/// /// My super CLI -/// #[derive(clap::Parser)] -/// #[clap(name = "demo")] -/// struct Context { -/// /// More verbose output -/// #[clap(long)] -/// verbose: bool, -/// /// An optional name -/// #[clap(short, long)] -/// name: Option, -/// } -/// ``` -/// -/// The equivalent [`Command`] struct + `From` implementation: -/// -/// ```rust -/// # use clap::{Command, Arg, ArgMatches, ArgAction}; -/// Command::new("demo") -/// .about("My super CLI") -/// .arg(Arg::new("verbose") -/// .long("verbose") -/// .action(ArgAction::SetTrue) -/// .help("More verbose output")) -/// .arg(Arg::new("name") -/// .long("name") -/// .short('n') -/// .help("An optional name") -/// .takes_value(true)); -/// -/// struct Context { -/// verbose: bool, -/// name: Option, -/// } -/// -/// impl From for Context { -/// fn from(m: ArgMatches) -> Self { -/// Context { -/// verbose: *m.get_one::("verbose").expect("defaulted_by_clap"), -/// name: m.get_one::("name").cloned(), -/// } -/// } -/// } -/// ``` -/// -pub trait Parser: FromArgMatches + CommandFactory + Sized { - /// Parse from `std::env::args_os()`, exit on error - fn parse() -> Self { - let mut matches = ::command().get_matches(); - let res = ::from_arg_matches_mut(&mut matches) - .map_err(format_error::); - match res { - Ok(s) => s, - Err(e) => { - // Since this is more of a development-time error, we aren't doing as fancy of a quit - // as `get_matches` - e.exit() - } - } - } - - /// Parse from `std::env::args_os()`, return Err on error. - fn try_parse() -> Result { - let mut matches = ::command().try_get_matches()?; - ::from_arg_matches_mut(&mut matches).map_err(format_error::) - } - - /// Parse from iterator, exit on error - fn parse_from(itr: I) -> Self - where - I: IntoIterator, - T: Into + Clone, - { - let mut matches = ::command().get_matches_from(itr); - let res = ::from_arg_matches_mut(&mut matches) - .map_err(format_error::); - match res { - Ok(s) => s, - Err(e) => { - // Since this is more of a development-time error, we aren't doing as fancy of a quit - // as `get_matches_from` - e.exit() - } - } - } - - /// Parse from iterator, return Err on error. - fn try_parse_from(itr: I) -> Result - where - I: IntoIterator, - T: Into + Clone, - { - let mut matches = ::command().try_get_matches_from(itr)?; - ::from_arg_matches_mut(&mut matches).map_err(format_error::) - } - - /// Update from iterator, exit on error - fn update_from(&mut self, itr: I) - where - I: IntoIterator, - T: Into + Clone, - { - let mut matches = ::command_for_update().get_matches_from(itr); - let res = ::update_from_arg_matches_mut(self, &mut matches) - .map_err(format_error::); - if let Err(e) = res { - // Since this is more of a development-time error, we aren't doing as fancy of a quit - // as `get_matches_from` - e.exit() - } - } - - /// Update from iterator, return Err on error. - fn try_update_from(&mut self, itr: I) -> Result<(), Error> - where - I: IntoIterator, - T: Into + Clone, - { - let mut matches = - ::command_for_update().try_get_matches_from(itr)?; - ::update_from_arg_matches_mut(self, &mut matches) - .map_err(format_error::) - } - - /// Deprecated, `StructOpt::clap` replaced with [`CommandFactory::command`] (derive as part of - /// [`Parser`]) - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "`StructOpt::clap` is replaced with `CommandFactory::command` (derived as part of `Parser`)" - ) - )] - #[doc(hidden)] - fn clap<'help>() -> Command<'help> { - ::command() - } - - /// Deprecated, `StructOpt::from_clap` replaced with [`FromArgMatches::from_arg_matches_mut`] (derive as part of - /// [`Parser`]) - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "`StructOpt::from_clap` is replaced with `FromArgMatches::from_arg_matches_mut` (derived as part of `Parser`)" - ) - )] - #[doc(hidden)] - fn from_clap(matches: &ArgMatches) -> Self { - ::from_arg_matches(matches).unwrap() - } - - /// Deprecated, `StructOpt::from_args` replaced with `Parser::parse` (note the change in derives) - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "`StructOpt::from_args` is replaced with `Parser::parse` (note the change in derives)" - ) - )] - #[doc(hidden)] - fn from_args() -> Self { - Self::parse() - } - - /// Deprecated, `StructOpt::from_args_safe` replaced with `Parser::try_parse` (note the change in derives) - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "`StructOpt::from_args_safe` is replaced with `Parser::try_parse` (note the change in derives)" - ) - )] - #[doc(hidden)] - fn from_args_safe() -> Result { - Self::try_parse() - } - - /// Deprecated, `StructOpt::from_iter` replaced with `Parser::parse_from` (note the change in derives) - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "`StructOpt::from_iter` is replaced with `Parser::parse_from` (note the change in derives)" - ) - )] - #[doc(hidden)] - fn from_iter(itr: I) -> Self - where - I: IntoIterator, - T: Into + Clone, - { - Self::parse_from(itr) - } - - /// Deprecated, `StructOpt::from_iter_safe` replaced with `Parser::try_parse_from` (note the - /// change in derives) - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "`StructOpt::from_iter_safe` is replaced with `Parser::try_parse_from` (note the change in derives)" - ) - )] - #[doc(hidden)] - fn from_iter_safe(itr: I) -> Result - where - I: IntoIterator, - T: Into + Clone, - { - Self::try_parse_from(itr) - } -} - -/// Create a [`Command`] relevant for a user-defined container. -/// -/// Derived as part of [`Parser`]. -pub trait CommandFactory: Sized { - /// Build a [`Command`] that can instantiate `Self`. - /// - /// See [`FromArgMatches::from_arg_matches_mut`] for instantiating `Self`. - fn command<'help>() -> Command<'help> { - #[allow(deprecated)] - Self::into_app() - } - /// Deprecated, replaced with `CommandFactory::command` - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `CommandFactory::command") - )] - fn into_app<'help>() -> Command<'help>; - /// Build a [`Command`] that can update `self`. - /// - /// See [`FromArgMatches::update_from_arg_matches_mut`] for updating `self`. - fn command_for_update<'help>() -> Command<'help> { - #[allow(deprecated)] - Self::into_app_for_update() - } - /// Deprecated, replaced with `CommandFactory::command_for_update` - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.1.0", - note = "Replaced with `CommandFactory::command_for_update" - ) - )] - fn into_app_for_update<'help>() -> Command<'help>; -} - -/// Converts an instance of [`ArgMatches`] to a user-defined container. -/// -/// Derived as part of [`Parser`], [`Args`], and [`Subcommand`]. -pub trait FromArgMatches: Sized { - /// Instantiate `Self` from [`ArgMatches`], parsing the arguments as needed. - /// - /// Motivation: If our application had two CLI options, `--name - /// ` and the flag `--debug`, we may create a struct as follows: - /// - #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] - #[cfg_attr(feature = "derive", doc = " ```no_run")] - /// struct Context { - /// name: String, - /// debug: bool - /// } - /// ``` - /// - /// We then need to convert the `ArgMatches` that `clap` generated into our struct. - /// `from_arg_matches` serves as the equivalent of: - /// - #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] - #[cfg_attr(feature = "derive", doc = " ```no_run")] - /// # use clap::ArgMatches; - /// # struct Context { - /// # name: String, - /// # debug: bool - /// # } - /// impl From for Context { - /// fn from(m: ArgMatches) -> Self { - /// Context { - /// name: m.get_one::("name").unwrap().clone(), - /// debug: *m.get_one::("debug").expect("defaulted by clap"), - /// } - /// } - /// } - /// ``` - fn from_arg_matches(matches: &ArgMatches) -> Result; - - /// Instantiate `Self` from [`ArgMatches`], parsing the arguments as needed. - /// - /// Motivation: If our application had two CLI options, `--name - /// ` and the flag `--debug`, we may create a struct as follows: - /// - #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] - #[cfg_attr(feature = "derive", doc = " ```no_run")] - /// struct Context { - /// name: String, - /// debug: bool - /// } - /// ``` - /// - /// We then need to convert the `ArgMatches` that `clap` generated into our struct. - /// `from_arg_matches_mut` serves as the equivalent of: - /// - #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] - #[cfg_attr(feature = "derive", doc = " ```no_run")] - /// # use clap::ArgMatches; - /// # struct Context { - /// # name: String, - /// # debug: bool - /// # } - /// impl From for Context { - /// fn from(m: ArgMatches) -> Self { - /// Context { - /// name: m.get_one::("name").unwrap().to_string(), - /// debug: *m.get_one::("debug").expect("defaulted by clap"), - /// } - /// } - /// } - /// ``` - fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { - Self::from_arg_matches(matches) - } - - /// Assign values from `ArgMatches` to `self`. - fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error>; - - /// Assign values from `ArgMatches` to `self`. - fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { - self.update_from_arg_matches(matches) - } -} - -/// Parse a set of arguments into a user-defined container. -/// -/// Implementing this trait lets a parent container delegate argument parsing behavior to `Self`. -/// with: -/// - `#[clap(flatten)] args: ChildArgs`: Attribute can only be used with struct fields that impl -/// `Args`. -/// - `Variant(ChildArgs)`: No attribute is used with enum variants that impl `Args`. -/// -/// See the [derive reference](crate::_derive) for attributes and best practices. -/// -/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] -/// -/// # Example -/// -#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] -#[cfg_attr(feature = "derive", doc = " ```")] -/// #[derive(clap::Parser)] -/// struct Args { -/// #[clap(flatten)] -/// logging: LogArgs, -/// } -/// -/// #[derive(clap::Args)] -/// struct LogArgs { -/// #[clap(long, short = 'v', parse(from_occurrences))] -/// verbose: i8, -/// } -/// ``` -pub trait Args: FromArgMatches + Sized { - /// Append to [`Command`] so it can instantiate `Self`. - /// - /// See also [`CommandFactory`]. - fn augment_args(cmd: Command<'_>) -> Command<'_>; - /// Append to [`Command`] so it can update `self`. - /// - /// This is used to implement `#[clap(flatten)]` - /// - /// See also [`CommandFactory`]. - fn augment_args_for_update(cmd: Command<'_>) -> Command<'_>; -} - -/// Parse a sub-command into a user-defined enum. -/// -/// Implementing this trait lets a parent container delegate subcommand behavior to `Self`. -/// with: -/// - `#[clap(subcommand)] field: SubCmd`: Attribute can be used with either struct fields or enum -/// variants that impl `Subcommand`. -/// - `#[clap(flatten)] Variant(SubCmd)`: Attribute can only be used with enum variants that impl -/// `Subcommand`. -/// -/// See the [derive reference](crate::_derive) for attributes and best practices. -/// -/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] -/// -/// # Example -/// -#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] -#[cfg_attr(feature = "derive", doc = " ```")] -/// #[derive(clap::Parser)] -/// struct Args { -/// #[clap(subcommand)] -/// action: Action, -/// } -/// -/// #[derive(clap::Subcommand)] -/// enum Action { -/// Add, -/// Remove, -/// } -/// ``` -pub trait Subcommand: FromArgMatches + Sized { - /// Append to [`Command`] so it can instantiate `Self`. - /// - /// See also [`CommandFactory`]. - fn augment_subcommands(cmd: Command<'_>) -> Command<'_>; - /// Append to [`Command`] so it can update `self`. - /// - /// This is used to implement `#[clap(flatten)]` - /// - /// See also [`CommandFactory`]. - fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_>; - /// Test whether `Self` can parse a specific subcommand - fn has_subcommand(name: &str) -> bool; -} - -/// Parse arguments into enums. -/// -/// When deriving [`Parser`], a field whose type implements `ValueEnum` can have the attribute -/// `#[clap(value_enum)]` which will -/// - Call [`Arg::possible_values`][crate::Arg::possible_values] -/// - Allowing using the `#[clap(default_value_t)]` attribute without implementing `Display`. -/// -/// See the [derive reference](crate::_derive) for attributes and best practices. -/// -/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] -/// -/// # Example -/// -#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] -#[cfg_attr(feature = "derive", doc = " ```")] -/// #[derive(clap::Parser)] -/// struct Args { -/// #[clap(value_enum)] -/// level: Level, -/// } -/// -/// #[derive(clap::ValueEnum, Clone)] -/// enum Level { -/// Debug, -/// Info, -/// Warning, -/// Error, -/// } -/// ``` -pub trait ValueEnum: Sized + Clone { - /// All possible argument values, in display order. - fn value_variants<'a>() -> &'a [Self]; - - /// Parse an argument into `Self`. - fn from_str(input: &str, ignore_case: bool) -> Result { - Self::value_variants() - .iter() - .find(|v| { - v.to_possible_value() - .expect("ValueEnum::value_variants contains only values with a corresponding ValueEnum::to_possible_value") - .matches(input, ignore_case) - }) - .cloned() - .ok_or_else(|| format!("Invalid variant: {}", input)) - } - - /// The canonical argument value. - /// - /// The value is `None` for skipped variants. - fn to_possible_value<'a>(&self) -> Option>; -} - -impl Parser for Box { - fn parse() -> Self { - Box::new(::parse()) - } - - fn try_parse() -> Result { - ::try_parse().map(Box::new) - } - - fn parse_from(itr: I) -> Self - where - I: IntoIterator, - It: Into + Clone, - { - Box::new(::parse_from(itr)) - } - - fn try_parse_from(itr: I) -> Result - where - I: IntoIterator, - It: Into + Clone, - { - ::try_parse_from(itr).map(Box::new) - } -} - -#[allow(deprecated)] -impl CommandFactory for Box { - fn into_app<'help>() -> Command<'help> { - ::into_app() - } - fn into_app_for_update<'help>() -> Command<'help> { - ::into_app_for_update() - } -} - -impl FromArgMatches for Box { - fn from_arg_matches(matches: &ArgMatches) -> Result { - ::from_arg_matches(matches).map(Box::new) - } - fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { - ::from_arg_matches_mut(matches).map(Box::new) - } - fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { - ::update_from_arg_matches(self, matches) - } - fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { - ::update_from_arg_matches_mut(self, matches) - } -} - -impl Args for Box { - fn augment_args(cmd: Command<'_>) -> Command<'_> { - ::augment_args(cmd) - } - fn augment_args_for_update(cmd: Command<'_>) -> Command<'_> { - ::augment_args_for_update(cmd) - } -} - -impl Subcommand for Box { - fn augment_subcommands(cmd: Command<'_>) -> Command<'_> { - ::augment_subcommands(cmd) - } - fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_> { - ::augment_subcommands_for_update(cmd) - } - fn has_subcommand(name: &str) -> bool { - ::has_subcommand(name) - } -} - -fn format_error(err: crate::Error) -> crate::Error { - let mut cmd = I::command(); - err.format(&mut cmd) -} diff --git a/vendor/clap/src/error/context.rs b/vendor/clap/src/error/context.rs deleted file mode 100644 index 985cd4d70..000000000 --- a/vendor/clap/src/error/context.rs +++ /dev/null @@ -1,55 +0,0 @@ -/// Semantics for a piece of error information -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[non_exhaustive] -pub enum ContextKind { - /// The cause of the error - InvalidSubcommand, - /// The cause of the error - InvalidArg, - /// Existing arguments - PriorArg, - /// Accepted values - ValidValue, - /// Rejected values - InvalidValue, - /// Number of values present - ActualNumValues, - /// Number of allowed values - ExpectedNumValues, - /// Minimum number of allowed values - MinValues, - /// Number of occurrences present - ActualNumOccurrences, - /// Maximum number of allowed occurrences - MaxOccurrences, - /// Potential fix for the user - SuggestedCommand, - /// Potential fix for the user - SuggestedSubcommand, - /// Potential fix for the user - SuggestedArg, - /// Potential fix for the user - SuggestedValue, - /// Trailing argument - TrailingArg, - /// A usage string - Usage, - /// An opaque message to the user - Custom, -} - -/// A piece of error information -#[derive(Clone, Debug, PartialEq, Eq)] -#[non_exhaustive] -pub enum ContextValue { - /// [`ContextKind`] is self-sufficient, no additional information needed - None, - /// A single value - Bool(bool), - /// A single value - String(String), - /// Many values - Strings(Vec), - /// A single value - Number(isize), -} diff --git a/vendor/clap/src/error/kind.rs b/vendor/clap/src/error/kind.rs deleted file mode 100644 index 4c3dc48b0..000000000 --- a/vendor/clap/src/error/kind.rs +++ /dev/null @@ -1,440 +0,0 @@ -/// Command line argument parser kind of error -#[derive(Debug, Copy, Clone, PartialEq)] -#[non_exhaustive] -pub enum ErrorKind { - /// Occurs when an [`Arg`][crate::Arg] has a set of possible values, - /// and the user provides a value which isn't in that set. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("speed") - /// .value_parser(["fast", "slow"])) - /// .try_get_matches_from(vec!["prog", "other"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue); - /// ``` - InvalidValue, - - /// Occurs when a user provides a flag, option, argument or subcommand which isn't defined. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(arg!(--flag "some flag")) - /// .try_get_matches_from(vec!["prog", "--other"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnknownArgument); - /// ``` - UnknownArgument, - - /// Occurs when the user provides an unrecognized [`Subcommand`] which meets the threshold for - /// being similar enough to an existing subcommand. - /// If it doesn't meet the threshold, or the 'suggestions' feature is disabled, - /// the more general [`UnknownArgument`] error is returned. - /// - /// # Examples - /// - #[cfg_attr(not(feature = "suggestions"), doc = " ```no_run")] - #[cfg_attr(feature = "suggestions", doc = " ```")] - /// # use clap::{Command, Arg, ErrorKind, }; - /// let result = Command::new("prog") - /// .subcommand(Command::new("config") - /// .about("Used for configuration") - /// .arg(Arg::new("config_file") - /// .help("The configuration file to use"))) - /// .try_get_matches_from(vec!["prog", "confi"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand); - /// ``` - /// - /// [`Subcommand`]: crate::Subcommand - /// [`UnknownArgument`]: ErrorKind::UnknownArgument - InvalidSubcommand, - - /// Occurs when the user provides an unrecognized [`Subcommand`] which either - /// doesn't meet the threshold for being similar enough to an existing subcommand, - /// or the 'suggestions' feature is disabled. - /// Otherwise the more detailed [`InvalidSubcommand`] error is returned. - /// - /// This error typically happens when passing additional subcommand names to the `help` - /// subcommand. Otherwise, the more general [`UnknownArgument`] error is used. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind, }; - /// let result = Command::new("prog") - /// .subcommand(Command::new("config") - /// .about("Used for configuration") - /// .arg(Arg::new("config_file") - /// .help("The configuration file to use"))) - /// .try_get_matches_from(vec!["prog", "help", "nothing"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand); - /// ``` - /// - /// [`Subcommand`]: crate::Subcommand - /// [`InvalidSubcommand`]: ErrorKind::InvalidSubcommand - /// [`UnknownArgument`]: ErrorKind::UnknownArgument - UnrecognizedSubcommand, - - /// Occurs when the user provides an empty value for an option that does not allow empty - /// values. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("color") - /// .takes_value(true) - /// .forbid_empty_values(true) - /// .long("color")) - /// .try_get_matches_from(vec!["prog", "--color="]); - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::EmptyValue); - /// ``` - EmptyValue, - - /// Occurs when the user doesn't use equals for an option that requires equal - /// sign to provide values. - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let res = Command::new("prog") - /// .arg(Arg::new("color") - /// .takes_value(true) - /// .require_equals(true) - /// .long("color")) - /// .try_get_matches_from(vec!["prog", "--color", "red"]); - /// assert!(res.is_err()); - /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals); - /// ``` - NoEquals, - - /// Occurs when the user provides a value for an argument with a custom validation and the - /// value fails that validation. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// fn is_numeric(val: &str) -> Result<(), String> { - /// match val.parse::() { - /// Ok(..) => Ok(()), - /// Err(..) => Err(String::from("Value wasn't a number!")), - /// } - /// } - /// - /// let result = Command::new("prog") - /// .arg(Arg::new("num") - /// .validator(is_numeric)) - /// .try_get_matches_from(vec!["prog", "NotANumber"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation); - /// ``` - ValueValidation, - - /// Occurs when a user provides more values for an argument than were defined by setting - /// [`Arg::max_values`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("arg") - /// .max_values(2)) - /// .try_get_matches_from(vec!["prog", "too", "many", "values"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyValues); - /// ``` - /// [`Arg::max_values`]: crate::Arg::max_values() - TooManyValues, - - /// Occurs when the user provides fewer values for an argument than were defined by setting - /// [`Arg::min_values`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("some_opt") - /// .long("opt") - /// .min_values(3)) - /// .try_get_matches_from(vec!["prog", "--opt", "too", "few"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooFewValues); - /// ``` - /// [`Arg::min_values`]: crate::Arg::min_values() - TooFewValues, - - /// Occurs when a user provides more occurrences for an argument than were defined by setting - /// [`Arg::max_occurrences`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("verbosity") - /// .short('v') - /// .max_occurrences(2)) - /// .try_get_matches_from(vec!["prog", "-vvv"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyOccurrences); - /// ``` - /// [`Arg::max_occurrences`]: crate::Arg::max_occurrences() - TooManyOccurrences, - - /// Occurs when the user provides a different number of values for an argument than what's - /// been defined by setting [`Arg::number_of_values`] or than was implicitly set by - /// [`Arg::value_names`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("some_opt") - /// .long("opt") - /// .takes_value(true) - /// .number_of_values(2)) - /// .try_get_matches_from(vec!["prog", "--opt", "wrong"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::WrongNumberOfValues); - /// ``` - /// - /// [`Arg::number_of_values`]: crate::Arg::number_of_values() - /// [`Arg::value_names`]: crate::Arg::value_names() - WrongNumberOfValues, - - /// Occurs when the user provides two values which conflict with each other and can't be used - /// together. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("debug") - /// .long("debug") - /// .conflicts_with("color")) - /// .arg(Arg::new("color") - /// .long("color")) - /// .try_get_matches_from(vec!["prog", "--debug", "--color"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ArgumentConflict); - /// ``` - ArgumentConflict, - - /// Occurs when the user does not provide one or more required arguments. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("debug") - /// .required(true)) - /// .try_get_matches_from(vec!["prog"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); - /// ``` - MissingRequiredArgument, - - /// Occurs when a subcommand is required (as defined by [`Command::subcommand_required`]), - /// but the user does not provide one. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, ErrorKind}; - /// let err = Command::new("prog") - /// .subcommand_required(true) - /// .subcommand(Command::new("test")) - /// .try_get_matches_from(vec![ - /// "myprog", - /// ]); - /// assert!(err.is_err()); - /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand); - /// # ; - /// ``` - /// - /// [`Command::subcommand_required`]: crate::Command::subcommand_required - MissingSubcommand, - - /// Occurs when the user provides multiple values to an argument which doesn't allow that. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .arg(Arg::new("debug") - /// .long("debug") - /// .multiple_occurrences(false)) - /// .try_get_matches_from(vec!["prog", "--debug", "--debug"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage); - /// ``` - UnexpectedMultipleUsage, - - /// Occurs when the user provides a value containing invalid UTF-8. - /// - /// To allow arbitrary data - /// - Set [`Arg::allow_invalid_utf8`] for argument values - /// - Set [`Command::allow_invalid_utf8_for_external_subcommands`] for external-subcommand - /// values - /// - /// # Platform Specific - /// - /// Non-Windows platforms only (such as Linux, Unix, OSX, etc.) - /// - /// # Examples - /// - #[cfg_attr(not(unix), doc = " ```ignore")] - #[cfg_attr(unix, doc = " ```")] - /// # use clap::{Command, Arg, ErrorKind}; - /// # use std::os::unix::ffi::OsStringExt; - /// # use std::ffi::OsString; - /// let result = Command::new("prog") - /// .arg(Arg::new("utf8") - /// .short('u') - /// .takes_value(true)) - /// .try_get_matches_from(vec![OsString::from("myprog"), - /// OsString::from("-u"), - /// OsString::from_vec(vec![0xE9])]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidUtf8); - /// ``` - /// - /// [`Arg::allow_invalid_utf8`]: crate::Arg::allow_invalid_utf8 - /// [`Command::allow_invalid_utf8_for_external_subcommands`]: crate::Command::allow_invalid_utf8_for_external_subcommands - InvalidUtf8, - - /// Not a true "error" as it means `--help` or similar was used. - /// The help message will be sent to `stdout`. - /// - /// **Note**: If the help is displayed due to an error (such as missing subcommands) it will - /// be sent to `stderr` instead of `stdout`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .try_get_matches_from(vec!["prog", "--help"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelp); - /// ``` - DisplayHelp, - - /// Occurs when either an argument or a [`Subcommand`] is required, as defined by - /// [`Command::arg_required_else_help`] , but the user did not provide - /// one. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind, }; - /// let result = Command::new("prog") - /// .arg_required_else_help(true) - /// .subcommand(Command::new("config") - /// .about("Used for configuration") - /// .arg(Arg::new("config_file") - /// .help("The configuration file to use"))) - /// .try_get_matches_from(vec!["prog"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand); - /// ``` - /// - /// [`Subcommand`]: crate::Subcommand - /// [`Command::arg_required_else_help`]: crate::Command::arg_required_else_help - DisplayHelpOnMissingArgumentOrSubcommand, - - /// Not a true "error" as it means `--version` or similar was used. - /// The message will be sent to `stdout`. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ErrorKind}; - /// let result = Command::new("prog") - /// .version("3.0") - /// .try_get_matches_from(vec!["prog", "--version"]); - /// assert!(result.is_err()); - /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayVersion); - /// ``` - DisplayVersion, - - /// Occurs when using the [`ArgMatches::value_of_t`] and friends to convert an argument value - /// into type `T`, but the argument you requested wasn't used. I.e. you asked for an argument - /// with name `config` to be converted, but `config` wasn't used by the user. - /// - /// [`ArgMatches::value_of_t`]: crate::ArgMatches::value_of_t() - ArgumentNotFound, - - /// Represents an [I/O error]. - /// Can occur when writing to `stderr` or `stdout` or reading a configuration file. - /// - /// [I/O error]: std::io::Error - Io, - - /// Represents a [Format error] (which is a part of [`Display`]). - /// Typically caused by writing to `stderr` or `stdout`. - /// - /// [`Display`]: std::fmt::Display - /// [Format error]: std::fmt::Error - Format, -} - -impl ErrorKind { - /// End-user description of the error case, where relevant - pub fn as_str(self) -> Option<&'static str> { - match self { - Self::InvalidValue => Some("One of the values isn't valid for an argument"), - Self::UnknownArgument => { - Some("Found an argument which wasn't expected or isn't valid in this context") - } - Self::InvalidSubcommand => Some("A subcommand wasn't recognized"), - Self::UnrecognizedSubcommand => Some("A subcommand wasn't recognized"), - Self::EmptyValue => Some("An argument requires a value but none was supplied"), - Self::NoEquals => Some("Equal is needed when assigning values to one of the arguments"), - Self::ValueValidation => Some("Invalid value for one of the arguments"), - Self::TooManyValues => Some("An argument received an unexpected value"), - Self::TooFewValues => Some("An argument requires more values"), - Self::TooManyOccurrences => Some("An argument occurred too many times"), - Self::WrongNumberOfValues => Some("An argument received too many or too few values"), - Self::ArgumentConflict => { - Some("An argument cannot be used with one or more of the other specified arguments") - } - Self::MissingRequiredArgument => { - Some("One or more required arguments were not provided") - } - Self::MissingSubcommand => Some("A subcommand is required but one was not provided"), - Self::UnexpectedMultipleUsage => { - Some("An argument was provided more than once but cannot be used multiple times") - } - Self::InvalidUtf8 => Some("Invalid UTF-8 was detected in one or more arguments"), - Self::DisplayHelp => None, - Self::DisplayHelpOnMissingArgumentOrSubcommand => None, - Self::DisplayVersion => None, - Self::ArgumentNotFound => Some("An argument wasn't found"), - Self::Io => None, - Self::Format => None, - } - } -} - -impl std::fmt::Display for ErrorKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.as_str().unwrap_or_default().fmt(f) - } -} diff --git a/vendor/clap/src/error/mod.rs b/vendor/clap/src/error/mod.rs deleted file mode 100644 index fbd2b30a8..000000000 --- a/vendor/clap/src/error/mod.rs +++ /dev/null @@ -1,1153 +0,0 @@ -//! Error reporting -#![allow(deprecated)] - -// Std -use std::{ - borrow::Cow, - convert::From, - error, - fmt::{self, Debug, Display, Formatter}, - io::{self, BufRead}, - result::Result as StdResult, -}; - -// Internal -use crate::output::fmt::Colorizer; -use crate::output::fmt::Stream; -use crate::parser::features::suggestions; -use crate::util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE}; -use crate::AppSettings; -use crate::Command; - -mod context; -mod kind; - -pub use context::ContextKind; -pub use context::ContextValue; -pub use kind::ErrorKind; - -/// Short hand for [`Result`] type -/// -/// [`Result`]: std::result::Result -pub type Result = StdResult; - -/// Command Line Argument Parser Error -/// -/// See [`Command::error`] to create an error. -/// -/// [`Command::error`]: crate::Command::error -#[derive(Debug)] -pub struct Error { - inner: Box, - /// Deprecated, replaced with [`Error::kind()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Error::kind()`") - )] - pub kind: ErrorKind, - /// Deprecated, replaced with [`Error::context()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `Error::context()`") - )] - pub info: Vec, -} - -#[derive(Debug)] -struct ErrorInner { - kind: ErrorKind, - context: Vec<(ContextKind, ContextValue)>, - message: Option, - source: Option>, - help_flag: Option<&'static str>, - color_when: ColorChoice, - wait_on_exit: bool, - backtrace: Option, -} - -impl Error { - /// Create an unformatted error - /// - /// This is for you need to pass the error up to - /// a place that has access to the `Command` at which point you can call [`Error::format`]. - /// - /// Prefer [`Command::error`] for generating errors. - /// - /// [`Command::error`]: crate::Command::error - pub fn raw(kind: ErrorKind, message: impl std::fmt::Display) -> Self { - Self::new(kind).set_message(message.to_string()) - } - - /// Format the existing message with the Command's context - #[must_use] - pub fn format(mut self, cmd: &mut Command) -> Self { - cmd._build_self(); - let usage = cmd.render_usage(); - if let Some(message) = self.inner.message.as_mut() { - message.format(cmd, usage); - } - self.with_cmd(cmd) - } - - /// Type of error for programmatic processing - pub fn kind(&self) -> ErrorKind { - self.inner.kind - } - - /// Additional information to further qualify the error - pub fn context(&self) -> impl Iterator { - self.inner.context.iter().map(|(k, v)| (*k, v)) - } - - /// Should the message be written to `stdout` or not? - #[inline] - pub fn use_stderr(&self) -> bool { - self.stream() == Stream::Stderr - } - - pub(crate) fn stream(&self) -> Stream { - match self.kind() { - ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => Stream::Stdout, - _ => Stream::Stderr, - } - } - - /// Prints the error and exits. - /// - /// Depending on the error kind, this either prints to `stderr` and exits with a status of `2` - /// or prints to `stdout` and exits with a status of `0`. - pub fn exit(&self) -> ! { - if self.use_stderr() { - // Swallow broken pipe errors - let _ = self.print(); - - if self.inner.wait_on_exit { - wlnerr!("\nPress [ENTER] / [RETURN] to continue..."); - let mut s = String::new(); - let i = io::stdin(); - i.lock().read_line(&mut s).unwrap(); - } - - safe_exit(USAGE_CODE); - } - - // Swallow broken pipe errors - let _ = self.print(); - safe_exit(SUCCESS_CODE) - } - - /// Prints formatted and colored error to `stdout` or `stderr` according to its error kind - /// - /// # Example - /// ```no_run - /// use clap::Command; - /// - /// match Command::new("Command").try_get_matches() { - /// Ok(matches) => { - /// // do_something - /// }, - /// Err(err) => { - /// err.print().expect("Error writing Error"); - /// // do_something - /// }, - /// }; - /// ``` - pub fn print(&self) -> io::Result<()> { - self.formatted().print() - } - - /// Deprecated, replaced with [`Command::error`] - /// - /// [`Command::error`]: crate::Command::error - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Command::error`") - )] - #[doc(hidden)] - pub fn with_description(description: String, kind: ErrorKind) -> Self { - Error::raw(kind, description) - } - - fn new(kind: ErrorKind) -> Self { - Self { - inner: Box::new(ErrorInner { - kind, - context: Vec::new(), - message: None, - source: None, - help_flag: None, - color_when: ColorChoice::Never, - wait_on_exit: false, - backtrace: Backtrace::new(), - }), - kind, - info: vec![], - } - } - - #[inline(never)] - fn for_app(kind: ErrorKind, cmd: &Command, colorizer: Colorizer, info: Vec) -> Self { - Self::new(kind) - .set_message(colorizer) - .with_cmd(cmd) - .set_info(info) - } - - pub(crate) fn with_cmd(self, cmd: &Command) -> Self { - self.set_wait_on_exit(cmd.is_set(AppSettings::WaitOnError)) - .set_color(cmd.get_color()) - .set_help_flag(get_help_flag(cmd)) - } - - pub(crate) fn set_message(mut self, message: impl Into) -> Self { - self.inner.message = Some(message.into()); - self - } - - pub(crate) fn set_info(mut self, info: Vec) -> Self { - self.info = info; - self - } - - pub(crate) fn set_source(mut self, source: Box) -> Self { - self.inner.source = Some(source); - self - } - - pub(crate) fn set_color(mut self, color_when: ColorChoice) -> Self { - self.inner.color_when = color_when; - self - } - - pub(crate) fn set_help_flag(mut self, help_flag: Option<&'static str>) -> Self { - self.inner.help_flag = help_flag; - self - } - - pub(crate) fn set_wait_on_exit(mut self, yes: bool) -> Self { - self.inner.wait_on_exit = yes; - self - } - - /// Does not verify if `ContextKind` is already present - #[inline(never)] - pub(crate) fn insert_context_unchecked( - mut self, - kind: ContextKind, - value: ContextValue, - ) -> Self { - self.inner.context.push((kind, value)); - self - } - - /// Does not verify if `ContextKind` is already present - #[inline(never)] - pub(crate) fn extend_context_unchecked( - mut self, - context: [(ContextKind, ContextValue); N], - ) -> Self { - self.inner.context.extend(context); - self - } - - #[inline(never)] - fn get_context(&self, kind: ContextKind) -> Option<&ContextValue> { - self.inner - .context - .iter() - .find_map(|(k, v)| (*k == kind).then(|| v)) - } - - pub(crate) fn display_help(cmd: &Command, colorizer: Colorizer) -> Self { - Self::for_app(ErrorKind::DisplayHelp, cmd, colorizer, vec![]) - } - - pub(crate) fn display_help_error(cmd: &Command, colorizer: Colorizer) -> Self { - Self::for_app( - ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand, - cmd, - colorizer, - vec![], - ) - } - - pub(crate) fn display_version(cmd: &Command, colorizer: Colorizer) -> Self { - Self::for_app(ErrorKind::DisplayVersion, cmd, colorizer, vec![]) - } - - pub(crate) fn argument_conflict( - cmd: &Command, - arg: String, - mut others: Vec, - usage: String, - ) -> Self { - let info = others.clone(); - let others = match others.len() { - 0 => ContextValue::None, - 1 => ContextValue::String(others.pop().unwrap()), - _ => ContextValue::Strings(others), - }; - Self::new(ErrorKind::ArgumentConflict) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::PriorArg, others), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn empty_value(cmd: &Command, good_vals: &[&str], arg: String) -> Self { - let info = vec![arg.clone()]; - let mut err = Self::new(ErrorKind::EmptyValue) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]); - if !good_vals.is_empty() { - err = err.insert_context_unchecked( - ContextKind::ValidValue, - ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()), - ); - } - err - } - - pub(crate) fn no_equals(cmd: &Command, arg: String, usage: String) -> Self { - let info = vec![arg.clone()]; - Self::new(ErrorKind::NoEquals) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn invalid_value( - cmd: &Command, - bad_val: String, - good_vals: &[&str], - arg: String, - ) -> Self { - let mut info = vec![arg.clone(), bad_val.clone()]; - info.extend(good_vals.iter().map(|s| (*s).to_owned())); - - let suggestion = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop(); - let mut err = Self::new(ErrorKind::InvalidValue) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::InvalidValue, ContextValue::String(bad_val)), - ( - ContextKind::ValidValue, - ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()), - ), - ]); - if let Some(suggestion) = suggestion { - err = err.insert_context_unchecked( - ContextKind::SuggestedValue, - ContextValue::String(suggestion), - ); - } - err - } - - pub(crate) fn invalid_subcommand( - cmd: &Command, - subcmd: String, - did_you_mean: String, - name: String, - usage: String, - ) -> Self { - let info = vec![subcmd.clone()]; - let suggestion = format!("{} -- {}", name, subcmd); - Self::new(ErrorKind::InvalidSubcommand) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)), - ( - ContextKind::SuggestedSubcommand, - ContextValue::String(did_you_mean), - ), - ( - ContextKind::SuggestedCommand, - ContextValue::String(suggestion), - ), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn unrecognized_subcommand(cmd: &Command, subcmd: String, usage: String) -> Self { - let info = vec![subcmd.clone()]; - Self::new(ErrorKind::UnrecognizedSubcommand) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn missing_required_argument( - cmd: &Command, - required: Vec, - usage: String, - ) -> Self { - let info = required.clone(); - Self::new(ErrorKind::MissingRequiredArgument) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::Strings(required)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn missing_subcommand(cmd: &Command, name: String, usage: String) -> Self { - let info = vec![]; - Self::new(ErrorKind::MissingSubcommand) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidSubcommand, ContextValue::String(name)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn invalid_utf8(cmd: &Command, usage: String) -> Self { - let info = vec![]; - Self::new(ErrorKind::InvalidUtf8) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([(ContextKind::Usage, ContextValue::String(usage))]) - } - - pub(crate) fn too_many_occurrences( - cmd: &Command, - arg: String, - max_occurs: usize, - curr_occurs: usize, - usage: String, - ) -> Self { - let info = vec![arg.clone(), curr_occurs.to_string(), max_occurs.to_string()]; - Self::new(ErrorKind::TooManyOccurrences) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - ( - ContextKind::MaxOccurrences, - ContextValue::Number(max_occurs as isize), - ), - ( - ContextKind::ActualNumValues, - ContextValue::Number(curr_occurs as isize), - ), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn too_many_values(cmd: &Command, val: String, arg: String, usage: String) -> Self { - let info = vec![arg.clone(), val.clone()]; - Self::new(ErrorKind::TooManyValues) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::InvalidValue, ContextValue::String(val)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn too_few_values( - cmd: &Command, - arg: String, - min_vals: usize, - curr_vals: usize, - usage: String, - ) -> Self { - let info = vec![arg.clone(), curr_vals.to_string(), min_vals.to_string()]; - Self::new(ErrorKind::TooFewValues) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - ( - ContextKind::MinValues, - ContextValue::Number(min_vals as isize), - ), - ( - ContextKind::ActualNumValues, - ContextValue::Number(curr_vals as isize), - ), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn value_validation( - arg: String, - val: String, - err: Box, - ) -> Self { - let info = vec![arg.clone(), val.to_string(), err.to_string()]; - Self::new(ErrorKind::ValueValidation) - .set_info(info) - .set_source(err) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::InvalidValue, ContextValue::String(val)), - ]) - } - - pub(crate) fn wrong_number_of_values( - cmd: &Command, - arg: String, - num_vals: usize, - curr_vals: usize, - usage: String, - ) -> Self { - let info = vec![arg.clone(), curr_vals.to_string(), num_vals.to_string()]; - Self::new(ErrorKind::WrongNumberOfValues) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - ( - ContextKind::ExpectedNumValues, - ContextValue::Number(num_vals as isize), - ), - ( - ContextKind::ActualNumValues, - ContextValue::Number(curr_vals as isize), - ), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn unexpected_multiple_usage(cmd: &Command, arg: String, usage: String) -> Self { - let info = vec![arg.clone()]; - Self::new(ErrorKind::UnexpectedMultipleUsage) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn unknown_argument( - cmd: &Command, - arg: String, - did_you_mean: Option<(String, Option)>, - usage: String, - ) -> Self { - let info = vec![arg.clone()]; - let mut err = Self::new(ErrorKind::UnknownArgument) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::Usage, ContextValue::String(usage)), - ]); - if let Some((flag, sub)) = did_you_mean { - err = err.insert_context_unchecked( - ContextKind::SuggestedArg, - ContextValue::String(format!("--{}", flag)), - ); - if let Some(sub) = sub { - err = err.insert_context_unchecked( - ContextKind::SuggestedSubcommand, - ContextValue::String(sub), - ); - } - } - err - } - - pub(crate) fn unnecessary_double_dash(cmd: &Command, arg: String, usage: String) -> Self { - let info = vec![arg.clone()]; - Self::new(ErrorKind::UnknownArgument) - .with_cmd(cmd) - .set_info(info) - .extend_context_unchecked([ - (ContextKind::InvalidArg, ContextValue::String(arg)), - (ContextKind::TrailingArg, ContextValue::Bool(true)), - (ContextKind::Usage, ContextValue::String(usage)), - ]) - } - - pub(crate) fn argument_not_found_auto(arg: String) -> Self { - let info = vec![arg.clone()]; - Self::new(ErrorKind::ArgumentNotFound) - .set_info(info) - .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]) - } - - fn formatted(&self) -> Cow<'_, Colorizer> { - if let Some(message) = self.inner.message.as_ref() { - message.formatted() - } else { - let mut c = Colorizer::new(self.stream(), self.inner.color_when); - - start_error(&mut c); - - if !self.write_dynamic_context(&mut c) { - if let Some(msg) = self.kind().as_str() { - c.none(msg.to_owned()); - } else if let Some(source) = self.inner.source.as_ref() { - c.none(source.to_string()); - } else { - c.none("Unknown cause"); - } - } - - let usage = self.get_context(ContextKind::Usage); - if let Some(ContextValue::String(usage)) = usage { - put_usage(&mut c, usage); - } - - try_help(&mut c, self.inner.help_flag); - - Cow::Owned(c) - } - } - - #[must_use] - fn write_dynamic_context(&self, c: &mut Colorizer) -> bool { - match self.kind() { - ErrorKind::ArgumentConflict => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let prior_arg = self.get_context(ContextKind::PriorArg); - if let (Some(ContextValue::String(invalid_arg)), Some(prior_arg)) = - (invalid_arg, prior_arg) - { - c.none("The argument '"); - c.warning(invalid_arg); - c.none("' cannot be used with"); - - match prior_arg { - ContextValue::Strings(values) => { - c.none(":"); - for v in values { - c.none("\n "); - c.warning(&**v); - } - } - ContextValue::String(value) => { - c.none(" '"); - c.warning(value); - c.none("'"); - } - _ => { - c.none(" one or more of the other specified arguments"); - } - } - true - } else { - false - } - } - ErrorKind::EmptyValue => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::String(invalid_arg)) = invalid_arg { - c.none("The argument '"); - c.warning(invalid_arg); - c.none("' requires a value but none was supplied"); - - let possible_values = self.get_context(ContextKind::ValidValue); - if let Some(ContextValue::Strings(possible_values)) = possible_values { - c.none("\n\t[possible values: "); - if let Some((last, elements)) = possible_values.split_last() { - for v in elements { - c.good(escape(v)); - c.none(", "); - } - c.good(escape(last)); - } - c.none("]"); - } - true - } else { - false - } - } - ErrorKind::NoEquals => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::String(invalid_arg)) = invalid_arg { - c.none("Equal sign is needed when assigning values to '"); - c.warning(invalid_arg); - c.none("'."); - true - } else { - false - } - } - ErrorKind::InvalidValue => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let invalid_value = self.get_context(ContextKind::InvalidValue); - if let ( - Some(ContextValue::String(invalid_arg)), - Some(ContextValue::String(invalid_value)), - ) = (invalid_arg, invalid_value) - { - c.none(quote(invalid_value)); - c.none(" isn't a valid value for '"); - c.warning(invalid_arg); - c.none("'"); - - let possible_values = self.get_context(ContextKind::ValidValue); - if let Some(ContextValue::Strings(possible_values)) = possible_values { - c.none("\n\t[possible values: "); - if let Some((last, elements)) = possible_values.split_last() { - for v in elements { - c.good(escape(v)); - c.none(", "); - } - c.good(escape(last)); - } - c.none("]"); - } - - let suggestion = self.get_context(ContextKind::SuggestedValue); - if let Some(ContextValue::String(suggestion)) = suggestion { - c.none("\n\n\tDid you mean "); - c.good(quote(suggestion)); - c.none("?"); - } - true - } else { - false - } - } - ErrorKind::InvalidSubcommand => { - let invalid_sub = self.get_context(ContextKind::InvalidSubcommand); - if let Some(ContextValue::String(invalid_sub)) = invalid_sub { - c.none("The subcommand '"); - c.warning(invalid_sub); - c.none("' wasn't recognized"); - - let valid_sub = self.get_context(ContextKind::SuggestedSubcommand); - if let Some(ContextValue::String(valid_sub)) = valid_sub { - c.none("\n\n\tDid you mean "); - c.good(valid_sub); - c.none("?"); - } - - let suggestion = self.get_context(ContextKind::SuggestedCommand); - if let Some(ContextValue::String(suggestion)) = suggestion { - c.none( - "\n\nIf you believe you received this message in error, try re-running with '", - ); - c.good(suggestion); - c.none("'"); - } - true - } else { - false - } - } - ErrorKind::UnrecognizedSubcommand => { - let invalid_sub = self.get_context(ContextKind::InvalidSubcommand); - if let Some(ContextValue::String(invalid_sub)) = invalid_sub { - c.none("The subcommand '"); - c.warning(invalid_sub); - c.none("' wasn't recognized"); - true - } else { - false - } - } - ErrorKind::MissingRequiredArgument => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::Strings(invalid_arg)) = invalid_arg { - c.none("The following required arguments were not provided:"); - for v in invalid_arg { - c.none("\n "); - c.good(&**v); - } - true - } else { - false - } - } - ErrorKind::MissingSubcommand => { - let invalid_sub = self.get_context(ContextKind::InvalidSubcommand); - if let Some(ContextValue::String(invalid_sub)) = invalid_sub { - c.none("'"); - c.warning(invalid_sub); - c.none("' requires a subcommand but one was not provided"); - true - } else { - false - } - } - ErrorKind::InvalidUtf8 => false, - ErrorKind::TooManyOccurrences => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let actual_num_occurs = self.get_context(ContextKind::ActualNumOccurrences); - let max_occurs = self.get_context(ContextKind::MaxOccurrences); - if let ( - Some(ContextValue::String(invalid_arg)), - Some(ContextValue::Number(actual_num_occurs)), - Some(ContextValue::Number(max_occurs)), - ) = (invalid_arg, actual_num_occurs, max_occurs) - { - let were_provided = Error::singular_or_plural(*actual_num_occurs as usize); - c.none("The argument '"); - c.warning(invalid_arg); - c.none("' allows at most "); - c.warning(max_occurs.to_string()); - c.none(" occurrences but "); - c.warning(actual_num_occurs.to_string()); - c.none(were_provided); - true - } else { - false - } - } - ErrorKind::TooManyValues => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let invalid_value = self.get_context(ContextKind::InvalidValue); - if let ( - Some(ContextValue::String(invalid_arg)), - Some(ContextValue::String(invalid_value)), - ) = (invalid_arg, invalid_value) - { - c.none("The value '"); - c.warning(invalid_value); - c.none("' was provided to '"); - c.warning(invalid_arg); - c.none("' but it wasn't expecting any more values"); - true - } else { - false - } - } - ErrorKind::TooFewValues => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let actual_num_values = self.get_context(ContextKind::ActualNumValues); - let min_values = self.get_context(ContextKind::MinValues); - if let ( - Some(ContextValue::String(invalid_arg)), - Some(ContextValue::Number(actual_num_values)), - Some(ContextValue::Number(min_values)), - ) = (invalid_arg, actual_num_values, min_values) - { - let were_provided = Error::singular_or_plural(*actual_num_values as usize); - c.none("The argument '"); - c.warning(invalid_arg); - c.none("' requires at least "); - c.warning(min_values.to_string()); - c.none(" values but only "); - c.warning(actual_num_values.to_string()); - c.none(were_provided); - true - } else { - false - } - } - ErrorKind::ValueValidation => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let invalid_value = self.get_context(ContextKind::InvalidValue); - if let ( - Some(ContextValue::String(invalid_arg)), - Some(ContextValue::String(invalid_value)), - ) = (invalid_arg, invalid_value) - { - c.none("Invalid value "); - c.warning(quote(invalid_value)); - c.none(" for '"); - c.warning(invalid_arg); - if let Some(source) = self.inner.source.as_deref() { - c.none("': "); - c.none(source.to_string()); - } else { - c.none("'"); - } - true - } else { - false - } - } - ErrorKind::WrongNumberOfValues => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - let actual_num_values = self.get_context(ContextKind::ActualNumValues); - let num_values = self.get_context(ContextKind::ExpectedNumValues); - if let ( - Some(ContextValue::String(invalid_arg)), - Some(ContextValue::Number(actual_num_values)), - Some(ContextValue::Number(num_values)), - ) = (invalid_arg, actual_num_values, num_values) - { - let were_provided = Error::singular_or_plural(*actual_num_values as usize); - c.none("The argument '"); - c.warning(invalid_arg); - c.none("' requires "); - c.warning(num_values.to_string()); - c.none(" values, but "); - c.warning(actual_num_values.to_string()); - c.none(were_provided); - true - } else { - false - } - } - ErrorKind::UnexpectedMultipleUsage => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::String(invalid_arg)) = invalid_arg { - c.none("The argument '"); - c.warning(invalid_arg.to_string()); - c.none("' was provided more than once, but cannot be used multiple times"); - true - } else { - false - } - } - ErrorKind::UnknownArgument => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::String(invalid_arg)) = invalid_arg { - c.none("Found argument '"); - c.warning(invalid_arg.to_string()); - c.none("' which wasn't expected, or isn't valid in this context"); - - let valid_sub = self.get_context(ContextKind::SuggestedSubcommand); - let valid_arg = self.get_context(ContextKind::SuggestedArg); - match (valid_sub, valid_arg) { - ( - Some(ContextValue::String(valid_sub)), - Some(ContextValue::String(valid_arg)), - ) => { - c.none("\n\n\tDid you mean "); - c.none("to put '"); - c.good(valid_arg); - c.none("' after the subcommand '"); - c.good(valid_sub); - c.none("'?"); - } - (None, Some(ContextValue::String(valid_arg))) => { - c.none("\n\n\tDid you mean '"); - c.good(valid_arg); - c.none("'?"); - } - (_, _) => {} - } - - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::String(invalid_arg)) = invalid_arg { - if invalid_arg.starts_with('-') { - c.none(format!( - "\n\n\tIf you tried to supply `{}` as a value rather than a flag, use `-- {}`", - invalid_arg, invalid_arg - )); - } - - let trailing_arg = self.get_context(ContextKind::TrailingArg); - if trailing_arg == Some(&ContextValue::Bool(true)) { - c.none(format!( - "\n\n\tIf you tried to supply `{}` as a subcommand, remove the '--' before it.", - invalid_arg - )); - } - } - true - } else { - false - } - } - ErrorKind::ArgumentNotFound => { - let invalid_arg = self.get_context(ContextKind::InvalidArg); - if let Some(ContextValue::String(invalid_arg)) = invalid_arg { - c.none("The argument '"); - c.warning(invalid_arg.to_string()); - c.none("' wasn't found"); - true - } else { - false - } - } - ErrorKind::DisplayHelp - | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand - | ErrorKind::DisplayVersion - | ErrorKind::Io - | ErrorKind::Format => false, - } - } - - /// Returns the singular or plural form on the verb to be based on the argument's value. - fn singular_or_plural(n: usize) -> &'static str { - if n > 1 { - " were provided" - } else { - " was provided" - } - } -} - -impl From for Error { - fn from(e: io::Error) -> Self { - Error::raw(ErrorKind::Io, e) - } -} - -impl From for Error { - fn from(e: fmt::Error) -> Self { - Error::raw(ErrorKind::Format, e) - } -} - -impl error::Error for Error { - #[allow(trivial_casts)] - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - self.inner.source.as_ref().map(|e| e.as_ref() as _) - } -} - -impl Display for Error { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - // Assuming `self.message` already has a trailing newline, from `try_help` or similar - write!(f, "{}", self.formatted())?; - if let Some(backtrace) = self.inner.backtrace.as_ref() { - writeln!(f)?; - writeln!(f, "Backtrace:")?; - writeln!(f, "{}", backtrace)?; - } - Ok(()) - } -} - -fn start_error(c: &mut Colorizer) { - c.error("error:"); - c.none(" "); -} - -fn put_usage(c: &mut Colorizer, usage: impl Into) { - c.none("\n\n"); - c.none(usage); -} - -fn get_help_flag(cmd: &Command) -> Option<&'static str> { - if !cmd.is_disable_help_flag_set() { - Some("--help") - } else if cmd.has_subcommands() && !cmd.is_disable_help_subcommand_set() { - Some("help") - } else { - None - } -} - -fn try_help(c: &mut Colorizer, help: Option<&str>) { - if let Some(help) = help { - c.none("\n\nFor more information try "); - c.good(help); - c.none("\n"); - } else { - c.none("\n"); - } -} - -fn quote(s: impl AsRef) -> String { - let s = s.as_ref(); - format!("{:?}", s) -} - -fn escape(s: impl AsRef) -> String { - let s = s.as_ref(); - if s.contains(char::is_whitespace) { - quote(s) - } else { - s.to_owned() - } -} - -#[derive(Clone, Debug)] -pub(crate) enum Message { - Raw(String), - Formatted(Colorizer), -} - -impl Message { - fn format(&mut self, cmd: &Command, usage: String) { - match self { - Message::Raw(s) => { - let mut c = Colorizer::new(Stream::Stderr, cmd.get_color()); - - let mut message = String::new(); - std::mem::swap(s, &mut message); - start_error(&mut c); - c.none(message); - put_usage(&mut c, usage); - try_help(&mut c, get_help_flag(cmd)); - *self = Self::Formatted(c); - } - Message::Formatted(_) => {} - } - } - - fn formatted(&self) -> Cow { - match self { - Message::Raw(s) => { - let mut c = Colorizer::new(Stream::Stderr, ColorChoice::Never); - start_error(&mut c); - c.none(s); - Cow::Owned(c) - } - Message::Formatted(c) => Cow::Borrowed(c), - } - } -} - -impl From for Message { - fn from(inner: String) -> Self { - Self::Raw(inner) - } -} - -impl From for Message { - fn from(inner: Colorizer) -> Self { - Self::Formatted(inner) - } -} - -#[cfg(feature = "debug")] -#[derive(Debug)] -struct Backtrace(backtrace::Backtrace); - -#[cfg(feature = "debug")] -impl Backtrace { - fn new() -> Option { - Some(Self(backtrace::Backtrace::new())) - } -} - -#[cfg(feature = "debug")] -impl Display for Backtrace { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - // `backtrace::Backtrace` uses `Debug` instead of `Display` - write!(f, "{:?}", self.0) - } -} - -#[cfg(not(feature = "debug"))] -#[derive(Debug)] -struct Backtrace; - -#[cfg(not(feature = "debug"))] -impl Backtrace { - fn new() -> Option { - None - } -} - -#[cfg(not(feature = "debug"))] -impl Display for Backtrace { - fn fmt(&self, _: &mut Formatter) -> fmt::Result { - Ok(()) - } -} - -#[test] -fn check_auto_traits() { - static_assertions::assert_impl_all!(Error: Send, Sync, Unpin); -} diff --git a/vendor/clap/src/lib.rs b/vendor/clap/src/lib.rs deleted file mode 100644 index 5cefe6ec1..000000000 --- a/vendor/clap/src/lib.rs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright ⓒ 2015-2016 Kevin B. Knapp and [`clap-rs` contributors](https://github.com/clap-rs/clap/graphs/contributors). -// Licensed under the MIT license -// (see LICENSE or ) All files in the project carrying such -// notice may not be copied, modified, or distributed except according to those terms. - -//! > **Command Line Argument Parser for Rust** -//! -//! Quick Links: -//! - Derive [tutorial][_derive::_tutorial] and [reference][_derive] -//! - Builder [tutorial][_tutorial] and [reference](index.html) -//! - [Cookbook][_cookbook] -//! - [FAQ][_faq] -//! - [Discussions](https://github.com/clap-rs/clap/discussions) -//! -//! ## Aspirations -//! -//! - Out of the box, users get a polished CLI experience -//! - Including common argument behavior, help generation, suggested fixes for users, colored output, [shell completions](https://github.com/clap-rs/clap/tree/master/clap_complete), etc -//! - Flexible enough to port your existing CLI interface -//! - However, we won't necessarily streamline support for each use case -//! - Reasonable parse performance -//! - Resilient maintainership, including -//! - Willing to break compatibility rather than batching up breaking changes in large releases -//! - Leverage feature flags to keep to one active branch -//! - Being under [WG-CLI](https://github.com/rust-cli/team/) to increase the bus factor -//! - We follow semver and will wait about 6-9 months between major breaking changes -//! - We will support the last two minor Rust releases (MSRV, currently 1.56.1) -//! -//! While these aspirations can be at odds with fast build times and low binary -//! size, we will still strive to keep these reasonable for the flexibility you -//! get. Check out the -//! [argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs) for -//! CLI parsers optimized for other use cases. -//! -//! ## Example -//! -//! Run -//! ```console -//! $ cargo add clap --features derive -//! ``` -//! *(See also [feature flag reference][_features])* -//! -//! Then define your CLI in `main.rs`: -#![cfg_attr(not(feature = "derive"), doc = " ```ignore")] -#![cfg_attr(feature = "derive", doc = " ```no_run")] -#![doc = include_str!("../examples/demo.rs")] -//! ``` -//! -//! And try it out: -#![doc = include_str!("../examples/demo.md")] -//! -//! See also the derive [tutorial][_derive::_tutorial] and [reference][_derive] -//! -//! ### Related Projects -//! -//! Augment clap: -//! - [wild](https://crates.io/crates/wild) for supporting wildcards (`*`) on Windows like you do Linux -//! - [argfile](https://crates.io/crates/argfile) for loading additional arguments from a file (aka response files) -//! - [shadow-rs](https://crates.io/crates/shadow-rs) for generating `Command::long_version` -//! - [clap_mangen](https://crates.io/crates/clap_mangen) for generating man page source (roff) -//! - [clap_complete](https://crates.io/crates/clap_complete) for shell completion support -//! -//! CLI Helpers -//! - [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag) -//! - [clap-cargo](https://crates.io/crates/clap-cargo) -//! - [concolor-clap](https://crates.io/crates/concolor-clap) -//! -//! Testing -//! - [`trycmd`](https://crates.io/crates/trycmd): Bulk snapshot testing -//! - [`snapbox`](https://crates.io/crates/snapbox): Specialized snapshot testing -//! - [`assert_cmd`](https://crates.io/crates/assert_cmd) and [`assert_fs`](https://crates.io/crates/assert_fs): Customized testing -//! -//! Documentation: -//! - [Command-line Apps for Rust](https://rust-cli.github.io/book/index.html) book -//! - -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")] -#![warn( - missing_docs, - missing_debug_implementations, - missing_copy_implementations, - trivial_casts, - unused_allocation, - trivial_numeric_casts, - clippy::single_char_pattern -)] -#![forbid(unsafe_code)] -// HACK https://github.com/rust-lang/rust-clippy/issues/7290 -#![allow(clippy::single_component_path_imports)] -#![allow(clippy::branches_sharing_code)] -// Doesn't allow for debug statements, etc to be unique -#![allow(clippy::if_same_then_else)] - -#[cfg(not(feature = "std"))] -compile_error!("`std` feature is currently required to build `clap`"); - -pub use crate::builder::ArgAction; -pub use crate::builder::Command; -pub use crate::builder::{Arg, ArgGroup}; -pub use crate::error::Error; -pub use crate::parser::ArgMatches; -#[cfg(feature = "color")] -pub use crate::util::color::ColorChoice; -#[cfg(not(feature = "color"))] -#[allow(unused_imports)] -pub(crate) use crate::util::color::ColorChoice; - -pub use crate::derive::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum}; - -#[allow(deprecated)] -pub use crate::builder::App; -pub use crate::builder::{AppFlags, AppSettings, ArgFlags, ArgSettings, PossibleValue, ValueHint}; -pub use crate::error::{ErrorKind, Result}; -#[allow(deprecated)] -pub use crate::parser::{Indices, OsValues, ValueSource, Values}; - -#[cfg(feature = "yaml")] -#[doc(hidden)] -#[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" - ) -)] -#[doc(hidden)] -pub use yaml_rust::YamlLoader; - -#[cfg(feature = "derive")] -#[doc(hidden)] -pub use clap_derive::{self, *}; - -/// Deprecated, replaced with [`CommandFactory`] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `CommandFactory`") -)] -pub use CommandFactory as IntoApp; -/// Deprecated, replaced with [`Parser`] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Parser`") -)] -#[doc(hidden)] -pub use Parser as StructOpt; -/// Deprecated, replaced with [`ValueEnum`] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ValueEnum`") -)] -pub use ValueEnum as ArgEnum; - -#[cfg(feature = "unstable-doc")] -pub mod _cookbook; -#[cfg(feature = "unstable-doc")] -pub mod _derive; -#[cfg(feature = "unstable-doc")] -pub mod _faq; -#[cfg(feature = "unstable-doc")] -pub mod _features; -#[cfg(feature = "unstable-doc")] -pub mod _tutorial; - -#[doc(hidden)] -pub mod __macro_refs { - #[cfg(any(feature = "derive", feature = "cargo"))] - #[doc(hidden)] - pub use once_cell; -} - -#[macro_use] -#[allow(missing_docs)] -mod macros; - -mod derive; - -#[cfg(feature = "regex")] -pub use crate::builder::RegexRef; - -pub mod builder; -pub mod error; -pub mod parser; - -mod mkeymap; -mod output; -mod util; - -const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \ - report at https://github.com/clap-rs/clap/issues"; -const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point"; - -/// Deprecated, replaced with [`Command::new`], unless you were looking for [Subcommand] -#[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `Command::new` unless you intended the `Subcommand` trait" - ) -)] -#[doc(hidden)] -#[derive(Debug, Copy, Clone)] -pub struct SubCommand {} - -#[allow(deprecated)] -impl SubCommand { - /// Deprecated, replaced with [`Command::new`]. - /// Did you mean Subcommand (lower-case c)? - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `Command::new`") - )] - #[doc(hidden)] - pub fn with_name<'help>(name: &str) -> App<'help> { - Command::new(name) - } - - /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? - #[cfg(feature = "yaml")] - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" - ) - )] - #[doc(hidden)] - pub fn from_yaml(yaml: &yaml_rust::Yaml) -> App { - #![allow(deprecated)] - Command::from_yaml(yaml) - } -} diff --git a/vendor/clap/src/macros.rs b/vendor/clap/src/macros.rs deleted file mode 100644 index 1f9167408..000000000 --- a/vendor/clap/src/macros.rs +++ /dev/null @@ -1,1058 +0,0 @@ -/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? -#[cfg(feature = "yaml")] -#[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" - ) -)] -#[doc(hidden)] -#[macro_export] -macro_rules! load_yaml { - ($yaml:expr) => { - &$crate::YamlLoader::load_from_str(include_str!($yaml)).expect("failed to load YAML file") - [0] - }; -} - -/// Deprecated, replaced with [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t] -#[macro_export] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`") -)] -#[doc(hidden)] -macro_rules! value_t { - ($m:ident, $v:expr, $t:ty) => { - $crate::value_t!($m.value_of($v), $t) - }; - ($m:ident.value_of($v:expr), $t:ty) => { - $m.value_of_t::<$t>($v) - }; -} - -/// Deprecated, replaced with [`ArgMatches::value_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit] -#[macro_export] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`") -)] -#[doc(hidden)] -macro_rules! value_t_or_exit { - ($m:ident, $v:expr, $t:ty) => { - value_t_or_exit!($m.value_of($v), $t) - }; - ($m:ident.value_of($v:expr), $t:ty) => { - $m.value_of_t_or_exit::<$t>($v) - }; -} - -/// Deprecated, replaced with [`ArgMatches::values_of_t`][crate::ArgMatches::value_of_t] -#[macro_export] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`") -)] -#[doc(hidden)] -macro_rules! values_t { - ($m:ident, $v:expr, $t:ty) => { - values_t!($m.values_of($v), $t) - }; - ($m:ident.values_of($v:expr), $t:ty) => { - $m.values_of_t::<$t>($v) - }; -} - -/// Deprecated, replaced with [`ArgMatches::values_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit] -#[macro_export] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`") -)] -#[doc(hidden)] -macro_rules! values_t_or_exit { - ($m:ident, $v:expr, $t:ty) => { - values_t_or_exit!($m.values_of($v), $t) - }; - ($m:ident.values_of($v:expr), $t:ty) => { - $m.values_of_t_or_exit::<$t>($v) - }; -} - -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`") -)] -#[doc(hidden)] -#[macro_export] -macro_rules! _clap_count_exprs { - () => { 0 }; - ($e:expr) => { 1 }; - ($e:expr, $($es:expr),+) => { 1 + $crate::_clap_count_exprs!($($es),*) }; -} - -/// Deprecated, replaced with [`ArgEnum`][crate::ArgEnum] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`") -)] -#[doc(hidden)] -#[macro_export] -macro_rules! arg_enum { - (@as_item $($i:item)*) => ($($i)*); - (@impls ( $($tts:tt)* ) -> ($e:ident, $($v:ident),+)) => { - $crate::arg_enum!(@as_item - $($tts)* - - impl ::std::str::FromStr for $e { - type Err = String; - - fn from_str(s: &str) -> ::std::result::Result { - #[allow(deprecated, unused_imports)] - use ::std::ascii::AsciiExt; - match s { - $(stringify!($v) | - _ if s.eq_ignore_ascii_case(stringify!($v)) => Ok($e::$v)),+, - _ => Err({ - let v = vec![ - $(stringify!($v),)+ - ]; - format!("valid values: {}", - v.join(", ")) - }), - } - } - } - impl ::std::fmt::Display for $e { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - $($e::$v => write!(f, stringify!($v)),)+ - } - } - } - impl $e { - #[allow(dead_code)] - pub fn variants() -> [&'static str; $crate::_clap_count_exprs!($(stringify!($v)),+)] { - [ - $(stringify!($v),)+ - ] - } - }); - }; - ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { - $crate::arg_enum!(@impls - ($(#[$($m),+])+ - pub enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { - $crate::arg_enum!(@impls - ($(#[$($m),+])+ - pub enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { - $crate::arg_enum!(@impls - ($(#[$($m),+])+ - enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { - $crate::arg_enum!(@impls - ($(#[$($m),+])+ - enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - (pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { - $crate::arg_enum!(@impls - (pub enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - (pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { - $crate::arg_enum!(@impls - (pub enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - (enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { - $crate::arg_enum!(@impls - (enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; - (enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { - $crate::arg_enum!(@impls - (enum $e { - $($v$(=$val)*),+ - }) -> ($e, $($v),+) - ); - }; -} - -/// Allows you to pull the version from your Cargo.toml at compile time as -/// `MAJOR.MINOR.PATCH_PKGVERSION_PRE` -/// -/// # Examples -/// -/// ```no_run -/// # #[macro_use] -/// # extern crate clap; -/// # use clap::Command; -/// # fn main() { -/// let m = Command::new("cmd") -/// .version(crate_version!()) -/// .get_matches(); -/// # } -/// ``` -#[cfg(feature = "cargo")] -#[macro_export] -macro_rules! crate_version { - () => { - env!("CARGO_PKG_VERSION") - }; -} - -/// Allows you to pull the authors for the command from your Cargo.toml at -/// compile time in the form: -/// `"author1 lastname :author2 lastname "` -/// -/// You can replace the colons with a custom separator by supplying a -/// replacement string, so, for example, -/// `crate_authors!(",\n")` would become -/// `"author1 lastname ,\nauthor2 lastname ,\nauthor3 lastname "` -/// -/// # Examples -/// -/// ```no_run -/// # #[macro_use] -/// # extern crate clap; -/// # use clap::Command; -/// # fn main() { -/// let m = Command::new("cmd") -/// .author(crate_authors!("\n")) -/// .get_matches(); -/// # } -/// ``` -#[cfg(feature = "cargo")] -#[macro_export] -macro_rules! crate_authors { - ($sep:expr) => {{ - static CACHED: clap::__macro_refs::once_cell::sync::Lazy = - clap::__macro_refs::once_cell::sync::Lazy::new(|| { - env!("CARGO_PKG_AUTHORS").replace(':', $sep) - }); - - let s: &'static str = &*CACHED; - s - }}; - () => { - env!("CARGO_PKG_AUTHORS") - }; -} - -/// Allows you to pull the description from your Cargo.toml at compile time. -/// -/// # Examples -/// -/// ```no_run -/// # #[macro_use] -/// # extern crate clap; -/// # use clap::Command; -/// # fn main() { -/// let m = Command::new("cmd") -/// .about(crate_description!()) -/// .get_matches(); -/// # } -/// ``` -#[cfg(feature = "cargo")] -#[macro_export] -macro_rules! crate_description { - () => { - env!("CARGO_PKG_DESCRIPTION") - }; -} - -/// Allows you to pull the name from your Cargo.toml at compile time. -/// -/// # Examples -/// -/// ```no_run -/// # #[macro_use] -/// # extern crate clap; -/// # use clap::Command; -/// # fn main() { -/// let m = Command::new(crate_name!()) -/// .get_matches(); -/// # } -/// ``` -#[cfg(feature = "cargo")] -#[macro_export] -macro_rules! crate_name { - () => { - env!("CARGO_PKG_NAME") - }; -} - -/// Allows you to build the `Command` instance from your Cargo.toml at compile time. -/// -/// **NOTE:** Changing the values in your `Cargo.toml` does not trigger a re-build automatically, -/// and therefore won't change the generated output until you recompile. -/// -/// In some cases you can "trick" the compiler into triggering a rebuild when your -/// `Cargo.toml` is changed by including this in your `src/main.rs` file -/// `include_str!("../Cargo.toml");` -/// -/// # Examples -/// -/// ```no_run -/// # #[macro_use] -/// # extern crate clap; -/// # fn main() { -/// let m = command!().get_matches(); -/// # } -/// ``` -#[cfg(feature = "cargo")] -#[macro_export] -macro_rules! command { - () => {{ - $crate::command!($crate::crate_name!()) - }}; - ($name:expr) => {{ - let mut cmd = $crate::Command::new($name).version($crate::crate_version!()); - - let author = $crate::crate_authors!(); - if !author.is_empty() { - cmd = cmd.author(author) - } - - let about = $crate::crate_description!(); - if !about.is_empty() { - cmd = cmd.about(about) - } - - cmd - }}; -} - -/// Requires `cargo` feature flag to be enabled. -#[cfg(not(feature = "cargo"))] -#[macro_export] -macro_rules! command { - () => {{ - compile_error!("`cargo` feature flag is required"); - }}; - ($name:expr) => {{ - compile_error!("`cargo` feature flag is required"); - }}; -} - -/// Deprecated, replaced with [`clap::command!`][crate::command] -#[cfg(feature = "cargo")] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.1.0", note = "Replaced with `clap::command!") -)] -#[macro_export] -macro_rules! app_from_crate { - () => {{ - let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!()); - - let author = $crate::crate_authors!(", "); - if !author.is_empty() { - cmd = cmd.author(author) - } - - let about = $crate::crate_description!(); - if !about.is_empty() { - cmd = cmd.about(about) - } - - cmd - }}; - ($sep:expr) => {{ - let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!()); - - let author = $crate::crate_authors!($sep); - if !author.is_empty() { - cmd = cmd.author(author) - } - - let about = $crate::crate_description!(); - if !about.is_empty() { - cmd = cmd.about(about) - } - - cmd - }}; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! arg_impl { - ( @string $val:ident ) => { - stringify!($val) - }; - ( @string $val:literal ) => {{ - let ident_or_string_literal: &str = $val; - ident_or_string_literal - }}; - ( @string $val:tt ) => { - ::std::compile_error!("Only identifiers or string literals supported"); - }; - ( @string ) => { - None - }; - - ( @char $val:ident ) => {{ - let ident_or_char_literal = stringify!($val); - debug_assert_eq!( - ident_or_char_literal.len(), - 1, - "Single-letter identifier expected, got {}", - ident_or_char_literal - ); - ident_or_char_literal.chars().next().unwrap() - }}; - ( @char $val:literal ) => {{ - let ident_or_char_literal: char = $val; - ident_or_char_literal - }}; - ( @char ) => {{ - None - }}; - - ( - @arg - ($arg:expr) - --$long:ident - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); - } - - let mut arg = $arg; - let long = $crate::arg_impl! { @string $long }; - if arg.get_id().is_empty() { - arg = arg.id(long); - } - arg.long(long) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - --$long:literal - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); - } - - let mut arg = $arg; - let long = $crate::arg_impl! { @string $long }; - if arg.get_id().is_empty() { - arg = arg.id(long); - } - arg.long(long) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - -$short:ident - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); - debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); - } - - $arg.short($crate::arg_impl! { @char $short }) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - -$short:literal - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); - debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); - } - - $arg.short($crate::arg_impl! { @char $short }) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - <$value_name:ident> - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); - } - debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); - - let mut arg = $arg; - - arg = arg.required(true); - arg = arg.takes_value(true); - - let value_name = $crate::arg_impl! { @string $value_name }; - if arg.get_id().is_empty() { - arg = arg.id(value_name); - } - arg.value_name(value_name) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - <$value_name:literal> - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); - } - debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); - - let mut arg = $arg; - - arg = arg.required(true); - arg = arg.takes_value(true); - - let value_name = $crate::arg_impl! { @string $value_name }; - if arg.get_id().is_empty() { - arg = arg.id(value_name); - } - arg.value_name(value_name) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - [$value_name:ident] - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); - } - debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); - - let mut arg = $arg; - - if arg.get_long().is_none() && arg.get_short().is_none() { - arg = arg.required(false); - } else { - arg = arg.min_values(0).max_values(1); - } - arg = arg.takes_value(true); - - let value_name = $crate::arg_impl! { @string $value_name }; - if arg.get_id().is_empty() { - arg = arg.id(value_name); - } - arg.value_name(value_name) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - [$value_name:literal] - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({ - #[allow(deprecated)] - { - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); - } - debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); - - let mut arg = $arg; - - if arg.get_long().is_none() && arg.get_short().is_none() { - arg = arg.required(false); - } else { - arg = arg.min_values(0).max_values(1); - } - arg = arg.takes_value(true); - - let value_name = $crate::arg_impl! { @string $value_name }; - if arg.get_id().is_empty() { - arg = arg.id(value_name); - } - arg.value_name(value_name) - }) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - ... - $($tail:tt)* - ) => { - $crate::arg_impl! { - @arg - ({#[allow(deprecated)]{ - $arg.multiple_occurrences(true) - }}) - $($tail)* - } - }; - ( - @arg - ($arg:expr) - $help:literal - ) => { - $arg.help($help) - }; - ( - @arg - ($arg:expr) - ) => { - $arg - }; -} - -/// Create an [`Arg`] from a usage string. -/// -/// Allows creation of basic settings for the [`Arg`]. -/// -/// **NOTE**: Not all settings may be set using the usage string method. Some properties are -/// only available via the builder pattern. -/// -/// # Syntax -/// -/// Usage strings typically following the form: -/// -/// ```notrust -/// [explicit name] [short] [long] [value names] [...] [help string] -/// ``` -/// -/// ### Explicit Name -/// -/// The name may be either a bare-word or a string, followed by a `:`, like `name:` or -/// `"name":`. -/// -/// *Note:* This is an optional field, if it's omitted the argument will use one of the additional -/// fields as the name using the following priority order: -/// -/// 1. Explicit Name -/// 2. Long -/// 3. Value Name -/// -/// See [`Arg::name`][crate::Arg::name]. -/// -/// ### Short -/// -/// A short flag is a `-` followed by either a bare-character or quoted character, like `-f` or -/// `-'f'`. -/// -/// See [`Arg::short`][crate::Arg::short]. -/// -/// ### Long -/// -/// A long flag is a `--` followed by either a bare-word or a string, like `--foo` or -/// `--"foo"`. -/// -/// See [`Arg::long`][crate::Arg::long]. -/// -/// ### Values (Value Notation) -/// -/// This is set by placing bare-word between: -/// - `[]` like `[FOO]` -/// - Positional argument: optional -/// - Named argument: optional value -/// - `<>` like ``: required -/// -/// See [`Arg::value_name`][crate::Arg::value_name]. -/// -/// ### `...` -/// -/// `...` (three consecutive dots/periods) specifies that this argument may occur multiple -/// times (not to be confused with multiple values per occurrence). -/// -/// See [`Arg::multiple_occurrences`][crate::Arg::multiple_occurrences]. -/// -/// ### Help String -/// -/// The help string is denoted between a pair of double quotes `""` and may contain any -/// characters. -/// -/// # Examples -/// -/// ```rust -/// # use clap::{Command, Arg, arg}; -/// Command::new("prog") -/// .args(&[ -/// arg!(--config "a required file for the configuration and no short"), -/// arg!(-d --debug ... "turns on debugging information and allows multiples"), -/// arg!([input] "an optional input file to use") -/// ]) -/// # ; -/// ``` -/// [`Arg`]: ./struct.Arg.html -#[macro_export] -macro_rules! arg { - ( $name:ident: $($tail:tt)+ ) => { - $crate::arg_impl! { - @arg ($crate::Arg::new($crate::arg_impl! { @string $name })) $($tail)+ - } - }; - ( $($tail:tt)+ ) => {{ - let arg = $crate::arg_impl! { - @arg ($crate::Arg::default()) $($tail)+ - }; - debug_assert!(!arg.get_id().is_empty(), "Without a value or long flag, the `name:` prefix is required"); - arg - }}; -} - -/// Deprecated, replaced with [`clap::Parser`][crate::Parser] and [`clap::arg!`][crate::arg] (Issue clap-rs/clap#2835) -#[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.0.0", - note = "Replaced with `clap::Parser` for a declarative API (Issue clap-rs/clap#2835)" - ) -)] -#[doc(hidden)] -#[macro_export] -macro_rules! clap_app { - (@app ($builder:expr)) => { $builder }; - (@app ($builder:expr) (@arg ($name:expr): $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($builder.arg( - $crate::clap_app!{ @arg ($crate::Arg::new($name)) (-) $($tail)* })) - $($tt)* - } - }; - (@app ($builder:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($builder.arg( - $crate::clap_app!{ @arg ($crate::Arg::new(stringify!($name))) (-) $($tail)* })) - $($tt)* - } - }; - (@app ($builder:expr) (@setting $setting:ident) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($builder.setting($crate::AppSettings::$setting)) - $($tt)* - } - }; -// Treat the application builder as an argument to set its attributes - (@app ($builder:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app ($crate::clap_app!{ @arg ($builder) $($attr)* }) $($tt)* } - }; - (@app ($builder:expr) (@group $name:ident => $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name))) $($tail)* }) - $($tt)* - } - }; - (@app ($builder:expr) (@group $name:ident !$ident:ident => $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(false)) $($tail)* }) - $($tt)* - } - }; - (@app ($builder:expr) (@group $name:ident +$ident:ident => $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(true)) $($tail)* }) - $($tt)* - } - }; -// Handle subcommand creation - (@app ($builder:expr) (@subcommand $name:ident => $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @app - ($builder.subcommand( - $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* } - )) - $($tt)* - } - }; -// Yaml like function calls - used for setting various meta directly against the app - (@app ($builder:expr) ($ident:ident: $($v:expr),*) $($tt:tt)*) => { -// $crate::clap_app!{ @app ($builder.$ident($($v),*)) $($tt)* } - $crate::clap_app!{ @app - ($builder.$ident($($v),*)) - $($tt)* - } - }; - -// Add members to group and continue argument handling with the parent builder - (@group ($builder:expr, $group:expr)) => { $builder.group($group) }; - // Treat the group builder as an argument to set its attributes - (@group ($builder:expr, $group:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @group ($builder, $crate::clap_app!{ @arg ($group) (-) $($attr)* }) $($tt)* } - }; - (@group ($builder:expr, $group:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => { - $crate::clap_app!{ @group - ($crate::clap_app!{ @app ($builder) (@arg $name: $($tail)*) }, - $group.arg(stringify!($name))) - $($tt)* - } - }; - -// No more tokens to munch - (@arg ($arg:expr) $modes:tt) => { $arg }; -// Shorthand tokens influenced by the usage_string - (@arg ($arg:expr) $modes:tt --($long:expr) $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.long($long)) $modes $($tail)* } - }; - (@arg ($arg:expr) $modes:tt --$long:ident $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.long(stringify!($long))) $modes $($tail)* } - }; - (@arg ($arg:expr) $modes:tt -$short:ident $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.short(stringify!($short).chars().next().unwrap())) $modes $($tail)* } - }; - (@arg ($arg:expr) (-) <$var:ident> $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value +required $($tail)* } - }; - (@arg ($arg:expr) (+) <$var:ident> $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* } - }; - (@arg ($arg:expr) (-) [$var:ident] $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value $($tail)* } - }; - (@arg ($arg:expr) (+) [$var:ident] $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* } - }; - (@arg ($arg:expr) $modes:tt ... $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg) $modes +multiple +takes_value $($tail)* } - }; -// Shorthand magic - (@arg ($arg:expr) $modes:tt #{$n:expr, $m:expr} $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg) $modes min_values($n) max_values($m) $($tail)* } - }; - (@arg ($arg:expr) $modes:tt * $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg) $modes +required $($tail)* } - }; -// !foo -> .foo(false) - (@arg ($arg:expr) $modes:tt !$ident:ident $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.$ident(false)) $modes $($tail)* } - }; -// +foo -> .foo(true) - (@arg ($arg:expr) $modes:tt +$ident:ident $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.$ident(true)) $modes $($tail)* } - }; -// Validator - (@arg ($arg:expr) $modes:tt {$fn_:expr} $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.validator($fn_)) $modes $($tail)* } - }; - (@as_expr $expr:expr) => { $expr }; -// Help - (@arg ($arg:expr) $modes:tt $desc:tt) => { $arg.help($crate::clap_app!{ @as_expr $desc }) }; -// Handle functions that need to be called multiple times for each argument - (@arg ($arg:expr) $modes:tt $ident:ident[$($target:ident)*] $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg $( .$ident(stringify!($target)) )*) $modes $($tail)* } - }; -// Inherit builder's functions, e.g. `index(2)`, `requires_if("val", "arg")` - (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr),*) $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } - }; -// Inherit builder's functions with trailing comma, e.g. `index(2,)`, `requires_if("val", "arg",)` - (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr,)*) $($tail:tt)*) => { - $crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } - }; - -// Build a subcommand outside of an app. - (@subcommand $name:ident => $($tail:tt)*) => { - $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* } - }; -// Start the magic - (($name:expr) => $($tail:tt)*) => {{ - $crate::clap_app!{ @app ($crate::Command::new($name)) $($tail)*} - }}; - - ($name:ident => $($tail:tt)*) => {{ - $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)*} - }}; -} - -macro_rules! impl_settings { - ($settings:ident, $flags:ident, - $( - $(#[$inner:ident $($args:tt)*])* - $setting:ident => $flag:path - ),+ - ) => { - impl $flags { - #[allow(dead_code)] - pub(crate) fn empty() -> Self { - $flags(Flags::empty()) - } - - #[allow(dead_code)] - pub(crate) fn insert(&mut self, rhs: Self) { - self.0.insert(rhs.0); - } - - #[allow(dead_code)] - pub(crate) fn remove(&mut self, rhs: Self) { - self.0.remove(rhs.0); - } - - #[allow(dead_code)] - pub(crate) fn set(&mut self, s: $settings) { - #[allow(deprecated)] // some Settings might be deprecated - match s { - $( - $(#[$inner $($args)*])* - $settings::$setting => self.0.insert($flag), - )* - } - } - - #[allow(dead_code)] - pub(crate) fn unset(&mut self, s: $settings) { - #[allow(deprecated)] // some Settings might be deprecated - match s { - $( - $(#[$inner $($args)*])* - $settings::$setting => self.0.remove($flag), - )* - } - } - - #[allow(dead_code)] - pub(crate) fn is_set(&self, s: $settings) -> bool { - #[allow(deprecated)] // some Settings might be deprecated - match s { - $( - $(#[$inner $($args)*])* - $settings::$setting => self.0.contains($flag), - )* - } - } - } - - impl BitOr for $flags { - type Output = Self; - - fn bitor(mut self, rhs: Self) -> Self::Output { - self.0.insert(rhs.0); - self - } - } - - impl From<$settings> for $flags { - fn from(setting: $settings) -> Self { - let mut flags = $flags::empty(); - flags.set(setting); - flags - } - } - - impl BitOr<$settings> for $flags { - type Output = Self; - - fn bitor(mut self, rhs: $settings) -> Self::Output { - self.set(rhs); - self - } - } - - impl BitOr for $settings { - type Output = $flags; - - fn bitor(self, rhs: Self) -> Self::Output { - let mut flags = $flags::empty(); - flags.set(self); - flags.set(rhs); - flags - } - } - } -} - -// Convenience for writing to stderr thanks to https://github.com/BurntSushi -macro_rules! wlnerr { - ($($arg:tt)*) => ({ - use std::io::{Write, stderr}; - writeln!(&mut stderr(), $($arg)*).ok(); - }) -} - -#[cfg(feature = "debug")] -macro_rules! debug { - ($($arg:tt)*) => ({ - let prefix = format!("[{:>w$}] \t", module_path!(), w = 28); - let body = format!($($arg)*); - let mut color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto); - color.hint(prefix); - color.hint(body); - color.none("\n"); - let _ = color.print(); - }) -} - -#[cfg(not(feature = "debug"))] -macro_rules! debug { - ($($arg:tt)*) => {}; -} diff --git a/vendor/clap/src/mkeymap.rs b/vendor/clap/src/mkeymap.rs deleted file mode 100644 index 97ecdda77..000000000 --- a/vendor/clap/src/mkeymap.rs +++ /dev/null @@ -1,193 +0,0 @@ -use std::iter::Iterator; -use std::ops::Index; -use std::{ffi::OsStr, ffi::OsString}; - -use crate::util::Id; -use crate::Arg; -use crate::INTERNAL_ERROR_MSG; - -#[derive(PartialEq, Eq, Debug, Clone)] -pub(crate) struct Key { - key: KeyType, - index: usize, -} - -#[derive(Default, PartialEq, Eq, Debug, Clone)] -pub(crate) struct MKeyMap<'help> { - /// All of the arguments. - args: Vec>, - - // Cache part: - /// Will be set after `_build()`. - keys: Vec, -} - -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -pub(crate) enum KeyType { - Short(char), - Long(OsString), - Position(usize), -} - -impl KeyType { - pub(crate) fn is_position(&self) -> bool { - matches!(self, KeyType::Position(_)) - } -} - -impl PartialEq for KeyType { - fn eq(&self, rhs: &usize) -> bool { - match self { - KeyType::Position(x) => x == rhs, - _ => false, - } - } -} - -impl PartialEq<&str> for KeyType { - fn eq(&self, rhs: &&str) -> bool { - match self { - KeyType::Long(l) => l == rhs, - _ => false, - } - } -} - -impl PartialEq for KeyType { - fn eq(&self, rhs: &str) -> bool { - match self { - KeyType::Long(l) => l == rhs, - _ => false, - } - } -} - -impl PartialEq for KeyType { - fn eq(&self, rhs: &OsStr) -> bool { - match self { - KeyType::Long(l) => l == rhs, - _ => false, - } - } -} - -impl PartialEq for KeyType { - fn eq(&self, rhs: &char) -> bool { - match self { - KeyType::Short(c) => c == rhs, - _ => false, - } - } -} - -impl<'help> MKeyMap<'help> { - /// If any arg has corresponding key in this map, we can search the key with - /// u64(for positional argument), char(for short flag), &str and OsString - /// (for long flag) - pub(crate) fn contains(&self, key: K) -> bool - where - KeyType: PartialEq, - { - self.keys.iter().any(|x| x.key == key) - } - - /// Reserves capacity for at least additional more elements to be inserted - pub(crate) fn reserve(&mut self, additional: usize) { - self.args.reserve(additional); - } - - /// Push an argument in the map. - pub(crate) fn push(&mut self, new_arg: Arg<'help>) { - self.args.push(new_arg); - } - - /// Find the arg have corresponding key in this map, we can search the key - /// with u64(for positional argument), char(for short flag), &str and - /// OsString (for long flag) - pub(crate) fn get(&self, key: &K) -> Option<&Arg<'help>> - where - KeyType: PartialEq, - { - self.keys - .iter() - .find(|k| &k.key == key) - .map(|k| &self.args[k.index]) - } - - /// Find out if the map have no arg. - pub(crate) fn is_empty(&self) -> bool { - self.args.is_empty() - } - - /// Return iterators of all keys. - pub(crate) fn keys(&self) -> impl Iterator { - self.keys.iter().map(|x| &x.key) - } - - /// Return iterators of all args. - pub(crate) fn args(&self) -> impl Iterator> { - self.args.iter() - } - - /// Return mutable iterators of all args. - pub(crate) fn args_mut<'map>(&'map mut self) -> impl Iterator> { - self.args.iter_mut() - } - - /// We need a lazy build here since some we may change args after creating - /// the map, you can checkout who uses `args_mut`. - pub(crate) fn _build(&mut self) { - for (i, arg) in self.args.iter().enumerate() { - append_keys(&mut self.keys, arg, i); - } - } - - /// Remove an arg in the graph by Id, usually used by `mut_arg`. Return - /// `Some(arg)` if removed. - pub(crate) fn remove_by_name(&mut self, name: &Id) -> Option> { - self.args - .iter() - .position(|arg| &arg.id == name) - // since it's a cold function, using this wouldn't hurt much - .map(|i| self.args.remove(i)) - } - - /// Remove an arg based on index - pub(crate) fn remove(&mut self, index: usize) -> Arg<'help> { - self.args.remove(index) - } -} - -impl<'help> Index<&'_ KeyType> for MKeyMap<'help> { - type Output = Arg<'help>; - - fn index(&self, key: &KeyType) -> &Self::Output { - self.get(key).expect(INTERNAL_ERROR_MSG) - } -} - -/// Generate key types for an specific Arg. -fn append_keys(keys: &mut Vec, arg: &Arg, index: usize) { - if let Some(pos_index) = arg.index { - let key = KeyType::Position(pos_index); - keys.push(Key { key, index }); - } else { - if let Some(short) = arg.short { - let key = KeyType::Short(short); - keys.push(Key { key, index }); - } - if let Some(long) = arg.long { - let key = KeyType::Long(OsString::from(long)); - keys.push(Key { key, index }); - } - - for (short, _) in arg.short_aliases.iter() { - let key = KeyType::Short(*short); - keys.push(Key { key, index }); - } - for (long, _) in arg.aliases.iter() { - let key = KeyType::Long(OsString::from(long)); - keys.push(Key { key, index }); - } - } -} diff --git a/vendor/clap/src/output/fmt.rs b/vendor/clap/src/output/fmt.rs deleted file mode 100644 index dc1f46e08..000000000 --- a/vendor/clap/src/output/fmt.rs +++ /dev/null @@ -1,158 +0,0 @@ -use crate::util::color::ColorChoice; - -use std::{ - fmt::{self, Display, Formatter}, - io::{self, Write}, -}; - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub(crate) enum Stream { - Stdout, - Stderr, -} - -#[derive(Clone, Debug)] -pub(crate) struct Colorizer { - stream: Stream, - #[allow(unused)] - color_when: ColorChoice, - pieces: Vec<(String, Style)>, -} - -impl Colorizer { - #[inline(never)] - pub(crate) fn new(stream: Stream, color_when: ColorChoice) -> Self { - Colorizer { - stream, - color_when, - pieces: vec![], - } - } - - #[inline(never)] - pub(crate) fn good(&mut self, msg: impl Into) { - self.pieces.push((msg.into(), Style::Good)); - } - - #[inline(never)] - pub(crate) fn warning(&mut self, msg: impl Into) { - self.pieces.push((msg.into(), Style::Warning)); - } - - #[inline(never)] - pub(crate) fn error(&mut self, msg: impl Into) { - self.pieces.push((msg.into(), Style::Error)); - } - - #[inline(never)] - #[allow(dead_code)] - pub(crate) fn hint(&mut self, msg: impl Into) { - self.pieces.push((msg.into(), Style::Hint)); - } - - #[inline(never)] - pub(crate) fn none(&mut self, msg: impl Into) { - self.pieces.push((msg.into(), Style::Default)); - } -} - -/// Printing methods. -impl Colorizer { - #[cfg(feature = "color")] - pub(crate) fn print(&self) -> io::Result<()> { - use termcolor::{BufferWriter, ColorChoice as DepColorChoice, ColorSpec, WriteColor}; - - let color_when = match self.color_when { - ColorChoice::Always => DepColorChoice::Always, - ColorChoice::Auto if is_a_tty(self.stream) => DepColorChoice::Auto, - _ => DepColorChoice::Never, - }; - - let writer = match self.stream { - Stream::Stderr => BufferWriter::stderr(color_when), - Stream::Stdout => BufferWriter::stdout(color_when), - }; - - let mut buffer = writer.buffer(); - - for piece in &self.pieces { - let mut color = ColorSpec::new(); - match piece.1 { - Style::Good => { - color.set_fg(Some(termcolor::Color::Green)); - } - Style::Warning => { - color.set_fg(Some(termcolor::Color::Yellow)); - } - Style::Error => { - color.set_fg(Some(termcolor::Color::Red)); - color.set_bold(true); - } - Style::Hint => { - color.set_dimmed(true); - } - Style::Default => {} - } - - buffer.set_color(&color)?; - buffer.write_all(piece.0.as_bytes())?; - buffer.reset()?; - } - - writer.print(&buffer) - } - - #[cfg(not(feature = "color"))] - pub(crate) fn print(&self) -> io::Result<()> { - // [e]println can't be used here because it panics - // if something went wrong. We don't want that. - match self.stream { - Stream::Stdout => { - let stdout = std::io::stdout(); - let mut stdout = stdout.lock(); - write!(stdout, "{}", self) - } - Stream::Stderr => { - let stderr = std::io::stderr(); - let mut stderr = stderr.lock(); - write!(stderr, "{}", self) - } - } - } -} - -/// Color-unaware printing. Never uses coloring. -impl Display for Colorizer { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - for piece in &self.pieces { - Display::fmt(&piece.0, f)?; - } - - Ok(()) - } -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Style { - Good, - Warning, - Error, - Hint, - Default, -} - -impl Default for Style { - fn default() -> Self { - Self::Default - } -} - -#[cfg(feature = "color")] -fn is_a_tty(stream: Stream) -> bool { - let stream = match stream { - Stream::Stdout => atty::Stream::Stdout, - Stream::Stderr => atty::Stream::Stderr, - }; - - atty::is(stream) -} diff --git a/vendor/clap/src/output/help.rs b/vendor/clap/src/output/help.rs deleted file mode 100644 index eb53bfa54..000000000 --- a/vendor/clap/src/output/help.rs +++ /dev/null @@ -1,1176 +0,0 @@ -// Std -use std::borrow::Cow; -use std::cmp; -use std::fmt::Write as _; -use std::io::{self, Write}; -use std::usize; - -// Internal -use crate::builder::{display_arg_val, Arg, Command}; -use crate::output::{fmt::Colorizer, Usage}; -use crate::PossibleValue; - -// Third party -use indexmap::IndexSet; -use textwrap::core::display_width; - -/// `clap` Help Writer. -/// -/// Wraps a writer stream providing different methods to generate help for `clap` objects. -pub(crate) struct Help<'help, 'cmd, 'writer> { - writer: HelpWriter<'writer>, - cmd: &'cmd Command<'help>, - usage: &'cmd Usage<'help, 'cmd>, - next_line_help: bool, - term_w: usize, - use_long: bool, -} - -// Public Functions -impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { - #[cfg(feature = "unstable-v4")] - const DEFAULT_TEMPLATE: &'static str = "\ - {before-help}{name} {version}\n\ - {author-with-newline}{about-with-newline}\n\ - {usage-heading}\n {usage}\n\ - \n\ - {all-args}{after-help}\ - "; - #[cfg(not(feature = "unstable-v4"))] - const DEFAULT_TEMPLATE: &'static str = "\ - {before-help}{bin} {version}\n\ - {author-with-newline}{about-with-newline}\n\ - {usage-heading}\n {usage}\n\ - \n\ - {all-args}{after-help}\ - "; - - #[cfg(feature = "unstable-v4")] - const DEFAULT_NO_ARGS_TEMPLATE: &'static str = "\ - {before-help}{name} {version}\n\ - {author-with-newline}{about-with-newline}\n\ - {usage-heading}\n {usage}{after-help}\ - "; - #[cfg(not(feature = "unstable-v4"))] - const DEFAULT_NO_ARGS_TEMPLATE: &'static str = "\ - {before-help}{bin} {version}\n\ - {author-with-newline}{about-with-newline}\n\ - {usage-heading}\n {usage}{after-help}\ - "; - - /// Create a new `Help` instance. - pub(crate) fn new( - writer: HelpWriter<'writer>, - cmd: &'cmd Command<'help>, - usage: &'cmd Usage<'help, 'cmd>, - use_long: bool, - ) -> Self { - debug!("Help::new cmd={}, use_long={}", cmd.get_name(), use_long); - let term_w = match cmd.get_term_width() { - Some(0) => usize::MAX, - Some(w) => w, - None => cmp::min( - dimensions().map_or(100, |(w, _)| w), - match cmd.get_max_term_width() { - None | Some(0) => usize::MAX, - Some(mw) => mw, - }, - ), - }; - let next_line_help = cmd.is_next_line_help_set(); - - Help { - writer, - cmd, - usage, - next_line_help, - term_w, - use_long, - } - } - - /// Writes the parser help to the wrapped stream. - pub(crate) fn write_help(&mut self) -> io::Result<()> { - debug!("Help::write_help"); - - if let Some(h) = self.cmd.get_override_help() { - self.none(h)?; - } else if let Some(tmpl) = self.cmd.get_help_template() { - self.write_templated_help(tmpl)?; - } else { - let pos = self - .cmd - .get_positionals() - .any(|arg| should_show_arg(self.use_long, arg)); - let non_pos = self - .cmd - .get_non_positionals() - .any(|arg| should_show_arg(self.use_long, arg)); - let subcmds = self.cmd.has_visible_subcommands(); - - if non_pos || pos || subcmds { - self.write_templated_help(Self::DEFAULT_TEMPLATE)?; - } else { - self.write_templated_help(Self::DEFAULT_NO_ARGS_TEMPLATE)?; - } - } - - self.none("\n")?; - - Ok(()) - } -} - -macro_rules! write_method { - ($_self:ident, $msg:ident, $meth:ident) => { - match &mut $_self.writer { - HelpWriter::Buffer(c) => { - c.$meth(($msg).into()); - Ok(()) - } - HelpWriter::Normal(w) => w.write_all($msg.as_ref()), - } - }; -} - -// Methods to write Arg help. -impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { - #[inline(never)] - fn good + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { - write_method!(self, msg, good) - } - - #[inline(never)] - fn warning + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { - write_method!(self, msg, warning) - } - - #[inline(never)] - fn none + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { - write_method!(self, msg, none) - } - - #[inline(never)] - fn spaces(&mut self, n: usize) -> io::Result<()> { - // A string with 64 consecutive spaces. - const SHORT_SPACE: &str = - " "; - if let Some(short) = SHORT_SPACE.get(..n) { - self.none(short) - } else { - self.none(" ".repeat(n)) - } - } - - /// Writes help for each argument in the order they were declared to the wrapped stream. - fn write_args_unsorted(&mut self, args: &[&Arg<'help>]) -> io::Result<()> { - debug!("Help::write_args_unsorted"); - // The shortest an arg can legally be is 2 (i.e. '-x') - let mut longest = 2; - let mut arg_v = Vec::with_capacity(10); - - for &arg in args - .iter() - .filter(|arg| should_show_arg(self.use_long, *arg)) - { - if arg.longest_filter() { - longest = longest.max(display_width(&arg.to_string())); - debug!( - "Help::write_args_unsorted: arg={:?} longest={}", - arg.get_id(), - longest - ); - } - arg_v.push(arg) - } - - let next_line_help = self.will_args_wrap(args, longest); - - let argc = arg_v.len(); - for (i, arg) in arg_v.iter().enumerate() { - self.write_arg(arg, i + 1 == argc, next_line_help, longest)?; - } - Ok(()) - } - - /// Sorts arguments by length and display order and write their help to the wrapped stream. - fn write_args(&mut self, args: &[&Arg<'help>], _category: &str) -> io::Result<()> { - debug!("Help::write_args {}", _category); - // The shortest an arg can legally be is 2 (i.e. '-x') - let mut longest = 2; - let mut ord_v = Vec::new(); - - // Determine the longest - for &arg in args.iter().filter(|arg| { - // If it's NextLineHelp we don't care to compute how long it is because it may be - // NextLineHelp on purpose simply *because* it's so long and would throw off all other - // args alignment - should_show_arg(self.use_long, *arg) - }) { - if arg.longest_filter() { - longest = longest.max(display_width(&arg.to_string())); - debug!( - "Help::write_args: arg={:?} longest={}", - arg.get_id(), - longest - ); - } - - // Formatting key like this to ensure that: - // 1. Argument has long flags are printed just after short flags. - // 2. For two args both have short flags like `-c` and `-C`, the - // `-C` arg is printed just after the `-c` arg - // 3. For args without short or long flag, print them at last(sorted - // by arg name). - // Example order: -a, -b, -B, -s, --select-file, --select-folder, -x - - let key = if let Some(x) = arg.short { - let mut s = x.to_ascii_lowercase().to_string(); - s.push(if x.is_ascii_lowercase() { '0' } else { '1' }); - s - } else if let Some(x) = arg.long { - x.to_string() - } else { - let mut s = '{'.to_string(); - s.push_str(arg.name); - s - }; - ord_v.push((arg.get_display_order(), key, arg)); - } - ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1))); - - let next_line_help = self.will_args_wrap(args, longest); - - for (i, (_, _, arg)) in ord_v.iter().enumerate() { - let last_arg = i + 1 == ord_v.len(); - self.write_arg(arg, last_arg, next_line_help, longest)?; - } - Ok(()) - } - - /// Writes help for an argument to the wrapped stream. - fn write_arg( - &mut self, - arg: &Arg<'help>, - last_arg: bool, - next_line_help: bool, - longest: usize, - ) -> io::Result<()> { - let spec_vals = &self.spec_vals(arg); - - self.short(arg)?; - self.long(arg)?; - self.val(arg)?; - self.align_to_about(arg, next_line_help, longest)?; - - let about = if self.use_long { - arg.long_help.or(arg.help).unwrap_or("") - } else { - arg.help.or(arg.long_help).unwrap_or("") - }; - - self.help(Some(arg), about, spec_vals, next_line_help, longest)?; - - if !last_arg { - self.none("\n")?; - if next_line_help { - self.none("\n")?; - } - } - Ok(()) - } - - /// Writes argument's short command to the wrapped stream. - fn short(&mut self, arg: &Arg<'help>) -> io::Result<()> { - debug!("Help::short"); - - self.none(TAB)?; - - if let Some(s) = arg.short { - self.good(format!("-{}", s)) - } else if !arg.is_positional() { - self.none(TAB) - } else { - Ok(()) - } - } - - /// Writes argument's long command to the wrapped stream. - fn long(&mut self, arg: &Arg<'help>) -> io::Result<()> { - debug!("Help::long"); - if let Some(long) = arg.long { - if arg.short.is_some() { - self.none(", ")?; - } - self.good(format!("--{}", long))?; - } - Ok(()) - } - - /// Writes argument's possible values to the wrapped stream. - fn val(&mut self, arg: &Arg<'help>) -> io::Result<()> { - debug!("Help::val: arg={}", arg.name); - let mut need_closing_bracket = false; - if arg.is_takes_value_set() && !arg.is_positional() { - let is_optional_val = arg.min_vals == Some(0); - let sep = if arg.is_require_equals_set() { - if is_optional_val { - need_closing_bracket = true; - "[=" - } else { - "=" - } - } else if is_optional_val { - need_closing_bracket = true; - " [" - } else { - " " - }; - self.none(sep)?; - } - - if arg.is_takes_value_set() || arg.is_positional() { - display_arg_val( - arg, - |s, good| if good { self.good(s) } else { self.none(s) }, - )?; - } - - if need_closing_bracket { - self.none("]")?; - } - Ok(()) - } - - /// Write alignment padding between arg's switches/values and its about message. - fn align_to_about( - &mut self, - arg: &Arg<'help>, - next_line_help: bool, - longest: usize, - ) -> io::Result<()> { - debug!( - "Help::align_to_about: arg={}, next_line_help={}, longest={}", - arg.name, next_line_help, longest - ); - if self.use_long || next_line_help { - // long help prints messages on the next line so it doesn't need to align text - debug!("Help::align_to_about: printing long help so skip alignment"); - } else if !arg.is_positional() { - let self_len = display_width(&arg.to_string()); - // Since we're writing spaces from the tab point we first need to know if we - // had a long and short, or just short - let padding = if arg.long.is_some() { - // Only account 4 after the val - 4 - } else { - // Only account for ', --' + 4 after the val - 8 - }; - let spcs = longest + padding - self_len; - debug!( - "Help::align_to_about: positional=false arg_len={}, spaces={}", - self_len, spcs - ); - - self.spaces(spcs)?; - } else { - let self_len = display_width(&arg.to_string()); - let padding = 4; - let spcs = longest + padding - self_len; - debug!( - "Help::align_to_about: positional=true arg_len={}, spaces={}", - self_len, spcs - ); - - self.spaces(spcs)?; - } - Ok(()) - } - - fn write_before_help(&mut self) -> io::Result<()> { - debug!("Help::write_before_help"); - let before_help = if self.use_long { - self.cmd - .get_before_long_help() - .or_else(|| self.cmd.get_before_help()) - } else { - self.cmd.get_before_help() - }; - if let Some(output) = before_help { - self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w))?; - self.none("\n\n")?; - } - Ok(()) - } - - fn write_after_help(&mut self) -> io::Result<()> { - debug!("Help::write_after_help"); - let after_help = if self.use_long { - self.cmd - .get_after_long_help() - .or_else(|| self.cmd.get_after_help()) - } else { - self.cmd.get_after_help() - }; - if let Some(output) = after_help { - self.none("\n\n")?; - self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w))?; - } - Ok(()) - } - - /// Writes argument's help to the wrapped stream. - fn help( - &mut self, - arg: Option<&Arg<'help>>, - about: &str, - spec_vals: &str, - next_line_help: bool, - longest: usize, - ) -> io::Result<()> { - debug!("Help::help"); - let mut help = String::from(about) + spec_vals; - debug!("Help::help: Next Line...{:?}", next_line_help); - - let spaces = if next_line_help { - 12 // "tab" * 3 - } else { - longest + 12 - }; - - let too_long = spaces + display_width(&help) >= self.term_w; - - // Is help on next line, if so then indent - if next_line_help { - self.none(format!("\n{}{}{}", TAB, TAB, TAB))?; - } - - debug!("Help::help: Too long..."); - if too_long && spaces <= self.term_w || help.contains("{n}") { - debug!("Yes"); - debug!("Help::help: help...{}", help); - debug!("Help::help: help width...{}", display_width(&help)); - // Determine how many newlines we need to insert - let avail_chars = self.term_w - spaces; - debug!("Help::help: Usable space...{}", avail_chars); - help = text_wrapper(&help.replace("{n}", "\n"), avail_chars); - } else { - debug!("No"); - } - if let Some(part) = help.lines().next() { - self.none(part)?; - } - - // indent of help - let spaces = if next_line_help { - TAB_WIDTH * 3 - } else if let Some(true) = arg.map(|a| a.is_positional()) { - longest + TAB_WIDTH * 2 - } else { - longest + TAB_WIDTH * 3 - }; - - for part in help.lines().skip(1) { - self.none("\n")?; - self.spaces(spaces)?; - self.none(part)?; - } - - #[cfg(feature = "unstable-v4")] - if let Some(arg) = arg { - const DASH_SPACE: usize = "- ".len(); - const COLON_SPACE: usize = ": ".len(); - let possible_vals = arg.get_possible_values2(); - if self.use_long - && !arg.is_hide_possible_values_set() - && possible_vals.iter().any(PossibleValue::should_show_help) - { - debug!("Help::help: Found possible vals...{:?}", possible_vals); - if !help.is_empty() { - self.none("\n\n")?; - self.spaces(spaces)?; - } - self.none("Possible values:")?; - let longest = possible_vals - .iter() - .filter_map(|f| f.get_visible_quoted_name().map(|name| display_width(&name))) - .max() - .expect("Only called with possible value"); - let help_longest = possible_vals - .iter() - .filter_map(|f| f.get_visible_help().map(display_width)) - .max() - .expect("Only called with possible value with help"); - // should new line - let taken = longest + spaces + DASH_SPACE; - - let possible_value_new_line = - self.term_w >= taken && self.term_w < taken + COLON_SPACE + help_longest; - - let spaces = spaces + TAB_WIDTH - DASH_SPACE; - let spaces_help = if possible_value_new_line { - spaces + DASH_SPACE - } else { - spaces + longest + DASH_SPACE + COLON_SPACE - }; - - for pv in possible_vals.iter().filter(|pv| !pv.is_hide_set()) { - self.none("\n")?; - self.spaces(spaces)?; - self.none("- ")?; - self.good(pv.get_name())?; - if let Some(help) = pv.get_help() { - debug!("Help::help: Possible Value help"); - - if possible_value_new_line { - self.none(":\n")?; - self.spaces(spaces_help)?; - } else { - self.none(": ")?; - // To align help messages - self.spaces(longest - display_width(pv.get_name()))?; - } - - let avail_chars = if self.term_w > spaces_help { - self.term_w - spaces_help - } else { - usize::MAX - }; - - let help = text_wrapper(help, avail_chars); - let mut help = help.lines(); - - self.none(help.next().unwrap_or_default())?; - for part in help { - self.none("\n")?; - self.spaces(spaces_help)?; - self.none(part)?; - } - } - } - } - } - Ok(()) - } - - /// Will use next line help on writing args. - fn will_args_wrap(&self, args: &[&Arg<'help>], longest: usize) -> bool { - args.iter() - .filter(|arg| should_show_arg(self.use_long, *arg)) - .any(|arg| { - let spec_vals = &self.spec_vals(arg); - self.arg_next_line_help(arg, spec_vals, longest) - }) - } - - fn arg_next_line_help(&self, arg: &Arg<'help>, spec_vals: &str, longest: usize) -> bool { - if self.next_line_help || arg.is_next_line_help_set() || self.use_long { - // setting_next_line - true - } else { - // force_next_line - let h = arg.help.unwrap_or(""); - let h_w = display_width(h) + display_width(spec_vals); - let taken = longest + 12; - self.term_w >= taken - && (taken as f32 / self.term_w as f32) > 0.40 - && h_w > (self.term_w - taken) - } - } - - fn spec_vals(&self, a: &Arg) -> String { - debug!("Help::spec_vals: a={}", a); - let mut spec_vals = vec![]; - #[cfg(feature = "env")] - if let Some(ref env) = a.env { - if !a.is_hide_env_set() { - debug!( - "Help::spec_vals: Found environment variable...[{:?}:{:?}]", - env.0, env.1 - ); - let env_val = if !a.is_hide_env_values_set() { - format!( - "={}", - env.1 - .as_ref() - .map_or(Cow::Borrowed(""), |val| val.to_string_lossy()) - ) - } else { - String::new() - }; - let env_info = format!("[env: {}{}]", env.0.to_string_lossy(), env_val); - spec_vals.push(env_info); - } - } - if a.is_takes_value_set() && !a.is_hide_default_value_set() && !a.default_vals.is_empty() { - debug!( - "Help::spec_vals: Found default value...[{:?}]", - a.default_vals - ); - - let pvs = a - .default_vals - .iter() - .map(|&pvs| pvs.to_string_lossy()) - .map(|pvs| { - if pvs.contains(char::is_whitespace) { - Cow::from(format!("{:?}", pvs)) - } else { - pvs - } - }) - .collect::>() - .join(" "); - - spec_vals.push(format!("[default: {}]", pvs)); - } - if !a.aliases.is_empty() { - debug!("Help::spec_vals: Found aliases...{:?}", a.aliases); - - let als = a - .aliases - .iter() - .filter(|&als| als.1) // visible - .map(|&als| als.0) // name - .collect::>() - .join(", "); - - if !als.is_empty() { - spec_vals.push(format!("[aliases: {}]", als)); - } - } - - if !a.short_aliases.is_empty() { - debug!( - "Help::spec_vals: Found short aliases...{:?}", - a.short_aliases - ); - - let als = a - .short_aliases - .iter() - .filter(|&als| als.1) // visible - .map(|&als| als.0.to_string()) // name - .collect::>() - .join(", "); - - if !als.is_empty() { - spec_vals.push(format!("[short aliases: {}]", als)); - } - } - - let possible_vals = a.get_possible_values2(); - if !(a.is_hide_possible_values_set() - || possible_vals.is_empty() - || cfg!(feature = "unstable-v4") - && self.use_long - && possible_vals.iter().any(PossibleValue::should_show_help)) - { - debug!("Help::spec_vals: Found possible vals...{:?}", possible_vals); - - let pvs = possible_vals - .iter() - .filter_map(PossibleValue::get_visible_quoted_name) - .collect::>() - .join(", "); - - spec_vals.push(format!("[possible values: {}]", pvs)); - } - let connector = if self.use_long { "\n" } else { " " }; - let prefix = if !spec_vals.is_empty() && !a.get_help().unwrap_or("").is_empty() { - if self.use_long { - "\n\n" - } else { - " " - } - } else { - "" - }; - prefix.to_string() + &spec_vals.join(connector) - } - - fn write_about(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> { - let about = if self.use_long { - self.cmd.get_long_about().or_else(|| self.cmd.get_about()) - } else { - self.cmd.get_about() - }; - if let Some(output) = about { - if before_new_line { - self.none("\n")?; - } - self.none(text_wrapper(output, self.term_w))?; - if after_new_line { - self.none("\n")?; - } - } - Ok(()) - } - - fn write_author(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> { - if let Some(author) = self.cmd.get_author() { - if before_new_line { - self.none("\n")?; - } - self.none(text_wrapper(author, self.term_w))?; - if after_new_line { - self.none("\n")?; - } - } - Ok(()) - } - - fn write_version(&mut self) -> io::Result<()> { - let version = self - .cmd - .get_version() - .or_else(|| self.cmd.get_long_version()); - if let Some(output) = version { - self.none(text_wrapper(output, self.term_w))?; - } - Ok(()) - } -} - -/// Methods to write a single subcommand -impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { - fn write_subcommand( - &mut self, - sc_str: &str, - cmd: &Command<'help>, - next_line_help: bool, - longest: usize, - ) -> io::Result<()> { - debug!("Help::write_subcommand"); - - let spec_vals = &self.sc_spec_vals(cmd); - - let about = cmd - .get_about() - .or_else(|| cmd.get_long_about()) - .unwrap_or(""); - - self.subcmd(sc_str, next_line_help, longest)?; - self.help(None, about, spec_vals, next_line_help, longest) - } - - fn sc_spec_vals(&self, a: &Command) -> String { - debug!("Help::sc_spec_vals: a={}", a.get_name()); - let mut spec_vals = vec![]; - if 0 < a.get_all_aliases().count() || 0 < a.get_all_short_flag_aliases().count() { - debug!( - "Help::spec_vals: Found aliases...{:?}", - a.get_all_aliases().collect::>() - ); - debug!( - "Help::spec_vals: Found short flag aliases...{:?}", - a.get_all_short_flag_aliases().collect::>() - ); - - let mut short_als = a - .get_visible_short_flag_aliases() - .map(|a| format!("-{}", a)) - .collect::>(); - - let als = a.get_visible_aliases().map(|s| s.to_string()); - - short_als.extend(als); - - let all_als = short_als.join(", "); - - if !all_als.is_empty() { - spec_vals.push(format!(" [aliases: {}]", all_als)); - } - } - spec_vals.join(" ") - } - - fn subcommand_next_line_help( - &self, - cmd: &Command<'help>, - spec_vals: &str, - longest: usize, - ) -> bool { - if self.next_line_help | self.use_long { - // setting_next_line - true - } else { - // force_next_line - let h = cmd.get_about().unwrap_or(""); - let h_w = display_width(h) + display_width(spec_vals); - let taken = longest + 12; - self.term_w >= taken - && (taken as f32 / self.term_w as f32) > 0.40 - && h_w > (self.term_w - taken) - } - } - - /// Writes subcommand to the wrapped stream. - fn subcmd(&mut self, sc_str: &str, next_line_help: bool, longest: usize) -> io::Result<()> { - self.none(TAB)?; - self.good(sc_str)?; - if !next_line_help { - let width = display_width(sc_str); - self.spaces(width.max(longest + 4) - width)?; - } - Ok(()) - } -} - -// Methods to write Parser help. -impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { - /// Writes help for all arguments (options, flags, args, subcommands) - /// including titles of a Parser Object to the wrapped stream. - pub(crate) fn write_all_args(&mut self) -> io::Result<()> { - debug!("Help::write_all_args"); - let pos = self - .cmd - .get_positionals_with_no_heading() - .filter(|arg| should_show_arg(self.use_long, arg)) - .collect::>(); - let non_pos = self - .cmd - .get_non_positionals_with_no_heading() - .filter(|arg| should_show_arg(self.use_long, arg)) - .collect::>(); - let subcmds = self.cmd.has_visible_subcommands(); - - let custom_headings = self - .cmd - .get_arguments() - .filter_map(|arg| arg.get_help_heading()) - .collect::>(); - - let mut first = if !pos.is_empty() { - // Write positional args if any - self.warning("ARGS:\n")?; - self.write_args_unsorted(&pos)?; - false - } else { - true - }; - - if !non_pos.is_empty() { - if !first { - self.none("\n\n")?; - } - self.warning("OPTIONS:\n")?; - self.write_args(&non_pos, "OPTIONS")?; - first = false; - } - if !custom_headings.is_empty() { - for heading in custom_headings { - let args = self - .cmd - .get_arguments() - .filter(|a| { - if let Some(help_heading) = a.get_help_heading() { - return help_heading == heading; - } - false - }) - .filter(|arg| should_show_arg(self.use_long, arg)) - .collect::>(); - - if !args.is_empty() { - if !first { - self.none("\n\n")?; - } - self.warning(format!("{}:\n", heading))?; - self.write_args(&args, heading)?; - first = false - } - } - } - - if subcmds { - if !first { - self.none("\n\n")?; - } - - self.warning( - self.cmd - .get_subcommand_help_heading() - .unwrap_or("SUBCOMMANDS"), - )?; - self.warning(":\n")?; - - self.write_subcommands(self.cmd)?; - } - - Ok(()) - } - - /// Will use next line help on writing subcommands. - fn will_subcommands_wrap<'a>( - &self, - subcommands: impl IntoIterator>, - longest: usize, - ) -> bool - where - 'help: 'a, - { - subcommands - .into_iter() - .filter(|&subcommand| should_show_subcommand(subcommand)) - .any(|subcommand| { - let spec_vals = &self.sc_spec_vals(subcommand); - self.subcommand_next_line_help(subcommand, spec_vals, longest) - }) - } - - /// Writes help for subcommands of a Parser Object to the wrapped stream. - fn write_subcommands(&mut self, cmd: &Command<'help>) -> io::Result<()> { - debug!("Help::write_subcommands"); - // The shortest an arg can legally be is 2 (i.e. '-x') - let mut longest = 2; - let mut ord_v = Vec::new(); - for subcommand in cmd - .get_subcommands() - .filter(|subcommand| should_show_subcommand(subcommand)) - { - let mut sc_str = String::new(); - sc_str.push_str(subcommand.get_name()); - if let Some(short) = subcommand.get_short_flag() { - write!(sc_str, " -{}", short).unwrap(); - } - if let Some(long) = subcommand.get_long_flag() { - write!(sc_str, " --{}", long).unwrap(); - } - longest = longest.max(display_width(&sc_str)); - ord_v.push((subcommand.get_display_order(), sc_str, subcommand)); - } - ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1))); - - debug!("Help::write_subcommands longest = {}", longest); - - let next_line_help = self.will_subcommands_wrap(cmd.get_subcommands(), longest); - - let mut first = true; - for (_, sc_str, sc) in &ord_v { - if first { - first = false; - } else { - self.none("\n")?; - } - self.write_subcommand(sc_str, sc, next_line_help, longest)?; - } - Ok(()) - } - - /// Writes binary name of a Parser Object to the wrapped stream. - fn write_display_name(&mut self) -> io::Result<()> { - debug!("Help::write_display_name"); - - let display_name = text_wrapper( - &self - .cmd - .get_display_name() - .unwrap_or_else(|| self.cmd.get_name()) - .replace("{n}", "\n"), - self.term_w, - ); - self.good(&display_name)?; - Ok(()) - } - - /// Writes binary name of a Parser Object to the wrapped stream. - fn write_bin_name(&mut self) -> io::Result<()> { - debug!("Help::write_bin_name"); - - let bin_name = if let Some(bn) = self.cmd.get_bin_name() { - if bn.contains(' ') { - // In case we're dealing with subcommands i.e. git mv is translated to git-mv - bn.replace(' ', "-") - } else { - text_wrapper(&self.cmd.get_name().replace("{n}", "\n"), self.term_w) - } - } else { - text_wrapper(&self.cmd.get_name().replace("{n}", "\n"), self.term_w) - }; - self.good(&bin_name)?; - Ok(()) - } -} - -// Methods to write Parser help using templates. -impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { - /// Write help to stream for the parser in the format defined by the template. - /// - /// For details about the template language see [`Command::help_template`]. - /// - /// [`Command::help_template`]: Command::help_template() - fn write_templated_help(&mut self, template: &str) -> io::Result<()> { - debug!("Help::write_templated_help"); - - // The strategy is to copy the template from the reader to wrapped stream - // until a tag is found. Depending on its value, the appropriate content is copied - // to the wrapped stream. - // The copy from template is then resumed, repeating this sequence until reading - // the complete template. - - macro_rules! tags { - ( - match $part:ident { - $( $tag:expr => $action:stmt )* - } - ) => { - match $part { - $( - part if part.starts_with(concat!($tag, "}")) => { - $action - let rest = &part[$tag.len()+1..]; - self.none(rest)?; - } - )* - - // Unknown tag, write it back. - part => { - self.none("{")?; - self.none(part)?; - } - } - }; - } - - let mut parts = template.split('{'); - if let Some(first) = parts.next() { - self.none(first)?; - } - - for part in parts { - tags! { - match part { - "name" => { - self.write_display_name()?; - } - "bin" => { - self.write_bin_name()?; - } - "version" => { - self.write_version()?; - } - "author" => { - self.write_author(false, false)?; - } - "author-with-newline" => { - self.write_author(false, true)?; - } - "author-section" => { - self.write_author(true, true)?; - } - "about" => { - self.write_about(false, false)?; - } - "about-with-newline" => { - self.write_about(false, true)?; - } - "about-section" => { - self.write_about(true, true)?; - } - "usage-heading" => { - self.warning("USAGE:")?; - } - "usage" => { - self.none(self.usage.create_usage_no_title(&[]))?; - } - "all-args" => { - self.write_all_args()?; - } - "options" => { - // Include even those with a heading as we don't have a good way of - // handling help_heading in the template. - self.write_args(&self.cmd.get_non_positionals().collect::>(), "options")?; - } - "positionals" => { - self.write_args(&self.cmd.get_positionals().collect::>(), "positionals")?; - } - "subcommands" => { - self.write_subcommands(self.cmd)?; - } - "after-help" => { - self.write_after_help()?; - } - "before-help" => { - self.write_before_help()?; - } - } - } - } - - Ok(()) - } -} - -pub(crate) fn dimensions() -> Option<(usize, usize)> { - #[cfg(not(feature = "wrap_help"))] - return None; - - #[cfg(feature = "wrap_help")] - terminal_size::terminal_size().map(|(w, h)| (w.0.into(), h.0.into())) -} - -const TAB: &str = " "; -const TAB_WIDTH: usize = 4; - -pub(crate) enum HelpWriter<'writer> { - Normal(&'writer mut dyn Write), - Buffer(&'writer mut Colorizer), -} - -fn should_show_arg(use_long: bool, arg: &Arg) -> bool { - debug!("should_show_arg: use_long={:?}, arg={}", use_long, arg.name); - if arg.is_hide_set() { - return false; - } - (!arg.is_hide_long_help_set() && use_long) - || (!arg.is_hide_short_help_set() && !use_long) - || arg.is_next_line_help_set() -} - -fn should_show_subcommand(subcommand: &Command) -> bool { - !subcommand.is_hide_set() -} - -fn text_wrapper(help: &str, width: usize) -> String { - let wrapper = textwrap::Options::new(width) - .break_words(false) - .word_splitter(textwrap::WordSplitter::NoHyphenation); - help.lines() - .map(|line| textwrap::fill(line, &wrapper)) - .collect::>() - .join("\n") -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn wrap_help_last_word() { - let help = String::from("foo bar baz"); - assert_eq!(text_wrapper(&help, 5), "foo\nbar\nbaz"); - } - - #[test] - fn display_width_handles_non_ascii() { - // Popular Danish tongue-twister, the name of a fruit dessert. - let text = "rødgrød med fløde"; - assert_eq!(display_width(text), 17); - // Note that the string width is smaller than the string - // length. This is due to the precomposed non-ASCII letters: - assert_eq!(text.len(), 20); - } - - #[test] - fn display_width_handles_emojis() { - let text = "😂"; - // There is a single `char`... - assert_eq!(text.chars().count(), 1); - // but it is double-width: - assert_eq!(display_width(text), 2); - // This is much less than the byte length: - assert_eq!(text.len(), 4); - } -} diff --git a/vendor/clap/src/output/mod.rs b/vendor/clap/src/output/mod.rs deleted file mode 100644 index e32aac26a..000000000 --- a/vendor/clap/src/output/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod help; -mod usage; - -pub(crate) mod fmt; - -pub(crate) use self::help::{Help, HelpWriter}; -pub(crate) use self::usage::Usage; diff --git a/vendor/clap/src/output/usage.rs b/vendor/clap/src/output/usage.rs deleted file mode 100644 index 6f7a2cad4..000000000 --- a/vendor/clap/src/output/usage.rs +++ /dev/null @@ -1,449 +0,0 @@ -use indexmap::IndexSet; - -// Internal -use crate::builder::AppSettings as AS; -use crate::builder::{Arg, ArgPredicate, Command}; -use crate::parser::ArgMatcher; -use crate::util::ChildGraph; -use crate::util::Id; -use crate::INTERNAL_ERROR_MSG; - -pub(crate) struct Usage<'help, 'cmd> { - cmd: &'cmd Command<'help>, - required: Option<&'cmd ChildGraph>, -} - -impl<'help, 'cmd> Usage<'help, 'cmd> { - pub(crate) fn new(cmd: &'cmd Command<'help>) -> Self { - Usage { - cmd, - required: None, - } - } - - pub(crate) fn required(mut self, required: &'cmd ChildGraph) -> Self { - self.required = Some(required); - self - } - - // Creates a usage string for display. This happens just after all arguments were parsed, but before - // any subcommands have been parsed (so as to give subcommands their own usage recursively) - pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> String { - debug!("Usage::create_usage_with_title"); - let mut usage = String::with_capacity(75); - usage.push_str("USAGE:\n "); - usage.push_str(&*self.create_usage_no_title(used)); - usage - } - - // Creates a usage string (*without title*) if one was not provided by the user manually. - pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String { - debug!("Usage::create_usage_no_title"); - if let Some(u) = self.cmd.get_override_usage() { - String::from(&*u) - } else if used.is_empty() { - self.create_help_usage(true) - } else { - self.create_smart_usage(used) - } - } - - // Creates a usage string for display in help messages (i.e. not for errors) - fn create_help_usage(&self, incl_reqs: bool) -> String { - debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs); - let mut usage = String::with_capacity(75); - let name = self - .cmd - .get_usage_name() - .or_else(|| self.cmd.get_bin_name()) - .unwrap_or_else(|| self.cmd.get_name()); - usage.push_str(name); - let req_string = if incl_reqs { - self.get_required_usage_from(&[], None, false) - .iter() - .fold(String::new(), |a, s| a + " " + s) - } else { - String::new() - }; - - if self.needs_options_tag() { - usage.push_str(" [OPTIONS]"); - } - - let allow_missing_positional = self.cmd.is_allow_missing_positional_set(); - if !allow_missing_positional { - usage.push_str(&req_string); - } - - let has_last = self.cmd.get_positionals().any(|p| p.is_last_set()); - // places a '--' in the usage string if there are args and options - // supporting multiple values - if self - .cmd - .get_non_positionals() - .any(|o| o.is_multiple_values_set()) - && self.cmd.get_positionals().any(|p| !p.is_required_set()) - && !(self.cmd.has_visible_subcommands() || self.cmd.is_allow_external_subcommands_set()) - && !has_last - { - usage.push_str(" [--]"); - } - let not_req_or_hidden = - |p: &Arg| (!p.is_required_set() || p.is_last_set()) && !p.is_hide_set(); - if self.cmd.get_positionals().any(not_req_or_hidden) { - if let Some(args_tag) = self.get_args_tag(incl_reqs) { - usage.push_str(&*args_tag); - } else { - usage.push_str(" [ARGS]"); - } - if has_last && incl_reqs { - let pos = self - .cmd - .get_positionals() - .find(|p| p.is_last_set()) - .expect(INTERNAL_ERROR_MSG); - debug!("Usage::create_help_usage: '{}' has .last(true)", pos.name); - let req = pos.is_required_set(); - if req && self.cmd.get_positionals().any(|p| !p.is_required_set()) { - usage.push_str(" -- <"); - } else if req { - usage.push_str(" [--] <"); - } else { - usage.push_str(" [-- <"); - } - usage.push_str(&*pos.name_no_brackets()); - usage.push('>'); - usage.push_str(pos.multiple_str()); - if !req { - usage.push(']'); - } - } - } - - if allow_missing_positional { - usage.push_str(&req_string); - } - - // incl_reqs is only false when this function is called recursively - if self.cmd.has_visible_subcommands() && incl_reqs - || self.cmd.is_allow_external_subcommands_set() - { - let placeholder = self.cmd.get_subcommand_value_name().unwrap_or("SUBCOMMAND"); - #[allow(deprecated)] - if self.cmd.is_subcommand_negates_reqs_set() - || self.cmd.is_args_conflicts_with_subcommands_set() - { - usage.push_str("\n "); - if !self.cmd.is_args_conflicts_with_subcommands_set() { - usage.push_str(&*self.create_help_usage(false)); - } else { - usage.push_str(&*name); - } - usage.push_str(" <"); - usage.push_str(placeholder); - usage.push('>'); - } else if self.cmd.is_subcommand_required_set() - || self.cmd.is_set(AS::SubcommandRequiredElseHelp) - { - usage.push_str(" <"); - usage.push_str(placeholder); - usage.push('>'); - } else { - usage.push_str(" ["); - usage.push_str(placeholder); - usage.push(']'); - } - } - let usage = usage.trim().to_owned(); - debug!("Usage::create_help_usage: usage={}", usage); - usage - } - - // Creates a context aware usage string, or "smart usage" from currently used - // args, and requirements - fn create_smart_usage(&self, used: &[Id]) -> String { - debug!("Usage::create_smart_usage"); - let mut usage = String::with_capacity(75); - - let r_string = self - .get_required_usage_from(used, None, true) - .iter() - .fold(String::new(), |acc, s| acc + " " + s); - - usage.push_str( - self.cmd - .get_usage_name() - .or_else(|| self.cmd.get_bin_name()) - .unwrap_or_else(|| self.cmd.get_name()), - ); - usage.push_str(&*r_string); - if self.cmd.is_subcommand_required_set() { - usage.push_str(" <"); - usage.push_str(self.cmd.get_subcommand_value_name().unwrap_or("SUBCOMMAND")); - usage.push('>'); - } - usage.shrink_to_fit(); - usage - } - - // Gets the `[ARGS]` tag for the usage string - fn get_args_tag(&self, incl_reqs: bool) -> Option { - debug!("Usage::get_args_tag; incl_reqs = {:?}", incl_reqs); - let mut count = 0; - for pos in self - .cmd - .get_positionals() - .filter(|pos| !pos.is_required_set()) - .filter(|pos| !pos.is_hide_set()) - .filter(|pos| !pos.is_last_set()) - { - debug!("Usage::get_args_tag:iter:{}", pos.name); - let required = self.cmd.groups_for_arg(&pos.id).any(|grp_s| { - debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s); - // if it's part of a required group we don't want to count it - self.cmd.get_groups().any(|g| g.required && (g.id == grp_s)) - }); - if !required { - count += 1; - debug!( - "Usage::get_args_tag:iter: {} Args not required or hidden", - count - ); - } - } - - if !self.cmd.is_dont_collapse_args_in_usage_set() && count > 1 { - debug!("Usage::get_args_tag:iter: More than one, returning [ARGS]"); - - // [ARGS] - None - } else if count == 1 && incl_reqs { - let pos = self - .cmd - .get_positionals() - .find(|pos| { - !pos.is_required_set() - && !pos.is_hide_set() - && !pos.is_last_set() - && !self.cmd.groups_for_arg(&pos.id).any(|grp_s| { - debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s); - // if it's part of a required group we don't want to count it - self.cmd.get_groups().any(|g| g.required && (g.id == grp_s)) - }) - }) - .expect(INTERNAL_ERROR_MSG); - - debug!( - "Usage::get_args_tag:iter: Exactly one, returning '{}'", - pos.name - ); - - Some(format!( - " [{}]{}", - pos.name_no_brackets(), - pos.multiple_str() - )) - } else if self.cmd.is_dont_collapse_args_in_usage_set() - && self.cmd.has_positionals() - && incl_reqs - { - debug!("Usage::get_args_tag:iter: Don't collapse returning all"); - Some( - self.cmd - .get_positionals() - .filter(|pos| !pos.is_required_set()) - .filter(|pos| !pos.is_hide_set()) - .filter(|pos| !pos.is_last_set()) - .map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())) - .collect::>() - .join(""), - ) - } else if !incl_reqs { - debug!("Usage::get_args_tag:iter: incl_reqs=false, building secondary usage string"); - let highest_req_pos = self - .cmd - .get_positionals() - .filter_map(|pos| { - if pos.is_required_set() && !pos.is_last_set() { - Some(pos.index) - } else { - None - } - }) - .max() - .unwrap_or_else(|| Some(self.cmd.get_positionals().count())); - Some( - self.cmd - .get_positionals() - .filter(|pos| pos.index <= highest_req_pos) - .filter(|pos| !pos.is_required_set()) - .filter(|pos| !pos.is_hide_set()) - .filter(|pos| !pos.is_last_set()) - .map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())) - .collect::>() - .join(""), - ) - } else { - Some("".into()) - } - } - - // Determines if we need the `[OPTIONS]` tag in the usage string - fn needs_options_tag(&self) -> bool { - debug!("Usage::needs_options_tag"); - 'outer: for f in self.cmd.get_non_positionals() { - debug!("Usage::needs_options_tag:iter: f={}", f.name); - - // Don't print `[OPTIONS]` just for help or version - if f.long == Some("help") || f.long == Some("version") { - debug!("Usage::needs_options_tag:iter Option is built-in"); - continue; - } - - if f.is_hide_set() { - debug!("Usage::needs_options_tag:iter Option is hidden"); - continue; - } - if f.is_required_set() { - debug!("Usage::needs_options_tag:iter Option is required"); - continue; - } - for grp_s in self.cmd.groups_for_arg(&f.id) { - debug!("Usage::needs_options_tag:iter:iter: grp_s={:?}", grp_s); - if self.cmd.get_groups().any(|g| g.id == grp_s && g.required) { - debug!("Usage::needs_options_tag:iter:iter: Group is required"); - continue 'outer; - } - } - - debug!("Usage::needs_options_tag:iter: [OPTIONS] required"); - return true; - } - - debug!("Usage::needs_options_tag: [OPTIONS] not required"); - false - } - - // Returns the required args in usage string form by fully unrolling all groups - // `incl_last`: should we include args that are Arg::Last? (i.e. `prog [foo] -- [last]). We - // can't do that for required usages being built for subcommands because it would look like: - // `prog [foo] -- [last] ` which is totally wrong. - pub(crate) fn get_required_usage_from( - &self, - incls: &[Id], - matcher: Option<&ArgMatcher>, - incl_last: bool, - ) -> IndexSet { - debug!( - "Usage::get_required_usage_from: incls={:?}, matcher={:?}, incl_last={:?}", - incls, - matcher.is_some(), - incl_last - ); - let mut ret_val = IndexSet::new(); - - let mut unrolled_reqs = IndexSet::new(); - - let required_owned; - let required = if let Some(required) = self.required { - required - } else { - required_owned = self.cmd.required_graph(); - &required_owned - }; - - for a in required.iter() { - let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option { - let required = match val { - ArgPredicate::Equals(_) => { - if let Some(matcher) = matcher { - matcher.check_explicit(a, *val) - } else { - false - } - } - ArgPredicate::IsPresent => true, - }; - required.then(|| req_arg.clone()) - }; - - for aa in self.cmd.unroll_arg_requires(is_relevant, a) { - // if we don't check for duplicates here this causes duplicate error messages - // see https://github.com/clap-rs/clap/issues/2770 - unrolled_reqs.insert(aa); - } - // always include the required arg itself. it will not be enumerated - // by unroll_requirements_for_arg. - unrolled_reqs.insert(a.clone()); - } - - debug!( - "Usage::get_required_usage_from: unrolled_reqs={:?}", - unrolled_reqs - ); - - let mut required_groups_members = IndexSet::new(); - let mut required_opts = IndexSet::new(); - let mut required_groups = IndexSet::new(); - let mut required_positionals = Vec::new(); - for req in unrolled_reqs.iter().chain(incls.iter()) { - if let Some(arg) = self.cmd.find(req) { - let is_present = matcher - .map(|m| m.check_explicit(req, ArgPredicate::IsPresent)) - .unwrap_or(false); - debug!( - "Usage::get_required_usage_from:iter:{:?} arg is_present={}", - req, is_present - ); - if !is_present { - if arg.is_positional() { - if incl_last || !arg.is_last_set() { - required_positionals.push((arg.index.unwrap(), arg.to_string())); - } - } else { - required_opts.insert(arg.to_string()); - } - } - } else { - debug_assert!(self.cmd.find_group(req).is_some()); - let group_members = self.cmd.unroll_args_in_group(req); - let is_present = matcher - .map(|m| { - group_members - .iter() - .any(|arg| m.check_explicit(arg, ArgPredicate::IsPresent)) - }) - .unwrap_or(false); - debug!( - "Usage::get_required_usage_from:iter:{:?} group is_present={}", - req, is_present - ); - if !is_present { - let elem = self.cmd.format_group(req); - required_groups.insert(elem); - required_groups_members.extend( - group_members - .iter() - .flat_map(|id| self.cmd.find(id)) - .map(|arg| arg.to_string()), - ); - } - } - } - - required_opts.retain(|arg| !required_groups_members.contains(arg)); - ret_val.extend(required_opts); - - ret_val.extend(required_groups); - - required_positionals.sort_by_key(|(ind, _)| *ind); // sort by index - for (_, p) in required_positionals { - if !required_groups_members.contains(&p) { - ret_val.insert(p); - } - } - - debug!("Usage::get_required_usage_from: ret_val={:?}", ret_val); - ret_val - } -} diff --git a/vendor/clap/src/parser/arg_matcher.rs b/vendor/clap/src/parser/arg_matcher.rs deleted file mode 100644 index 22087e722..000000000 --- a/vendor/clap/src/parser/arg_matcher.rs +++ /dev/null @@ -1,280 +0,0 @@ -// Std -use std::collections::HashMap; -use std::ffi::OsString; -use std::mem; -use std::ops::Deref; - -// Internal -use crate::builder::{Arg, ArgPredicate, Command}; -use crate::parser::AnyValue; -use crate::parser::Identifier; -use crate::parser::PendingArg; -use crate::parser::{ArgMatches, MatchedArg, SubCommand, ValueSource}; -use crate::util::Id; -use crate::INTERNAL_ERROR_MSG; - -#[derive(Debug, Default)] -pub(crate) struct ArgMatcher { - matches: ArgMatches, - pending: Option, -} - -impl ArgMatcher { - pub(crate) fn new(_cmd: &Command) -> Self { - ArgMatcher { - matches: ArgMatches { - #[cfg(debug_assertions)] - valid_args: { - let args = _cmd.get_arguments().map(|a| a.id.clone()); - let groups = _cmd.get_groups().map(|g| g.id.clone()); - args.chain(groups).collect() - }, - #[cfg(debug_assertions)] - valid_subcommands: _cmd.get_subcommands().map(|sc| sc.get_id()).collect(), - // HACK: Allow an external subcommand's ArgMatches be a stand-in for any ArgMatches - // since users can't detect it and avoid the asserts. - // - // See clap-rs/clap#3263 - #[cfg(debug_assertions)] - #[cfg(not(feature = "unstable-v4"))] - disable_asserts: _cmd.is_allow_external_subcommands_set(), - #[cfg(debug_assertions)] - #[cfg(feature = "unstable-v4")] - disable_asserts: false, - ..Default::default() - }, - pending: None, - } - } - - pub(crate) fn into_inner(self) -> ArgMatches { - self.matches - } - - pub(crate) fn propagate_globals(&mut self, global_arg_vec: &[Id]) { - debug!( - "ArgMatcher::get_global_values: global_arg_vec={:?}", - global_arg_vec - ); - let mut vals_map = HashMap::new(); - self.fill_in_global_values(global_arg_vec, &mut vals_map); - } - - fn fill_in_global_values( - &mut self, - global_arg_vec: &[Id], - vals_map: &mut HashMap, - ) { - for global_arg in global_arg_vec { - if let Some(ma) = self.get(global_arg) { - // We have to check if the parent's global arg wasn't used but still exists - // such as from a default value. - // - // For example, `myprog subcommand --global-arg=value` where `--global-arg` defines - // a default value of `other` myprog would have an existing MatchedArg for - // `--global-arg` where the value is `other` - let to_update = if let Some(parent_ma) = vals_map.get(global_arg) { - if parent_ma.source() > ma.source() { - parent_ma - } else { - ma - } - } else { - ma - } - .clone(); - vals_map.insert(global_arg.clone(), to_update); - } - } - if let Some(ref mut sc) = self.matches.subcommand { - let mut am = ArgMatcher { - matches: mem::take(&mut sc.matches), - pending: None, - }; - am.fill_in_global_values(global_arg_vec, vals_map); - mem::swap(&mut am.matches, &mut sc.matches); - } - - for (name, matched_arg) in vals_map.iter_mut() { - self.matches.args.insert(name.clone(), matched_arg.clone()); - } - } - - pub(crate) fn get(&self, arg: &Id) -> Option<&MatchedArg> { - self.matches.args.get(arg) - } - - pub(crate) fn get_mut(&mut self, arg: &Id) -> Option<&mut MatchedArg> { - self.matches.args.get_mut(arg) - } - - pub(crate) fn remove(&mut self, arg: &Id) { - self.matches.args.swap_remove(arg); - } - - pub(crate) fn contains(&self, arg: &Id) -> bool { - self.matches.args.contains_key(arg) - } - - pub(crate) fn arg_ids(&self) -> indexmap::map::Keys { - self.matches.args.keys() - } - - pub(crate) fn entry(&mut self, arg: &Id) -> indexmap::map::Entry { - self.matches.args.entry(arg.clone()) - } - - pub(crate) fn subcommand(&mut self, sc: SubCommand) { - self.matches.subcommand = Some(Box::new(sc)); - } - - pub(crate) fn subcommand_name(&self) -> Option<&str> { - self.matches.subcommand_name() - } - - pub(crate) fn iter(&self) -> indexmap::map::Iter { - self.matches.args.iter() - } - - pub(crate) fn check_explicit<'a>(&self, arg: &Id, predicate: ArgPredicate<'a>) -> bool { - self.get(arg).map_or(false, |a| a.check_explicit(predicate)) - } - - pub(crate) fn start_custom_arg(&mut self, arg: &Arg, source: ValueSource) { - let id = &arg.id; - debug!( - "ArgMatcher::start_custom_arg: id={:?}, source={:?}", - id, source - ); - let ma = self.entry(id).or_insert(MatchedArg::new_arg(arg)); - debug_assert_eq!(ma.type_id(), Some(arg.get_value_parser().type_id())); - ma.set_source(source); - ma.new_val_group(); - } - - pub(crate) fn start_custom_group(&mut self, id: &Id, source: ValueSource) { - debug!( - "ArgMatcher::start_custom_arg: id={:?}, source={:?}", - id, source - ); - let ma = self.entry(id).or_insert(MatchedArg::new_group()); - debug_assert_eq!(ma.type_id(), None); - ma.set_source(source); - ma.new_val_group(); - } - - pub(crate) fn start_occurrence_of_arg(&mut self, arg: &Arg) { - let id = &arg.id; - debug!("ArgMatcher::start_occurrence_of_arg: id={:?}", id); - let ma = self.entry(id).or_insert(MatchedArg::new_arg(arg)); - debug_assert_eq!(ma.type_id(), Some(arg.get_value_parser().type_id())); - ma.set_source(ValueSource::CommandLine); - #[allow(deprecated)] - ma.inc_occurrences(); - ma.new_val_group(); - } - - pub(crate) fn start_occurrence_of_group(&mut self, id: &Id) { - debug!("ArgMatcher::start_occurrence_of_group: id={:?}", id); - let ma = self.entry(id).or_insert(MatchedArg::new_group()); - debug_assert_eq!(ma.type_id(), None); - ma.set_source(ValueSource::CommandLine); - #[allow(deprecated)] - ma.inc_occurrences(); - ma.new_val_group(); - } - - pub(crate) fn start_occurrence_of_external(&mut self, cmd: &crate::Command) { - let id = &Id::empty_hash(); - debug!("ArgMatcher::start_occurrence_of_external: id={:?}", id,); - let ma = self.entry(id).or_insert(MatchedArg::new_external(cmd)); - debug_assert_eq!( - ma.type_id(), - Some( - cmd.get_external_subcommand_value_parser() - .expect(INTERNAL_ERROR_MSG) - .type_id() - ) - ); - ma.set_source(ValueSource::CommandLine); - #[allow(deprecated)] - ma.inc_occurrences(); - ma.new_val_group(); - } - - pub(crate) fn add_val_to(&mut self, arg: &Id, val: AnyValue, raw_val: OsString) { - let ma = self.get_mut(arg).expect(INTERNAL_ERROR_MSG); - ma.append_val(val, raw_val); - } - - pub(crate) fn add_index_to(&mut self, arg: &Id, idx: usize) { - let ma = self.get_mut(arg).expect(INTERNAL_ERROR_MSG); - ma.push_index(idx); - } - - pub(crate) fn needs_more_vals(&self, o: &Arg) -> bool { - let num_resolved = self.get(&o.id).map(|ma| ma.num_vals()).unwrap_or(0); - let num_pending = self - .pending - .as_ref() - .and_then(|p| (p.id == o.id).then(|| p.raw_vals.len())) - .unwrap_or(0); - let current_num = num_resolved + num_pending; - debug!( - "ArgMatcher::needs_more_vals: o={}, resolved={}, pending={}", - o.name, num_resolved, num_pending - ); - if current_num == 0 { - true - } else if let Some(num) = o.num_vals { - debug!("ArgMatcher::needs_more_vals: num_vals...{}", num); - #[allow(deprecated)] - if o.is_multiple_occurrences_set() { - (current_num % num) != 0 - } else { - num != current_num - } - } else if let Some(num) = o.max_vals { - debug!("ArgMatcher::needs_more_vals: max_vals...{}", num); - current_num < num - } else if o.min_vals.is_some() { - debug!("ArgMatcher::needs_more_vals: min_vals...true"); - true - } else { - o.is_multiple_values_set() - } - } - - pub(crate) fn pending_arg_id(&self) -> Option<&Id> { - self.pending.as_ref().map(|p| &p.id) - } - - pub(crate) fn pending_values_mut( - &mut self, - id: &Id, - ident: Option, - ) -> &mut Vec { - let pending = self.pending.get_or_insert_with(|| PendingArg { - id: id.clone(), - ident, - raw_vals: Default::default(), - }); - debug_assert_eq!(pending.id, *id, "{}", INTERNAL_ERROR_MSG); - if ident.is_some() { - debug_assert_eq!(pending.ident, ident, "{}", INTERNAL_ERROR_MSG); - } - &mut pending.raw_vals - } - - pub(crate) fn take_pending(&mut self) -> Option { - self.pending.take() - } -} - -impl Deref for ArgMatcher { - type Target = ArgMatches; - - fn deref(&self) -> &Self::Target { - &self.matches - } -} diff --git a/vendor/clap/src/parser/error.rs b/vendor/clap/src/parser/error.rs deleted file mode 100644 index caeba4b8f..000000000 --- a/vendor/clap/src/parser/error.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::util::Id; - -/// Violation of [`ArgMatches`][crate::ArgMatches] assumptions -#[derive(Clone, Debug)] -#[allow(missing_copy_implementations)] // We might add non-Copy types in the future -#[non_exhaustive] -pub enum MatchesError { - /// Failed to downcast `AnyValue` to the specified type - #[non_exhaustive] - Downcast { - /// Type for value stored in [`ArgMatches`][crate::ArgMatches] - actual: super::AnyValueId, - /// The target type to downcast to - expected: super::AnyValueId, - }, - /// Argument not defined in [`Command`][crate::Command] - #[non_exhaustive] - UnknownArgument { - // Missing `id` but blocked on a public id type which will hopefully come with `unstable-v4` - }, -} - -impl MatchesError { - #[track_caller] - pub(crate) fn unwrap(id: &Id, r: Result) -> T { - let err = match r { - Ok(t) => { - return t; - } - Err(err) => err, - }; - panic!( - "Mismatch between definition and access of `{:?}`. {}", - id, err - ) - } -} - -impl std::error::Error for MatchesError {} - -impl std::fmt::Display for MatchesError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Self::Downcast { actual, expected } => { - writeln!( - f, - "Could not downcast to {:?}, need to downcast to {:?}", - expected, actual - ) - } - Self::UnknownArgument {} => { - writeln!(f, "Unknown argument or group id. Make sure you are using the argument id and not the short or long flags") - } - } - } -} - -#[test] -fn check_auto_traits() { - static_assertions::assert_impl_all!( - MatchesError: Send, - Sync, - std::panic::RefUnwindSafe, - std::panic::UnwindSafe, - Unpin - ); -} diff --git a/vendor/clap/src/parser/features/mod.rs b/vendor/clap/src/parser/features/mod.rs deleted file mode 100644 index bdeb766ec..000000000 --- a/vendor/clap/src/parser/features/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod suggestions; diff --git a/vendor/clap/src/parser/features/suggestions.rs b/vendor/clap/src/parser/features/suggestions.rs deleted file mode 100644 index 9e46f3c9e..000000000 --- a/vendor/clap/src/parser/features/suggestions.rs +++ /dev/null @@ -1,105 +0,0 @@ -#[cfg(feature = "suggestions")] -use std::cmp::Ordering; - -// Internal -use crate::builder::Command; - -/// Produces multiple strings from a given list of possible values which are similar -/// to the passed in value `v` within a certain confidence by least confidence. -/// Thus in a list of possible values like ["foo", "bar"], the value "fop" will yield -/// `Some("foo")`, whereas "blark" would yield `None`. -#[cfg(feature = "suggestions")] -pub(crate) fn did_you_mean(v: &str, possible_values: I) -> Vec -where - T: AsRef, - I: IntoIterator, -{ - let mut candidates: Vec<(f64, String)> = possible_values - .into_iter() - .map(|pv| (strsim::jaro_winkler(v, pv.as_ref()), pv.as_ref().to_owned())) - .filter(|(confidence, _)| *confidence > 0.8) - .collect(); - candidates.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal)); - candidates.into_iter().map(|(_, pv)| pv).collect() -} - -#[cfg(not(feature = "suggestions"))] -pub(crate) fn did_you_mean(_: &str, _: I) -> Vec -where - T: AsRef, - I: IntoIterator, -{ - Vec::new() -} - -/// Returns a suffix that can be empty, or is the standard 'did you mean' phrase -pub(crate) fn did_you_mean_flag<'a, 'help, I, T>( - arg: &str, - remaining_args: &[&str], - longs: I, - subcommands: impl IntoIterator>, -) -> Option<(String, Option)> -where - 'help: 'a, - T: AsRef, - I: IntoIterator, -{ - use crate::mkeymap::KeyType; - - match did_you_mean(arg, longs).pop() { - Some(candidate) => Some((candidate, None)), - None => subcommands - .into_iter() - .filter_map(|subcommand| { - subcommand._build_self(); - - let longs = subcommand.get_keymap().keys().filter_map(|a| { - if let KeyType::Long(v) = a { - Some(v.to_string_lossy().into_owned()) - } else { - None - } - }); - - let subcommand_name = subcommand.get_name(); - - let candidate = did_you_mean(arg, longs).pop()?; - let score = remaining_args.iter().position(|x| *x == subcommand_name)?; - Some((score, (candidate, Some(subcommand_name.to_string())))) - }) - .min_by_key(|(x, _)| *x) - .map(|(_, suggestion)| suggestion), - } -} - -#[cfg(all(test, features = "suggestions"))] -mod test { - use super::*; - - #[test] - fn possible_values_match() { - let p_vals = ["test", "possible", "values"]; - assert_eq!(did_you_mean("tst", p_vals.iter()), Some("test")); - } - - #[test] - fn possible_values_match() { - let p_vals = ["test", "temp"]; - assert_eq!(did_you_mean("te", p_vals.iter()), Some("test")); - } - - #[test] - fn possible_values_nomatch() { - let p_vals = ["test", "possible", "values"]; - assert!(did_you_mean("hahaahahah", p_vals.iter()).is_none()); - } - - #[test] - fn flag() { - let p_vals = ["test", "possible", "values"]; - assert_eq!( - did_you_mean_flag("tst", p_vals.iter(), []), - Some(("test", None)) - ); - } -} diff --git a/vendor/clap/src/parser/matches/any_value.rs b/vendor/clap/src/parser/matches/any_value.rs deleted file mode 100644 index a9277e75f..000000000 --- a/vendor/clap/src/parser/matches/any_value.rs +++ /dev/null @@ -1,112 +0,0 @@ -#[derive(Clone)] -pub(crate) struct AnyValue { - inner: std::sync::Arc, - // While we can extract `TypeId` from `inner`, the debug repr is of a number, so let's track - // the type_name in debug builds. - id: AnyValueId, -} - -impl AnyValue { - pub(crate) fn new(inner: V) -> Self { - let id = AnyValueId::of::(); - let inner = std::sync::Arc::new(inner); - Self { inner, id } - } - - pub(crate) fn downcast_ref( - &self, - ) -> Option<&T> { - self.inner.downcast_ref::() - } - - pub(crate) fn downcast_into(self) -> Result { - let id = self.id; - let value = - std::sync::Arc::downcast::(self.inner).map_err(|inner| Self { inner, id })?; - let value = std::sync::Arc::try_unwrap(value).unwrap_or_else(|arc| (*arc).clone()); - Ok(value) - } - - pub(crate) fn type_id(&self) -> AnyValueId { - self.id - } -} - -impl std::fmt::Debug for AnyValue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - f.debug_struct("AnyValue").field("inner", &self.id).finish() - } -} - -#[derive(Copy, Clone)] -pub struct AnyValueId { - type_id: std::any::TypeId, - #[cfg(debug_assertions)] - type_name: &'static str, -} - -impl AnyValueId { - pub(crate) fn of() -> Self { - Self { - type_id: std::any::TypeId::of::(), - #[cfg(debug_assertions)] - type_name: std::any::type_name::(), - } - } -} - -impl PartialEq for AnyValueId { - fn eq(&self, other: &Self) -> bool { - self.type_id == other.type_id - } -} - -impl Eq for AnyValueId {} - -impl PartialOrd for AnyValueId { - fn partial_cmp(&self, other: &Self) -> Option { - self.type_id.partial_cmp(&other.type_id) - } -} - -impl Ord for AnyValueId { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.type_id.cmp(&other.type_id) - } -} - -impl std::hash::Hash for AnyValueId { - fn hash(&self, state: &mut H) { - self.type_id.hash(state); - } -} - -impl std::fmt::Debug for AnyValueId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - #[cfg(not(debug_assertions))] - { - self.type_id.fmt(f) - } - #[cfg(debug_assertions)] - { - f.debug_struct(self.type_name).finish() - } - } -} - -impl<'a, A: ?Sized + 'static> From<&'a A> for AnyValueId { - fn from(_: &'a A) -> Self { - Self::of::() - } -} - -#[cfg(test)] -mod test { - #[test] - #[cfg(debug_assertions)] - fn debug_impl() { - use super::*; - - assert_eq!(format!("{:?}", AnyValue::new(5)), "AnyValue { inner: i32 }"); - } -} diff --git a/vendor/clap/src/parser/matches/arg_matches.rs b/vendor/clap/src/parser/matches/arg_matches.rs deleted file mode 100644 index 2585c0219..000000000 --- a/vendor/clap/src/parser/matches/arg_matches.rs +++ /dev/null @@ -1,1896 +0,0 @@ -// Std -use std::any::Any; -use std::borrow::Cow; -use std::ffi::{OsStr, OsString}; -use std::fmt::{Debug, Display}; -use std::iter::{Cloned, Flatten, Map}; -use std::slice::Iter; -use std::str::FromStr; - -// Third Party -use indexmap::IndexMap; - -// Internal -use crate::parser::AnyValue; -use crate::parser::AnyValueId; -use crate::parser::MatchedArg; -use crate::parser::MatchesError; -use crate::parser::ValueSource; -use crate::util::{Id, Key}; -use crate::Error; -use crate::INTERNAL_ERROR_MSG; - -/// Container for parse results. -/// -/// Used to get information about the arguments that were supplied to the program at runtime by -/// the user. New instances of this struct are obtained by using the [`Command::get_matches`] family of -/// methods. -/// -/// # Examples -/// -/// ```no_run -/// # use clap::{Command, Arg, ValueSource}; -/// let matches = Command::new("MyApp") -/// .arg(Arg::new("out") -/// .long("output") -/// .required(true) -/// .takes_value(true) -/// .default_value("-")) -/// .arg(Arg::new("cfg") -/// .short('c') -/// .takes_value(true)) -/// .get_matches(); // builds the instance of ArgMatches -/// -/// // to get information about the "cfg" argument we created, such as the value supplied we use -/// // various ArgMatches methods, such as [ArgMatches::get_one] -/// if let Some(c) = matches.get_one::("cfg") { -/// println!("Value for -c: {}", c); -/// } -/// -/// // The ArgMatches::get_one method returns an Option because the user may not have supplied -/// // that argument at runtime. But if we specified that the argument was "required" as we did -/// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually -/// // used at runtime. -/// println!("Value for --output: {}", matches.get_one::("out").unwrap()); -/// -/// // You can check the presence of an argument's values -/// if matches.contains_id("out") { -/// // However, if you want to know where the value came from -/// if matches.value_source("out").expect("checked contains_id") == ValueSource::CommandLine { -/// println!("`out` set by user"); -/// } else { -/// println!("`out` is defaulted"); -/// } -/// } -/// ``` -/// [`Command::get_matches`]: crate::Command::get_matches() -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct ArgMatches { - #[cfg(debug_assertions)] - pub(crate) valid_args: Vec, - #[cfg(debug_assertions)] - pub(crate) valid_subcommands: Vec, - #[cfg(debug_assertions)] - pub(crate) disable_asserts: bool, - pub(crate) args: IndexMap, - pub(crate) subcommand: Option>, -} - -/// # Arguments -impl ArgMatches { - /// Gets the value of a specific option or positional argument. - /// - /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime. - /// - /// Returns an error if the wrong type was used. - /// - /// Returns `None` if the option wasn't present. - /// - /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set. - /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime. - /// - /// # Panic - /// - /// If the argument definition and access mismatch. To handle this case programmatically, see - /// [`ArgMatches::try_get_one`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, value_parser}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("port") - /// .value_parser(value_parser!(usize)) - /// .takes_value(true) - /// .required(true)) - /// .get_matches_from(vec!["myapp", "2020"]); - /// - /// let port: usize = *m - /// .get_one("port") - /// .expect("`port`is required"); - /// assert_eq!(port, 2020); - /// ``` - /// [option]: crate::Arg::takes_value() - /// [positional]: crate::Arg::index() - /// [`default_value`]: crate::Arg::default_value() - #[track_caller] - pub fn get_one(&self, id: &str) -> Option<&T> { - let internal_id = Id::from(id); - MatchesError::unwrap(&internal_id, self.try_get_one(id)) - } - - /// Gets the value of a specific [`ArgAction::Count`][crate::ArgAction::Count] flag - /// - /// # Panic - /// - /// If the argument's action is not [`ArgAction::Count`][crate::ArgAction::Count] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::Count) - /// ); - /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); - /// assert_eq!( - /// matches.get_count("flag"), - /// 2 - /// ); - /// ``` - #[track_caller] - pub fn get_count(&self, id: &str) -> u8 { - *self - .get_one::(id) - .expect("ArgAction::Count is defaulted") - } - - /// Gets the value of a specific [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] flag - /// - /// # Panic - /// - /// If the argument's action is not [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] - /// - /// # Examples - /// - /// ```rust - /// # use clap::Command; - /// # use clap::Arg; - /// let cmd = Command::new("mycmd") - /// .arg( - /// Arg::new("flag") - /// .long("flag") - /// .action(clap::ArgAction::SetTrue) - /// ); - /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); - /// assert!(matches.contains_id("flag")); - /// assert_eq!( - /// matches.get_flag("flag"), - /// true - /// ); - /// ``` - #[track_caller] - pub fn get_flag(&self, id: &str) -> bool { - *self - .get_one::(id) - .expect("ArgAction::SetTrue / ArgAction::SetFalse is defaulted") - } - - /// Iterate over values of a specific option or positional argument. - /// - /// i.e. an argument that takes multiple values at runtime. - /// - /// Returns an error if the wrong type was used. - /// - /// Returns `None` if the option wasn't present. - /// - /// # Panic - /// - /// If the argument definition and access mismatch. To handle this case programmatically, see - /// [`ArgMatches::try_get_many`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, value_parser, ArgAction}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("ports") - /// .action(ArgAction::Append) - /// .value_parser(value_parser!(usize)) - /// .short('p') - /// .takes_value(true) - /// .required(true)) - /// .get_matches_from(vec![ - /// "myprog", "-p", "22", "-p", "80", "-p", "2020" - /// ]); - /// let vals: Vec = m.get_many("ports") - /// .expect("`port`is required") - /// .copied() - /// .collect(); - /// assert_eq!(vals, [22, 80, 2020]); - /// ``` - #[track_caller] - pub fn get_many( - &self, - id: &str, - ) -> Option> { - let internal_id = Id::from(id); - MatchesError::unwrap(&internal_id, self.try_get_many(id)) - } - - /// Iterate over the original argument values. - /// - /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they - /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid - /// filename on a Unix system as an argument value may contain invalid UTF-8. - /// - /// Returns `None` if the option wasn't present. - /// - /// # Panic - /// - /// If the argument definition and access mismatch. To handle this case programmatically, see - /// [`ArgMatches::try_get_raw`]. - /// - /// # Examples - /// - #[cfg_attr(not(unix), doc = " ```ignore")] - #[cfg_attr(unix, doc = " ```")] - /// # use clap::{Command, arg, value_parser}; - /// # use std::ffi::{OsStr,OsString}; - /// # use std::os::unix::ffi::{OsStrExt,OsStringExt}; - /// use std::path::PathBuf; - /// - /// let m = Command::new("utf8") - /// .arg(arg!( ... "some arg").value_parser(value_parser!(PathBuf))) - /// .get_matches_from(vec![OsString::from("myprog"), - /// // "Hi" - /// OsString::from_vec(vec![b'H', b'i']), - /// // "{0xe9}!" - /// OsString::from_vec(vec![0xe9, b'!'])]); - /// - /// let mut itr = m.get_raw("arg") - /// .expect("`port`is required") - /// .into_iter(); - /// assert_eq!(itr.next(), Some(OsStr::new("Hi"))); - /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!']))); - /// assert_eq!(itr.next(), None); - /// ``` - /// [`Iterator`]: std::iter::Iterator - /// [`OsSt`]: std::ffi::OsStr - /// [values]: OsValues - /// [`String`]: std::string::String - #[track_caller] - pub fn get_raw(&self, id: &str) -> Option> { - let internal_id = Id::from(id); - MatchesError::unwrap(&internal_id, self.try_get_raw(id)) - } - - /// Returns the value of a specific option or positional argument. - /// - /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime. - /// - /// Returns an error if the wrong type was used. No item will have been removed. - /// - /// Returns `None` if the option wasn't present. - /// - /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set. - /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime. - /// - /// # Panic - /// - /// If the argument definition and access mismatch. To handle this case programmatically, see - /// [`ArgMatches::try_remove_one`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, value_parser}; - /// let mut m = Command::new("myprog") - /// .arg(Arg::new("file") - /// .required(true) - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "myprog", "file.txt", - /// ]); - /// let vals: String = m.remove_one("file") - /// .expect("`file`is required"); - /// assert_eq!(vals, "file.txt"); - /// ``` - /// [option]: crate::Arg::takes_value() - /// [positional]: crate::Arg::index() - /// [`default_value`]: crate::Arg::default_value() - #[track_caller] - pub fn remove_one(&mut self, id: &str) -> Option { - let internal_id = Id::from(id); - MatchesError::unwrap(&internal_id, self.try_remove_one(id)) - } - - /// Return values of a specific option or positional argument. - /// - /// i.e. an argument that takes multiple values at runtime. - /// - /// Returns an error if the wrong type was used. No item will have been removed. - /// - /// Returns `None` if the option wasn't present. - /// - /// # Panic - /// - /// If the argument definition and access mismatch. To handle this case programmatically, see - /// [`ArgMatches::try_remove_many`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, value_parser, ArgAction}; - /// let mut m = Command::new("myprog") - /// .arg(Arg::new("file") - /// .action(ArgAction::Append) - /// .multiple_values(true) - /// .required(true) - /// .takes_value(true)) - /// .get_matches_from(vec![ - /// "myprog", "file1.txt", "file2.txt", "file3.txt", "file4.txt", - /// ]); - /// let vals: Vec = m.remove_many("file") - /// .expect("`file`is required") - /// .collect(); - /// assert_eq!(vals, ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]); - /// ``` - #[track_caller] - pub fn remove_many( - &mut self, - id: &str, - ) -> Option> { - let internal_id = Id::from(id); - MatchesError::unwrap(&internal_id, self.try_remove_many(id)) - } - - /// Check if values are present for the argument or group id - /// - /// *NOTE:* This will always return `true` if [`default_value`] has been set. - /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime. - /// - /// # Panics - /// - /// If `id` is is not a valid argument or group name. To handle this case programmatically, see - /// [`ArgMatches::try_contains_id`]. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("debug") - /// .short('d')) - /// .get_matches_from(vec![ - /// "myprog", "-d" - /// ]); - /// - /// assert!(m.contains_id("debug")); - /// ``` - /// - /// [`default_value`]: crate::Arg::default_value() - pub fn contains_id(&self, id: &str) -> bool { - let internal_id = Id::from(id); - MatchesError::unwrap(&internal_id, self.try_contains_id(id)) - } - - /// Check if any args were present on the command line - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let mut cmd = Command::new("myapp") - /// .arg(Arg::new("output") - /// .takes_value(true)); - /// - /// let m = cmd - /// .try_get_matches_from_mut(vec!["myapp", "something"]) - /// .unwrap(); - /// assert!(m.args_present()); - /// - /// let m = cmd - /// .try_get_matches_from_mut(vec!["myapp"]) - /// .unwrap(); - /// assert!(! m.args_present()); - pub fn args_present(&self) -> bool { - !self.args.is_empty() - } - - /// Deprecated, replaced with [`ArgMatches::get_one()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn value_of(&self, id: T) -> Option<&str> { - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = unwrap_string_arg(&id, arg.first()?); - Some(v) - } - - /// Deprecated, replaced with [`ArgMatches::get_one()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn value_of_lossy(&self, id: T) -> Option> { - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = unwrap_os_string_arg(&id, arg.first()?); - Some(v.to_string_lossy()) - } - - /// Deprecated, replaced with [`ArgMatches::get_one()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn value_of_os(&self, id: T) -> Option<&OsStr> { - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = unwrap_os_string_arg(&id, arg.first()?); - Some(v) - } - - /// Deprecated, replaced with [`ArgMatches::get_many()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn values_of(&self, id: T) -> Option { - #![allow(deprecated)] - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = Values { - iter: arg.vals_flatten().map(unwrap_string), - len: arg.num_vals(), - }; - Some(v) - } - - /// Get an [`Iterator`] over groups of values of a specific option. - /// - /// specifically grouped by the occurrences of the options. - /// - /// Each group is a `Vec<&str>` containing the arguments passed to a single occurrence - /// of the option. - /// - /// If the option doesn't support multiple occurrences, or there was only a single occurrence, - /// the iterator will only contain a single item. - /// - /// Returns `None` if the option wasn't present. - /// - /// # Panics - /// - /// If the value is invalid UTF-8. - /// - /// If `id` is not a valid argument or group id. - /// - /// # Examples - /// ```rust - /// # use clap::{Command,Arg, ArgAction}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("exec") - /// .short('x') - /// .min_values(1) - /// .action(ArgAction::Append) - /// .value_terminator(";")) - /// .get_matches_from(vec![ - /// "myprog", "-x", "echo", "hi", ";", "-x", "echo", "bye"]); - /// let vals: Vec> = m.grouped_values_of("exec").unwrap().collect(); - /// assert_eq!(vals, [["echo", "hi"], ["echo", "bye"]]); - /// ``` - /// [`Iterator`]: std::iter::Iterator - #[cfg(feature = "unstable-grouped")] - #[cfg_attr(debug_assertions, track_caller)] - pub fn grouped_values_of(&self, id: T) -> Option { - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = GroupedValues { - iter: arg.vals().map(|g| g.iter().map(unwrap_string).collect()), - len: arg.vals().len(), - }; - Some(v) - } - - /// Deprecated, replaced with [`ArgMatches::get_many()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn values_of_lossy(&self, id: T) -> Option> { - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = arg - .vals_flatten() - .map(|v| unwrap_os_string_arg(&id, v).to_string_lossy().into_owned()) - .collect(); - Some(v) - } - - /// Deprecated, replaced with [`ArgMatches::get_many()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn values_of_os(&self, id: T) -> Option { - #![allow(deprecated)] - let id = Id::from(id); - let arg = self.get_arg(&id)?; - let v = OsValues { - iter: arg.vals_flatten().map(unwrap_os_string), - len: arg.num_vals(), - }; - Some(v) - } - - /// Deprecated, replaced with [`ArgMatches::get_one()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn value_of_t(&self, name: &str) -> Result - where - R: FromStr, - ::Err: Display, - { - #![allow(deprecated)] - let v = self - .value_of(name) - .ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?; - v.parse::().map_err(|e| { - let message = format!( - "The argument '{}' isn't a valid value for '{}': {}", - v, name, e - ); - - Error::value_validation(name.to_string(), v.to_string(), message.into()) - }) - } - - /// Deprecated, replaced with [`ArgMatches::get_one()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn value_of_t_or_exit(&self, name: &str) -> R - where - R: FromStr, - ::Err: Display, - { - #![allow(deprecated)] - self.value_of_t(name).unwrap_or_else(|e| e.exit()) - } - - /// Deprecated, replaced with [`ArgMatches::get_many()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn values_of_t(&self, name: &str) -> Result, Error> - where - R: FromStr, - ::Err: Display, - { - #![allow(deprecated)] - let v = self - .values_of(name) - .ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?; - v.map(|v| { - v.parse::().map_err(|e| { - let message = format!("The argument '{}' isn't a valid value: {}", v, e); - - Error::value_validation(name.to_string(), v.to_string(), message.into()) - }) - }) - .collect() - } - - /// Deprecated, replaced with [`ArgMatches::get_many()`] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn values_of_t_or_exit(&self, name: &str) -> Vec - where - R: FromStr, - ::Err: Display, - { - #![allow(deprecated)] - self.values_of_t(name).unwrap_or_else(|e| e.exit()) - } - - /// Deprecated, replaced with [`ArgAction::SetTrue`][crate::ArgAction] or - /// [`ArgMatches::contains_id`]. - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with either `ArgAction::SetTrue` or `ArgMatches::contains_id(...)`" - ) - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn is_present(&self, id: T) -> bool { - let id = Id::from(id); - - #[cfg(debug_assertions)] - self.get_arg(&id); - - self.args.contains_key(&id) - } - - /// Report where argument value came from - /// - /// # Panics - /// - /// If `id` is is not a valid argument or group id. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ValueSource}; - /// let m = Command::new("myprog") - /// .arg(Arg::new("debug") - /// .short('d')) - /// .get_matches_from(vec![ - /// "myprog", "-d" - /// ]); - /// - /// assert_eq!(m.value_source("debug"), Some(ValueSource::CommandLine)); - /// ``` - /// - /// [`default_value`]: crate::Arg::default_value() - #[cfg_attr(debug_assertions, track_caller)] - pub fn value_source(&self, id: T) -> Option { - let id = Id::from(id); - - let value = self.get_arg(&id); - - value.and_then(MatchedArg::source) - } - - /// Deprecated, replaced with [`ArgAction::Count`][crate::ArgAction], - /// [`ArgMatches::get_many`]`.len()`, or [`ArgMatches::value_source`]. - #[cfg_attr( - feature = "deprecated", - deprecated( - since = "3.2.0", - note = "Replaced with either `ArgAction::Count`, `ArgMatches::get_many(...).len()`, or `ArgMatches::value_source`" - ) - )] - #[cfg_attr(debug_assertions, track_caller)] - pub fn occurrences_of(&self, id: T) -> u64 { - #![allow(deprecated)] - self.get_arg(&Id::from(id)) - .map_or(0, |a| a.get_occurrences()) - } - - /// The first index of that an argument showed up. - /// - /// Indices are similar to argv indices, but are not exactly 1:1. - /// - /// For flags (i.e. those arguments which don't have an associated value), indices refer - /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices - /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the - /// index for `val` would be recorded. This is by design. - /// - /// Besides the flag/option discrepancy, the primary difference between an argv index and clap - /// index, is that clap continues counting once all arguments have properly separated, whereas - /// an argv index does not. - /// - /// The examples should clear this up. - /// - /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first* - /// index. See [`ArgMatches::indices_of`]. - /// - /// # Panics - /// - /// If `id` is is not a valid argument or group id. - /// - /// # Examples - /// - /// The argv indices are listed in the comments below. See how they correspond to the clap - /// indices. Note that if it's not listed in a clap index, this is because it's not saved in - /// in an `ArgMatches` struct for querying. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("option") - /// .short('o') - /// .takes_value(true)) - /// .get_matches_from(vec!["myapp", "-f", "-o", "val"]); - /// // ARGV indices: ^0 ^1 ^2 ^3 - /// // clap indices: ^1 ^3 - /// - /// assert_eq!(m.index_of("flag"), Some(1)); - /// assert_eq!(m.index_of("option"), Some(3)); - /// ``` - /// - /// Now notice, if we use one of the other styles of options: - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("option") - /// .short('o') - /// .takes_value(true)) - /// .get_matches_from(vec!["myapp", "-f", "-o=val"]); - /// // ARGV indices: ^0 ^1 ^2 - /// // clap indices: ^1 ^3 - /// - /// assert_eq!(m.index_of("flag"), Some(1)); - /// assert_eq!(m.index_of("option"), Some(3)); - /// ``` - /// - /// Things become much more complicated, or clear if we look at a more complex combination of - /// flags. Let's also throw in the final option style for good measure. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("flag2") - /// .short('F')) - /// .arg(Arg::new("flag3") - /// .short('z')) - /// .arg(Arg::new("option") - /// .short('o') - /// .takes_value(true)) - /// .get_matches_from(vec!["myapp", "-fzF", "-oval"]); - /// // ARGV indices: ^0 ^1 ^2 - /// // clap indices: ^1,2,3 ^5 - /// // - /// // clap sees the above as 'myapp -f -z -F -o val' - /// // ^0 ^1 ^2 ^3 ^4 ^5 - /// assert_eq!(m.index_of("flag"), Some(1)); - /// assert_eq!(m.index_of("flag2"), Some(3)); - /// assert_eq!(m.index_of("flag3"), Some(2)); - /// assert_eq!(m.index_of("option"), Some(5)); - /// ``` - /// - /// One final combination of flags/options to see how they combine: - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("flag") - /// .short('f')) - /// .arg(Arg::new("flag2") - /// .short('F')) - /// .arg(Arg::new("flag3") - /// .short('z')) - /// .arg(Arg::new("option") - /// .short('o') - /// .takes_value(true)) - /// .get_matches_from(vec!["myapp", "-fzFoval"]); - /// // ARGV indices: ^0 ^1 - /// // clap indices: ^1,2,3^5 - /// // - /// // clap sees the above as 'myapp -f -z -F -o val' - /// // ^0 ^1 ^2 ^3 ^4 ^5 - /// assert_eq!(m.index_of("flag"), Some(1)); - /// assert_eq!(m.index_of("flag2"), Some(3)); - /// assert_eq!(m.index_of("flag3"), Some(2)); - /// assert_eq!(m.index_of("option"), Some(5)); - /// ``` - /// - /// The last part to mention is when values are sent in multiple groups with a [delimiter]. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("option") - /// .short('o') - /// .use_value_delimiter(true) - /// .multiple_values(true)) - /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); - /// // ARGV indices: ^0 ^1 - /// // clap indices: ^2 ^3 ^4 - /// // - /// // clap sees the above as 'myapp -o val1 val2 val3' - /// // ^0 ^1 ^2 ^3 ^4 - /// assert_eq!(m.index_of("option"), Some(2)); - /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 3, 4]); - /// ``` - /// [delimiter]: crate::Arg::value_delimiter() - #[cfg_attr(debug_assertions, track_caller)] - pub fn index_of(&self, id: T) -> Option { - let arg = self.get_arg(&Id::from(id))?; - let i = arg.get_index(0)?; - Some(i) - } - - /// All indices an argument appeared at when parsing. - /// - /// Indices are similar to argv indices, but are not exactly 1:1. - /// - /// For flags (i.e. those arguments which don't have an associated value), indices refer - /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices - /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the - /// index for `val` would be recorded. This is by design. - /// - /// *NOTE:* For more information about how clap indices compared to argv indices, see - /// [`ArgMatches::index_of`] - /// - /// # Panics - /// - /// If `id` is is not a valid argument or group id. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("option") - /// .short('o') - /// .use_value_delimiter(true) - /// .multiple_values(true)) - /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); - /// // ARGV indices: ^0 ^1 - /// // clap indices: ^2 ^3 ^4 - /// // - /// // clap sees the above as 'myapp -o val1 val2 val3' - /// // ^0 ^1 ^2 ^3 ^4 - /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 3, 4]); - /// ``` - /// - /// Another quick example is when flags and options are used together - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("option") - /// .short('o') - /// .takes_value(true) - /// .action(ArgAction::Append)) - /// .arg(Arg::new("flag") - /// .short('f') - /// .action(ArgAction::Count)) - /// .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]); - /// // ARGV indices: ^0 ^1 ^2 ^3 ^4 ^5 ^6 - /// // clap indices: ^2 ^3 ^5 ^6 - /// - /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 5]); - /// assert_eq!(m.indices_of("flag").unwrap().collect::>(), &[6]); - /// ``` - /// - /// One final example, which is an odd case; if we *don't* use value delimiter as we did with - /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they - /// would all be a single value of `val1,val2,val3`, in which case they'd only receive a single - /// index. - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("myapp") - /// .arg(Arg::new("option") - /// .short('o') - /// .takes_value(true) - /// .multiple_values(true)) - /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); - /// // ARGV indices: ^0 ^1 - /// // clap indices: ^2 - /// // - /// // clap sees the above as 'myapp -o "val1,val2,val3"' - /// // ^0 ^1 ^2 - /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2]); - /// ``` - /// [`ArgMatches::index_of`]: ArgMatches::index_of() - /// [delimiter]: Arg::value_delimiter() - #[cfg_attr(debug_assertions, track_caller)] - pub fn indices_of(&self, id: T) -> Option> { - let arg = self.get_arg(&Id::from(id))?; - let i = Indices { - iter: arg.indices(), - len: arg.num_vals(), - }; - Some(i) - } - - #[inline] - #[doc(hidden)] - #[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::try_get_one()`") - )] - pub fn is_valid_arg(&self, _id: impl Key) -> bool { - #[cfg(debug_assertions)] - { - let id = Id::from(_id); - self.disable_asserts || id == Id::empty_hash() || self.valid_args.contains(&id) - } - #[cfg(not(debug_assertions))] - { - true - } - } -} - -/// # Subcommands -impl ArgMatches { - /// The name and `ArgMatches` of the current [subcommand]. - /// - /// Subcommand values are put in a child [`ArgMatches`] - /// - /// Returns `None` if the subcommand wasn't present at runtime, - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let app_m = Command::new("git") - /// .subcommand(Command::new("clone")) - /// .subcommand(Command::new("push")) - /// .subcommand(Command::new("commit")) - /// .get_matches(); - /// - /// match app_m.subcommand() { - /// Some(("clone", sub_m)) => {}, // clone was used - /// Some(("push", sub_m)) => {}, // push was used - /// Some(("commit", sub_m)) => {}, // commit was used - /// _ => {}, // Either no subcommand or one not tested for... - /// } - /// ``` - /// - /// Another useful scenario is when you want to support third party, or external, subcommands. - /// In these cases you can't know the subcommand name ahead of time, so use a variable instead - /// with pattern matching! - /// - /// ```rust - /// # use clap::Command; - /// // Assume there is an external subcommand named "subcmd" - /// let app_m = Command::new("myprog") - /// .allow_external_subcommands(true) - /// .get_matches_from(vec![ - /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" - /// ]); - /// - /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty - /// // string argument name - /// match app_m.subcommand() { - /// Some((external, sub_m)) => { - /// let ext_args: Vec<&str> = sub_m.get_many::("") - /// .unwrap().map(|s| s.as_str()).collect(); - /// assert_eq!(external, "subcmd"); - /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); - /// }, - /// _ => {}, - /// } - /// ``` - /// [subcommand]: crate::Command::subcommand - #[inline] - pub fn subcommand(&self) -> Option<(&str, &ArgMatches)> { - self.subcommand.as_ref().map(|sc| (&*sc.name, &sc.matches)) - } - - /// Return the name and `ArgMatches` of the current [subcommand]. - /// - /// Subcommand values are put in a child [`ArgMatches`] - /// - /// Returns `None` if the subcommand wasn't present at runtime, - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let mut app_m = Command::new("git") - /// .subcommand(Command::new("clone")) - /// .subcommand(Command::new("push")) - /// .subcommand(Command::new("commit")) - /// .subcommand_required(true) - /// .get_matches(); - /// - /// let (name, sub_m) = app_m.remove_subcommand().expect("required"); - /// match (name.as_str(), sub_m) { - /// ("clone", sub_m) => {}, // clone was used - /// ("push", sub_m) => {}, // push was used - /// ("commit", sub_m) => {}, // commit was used - /// (name, _) => unimplemented!("{}", name), - /// } - /// ``` - /// - /// Another useful scenario is when you want to support third party, or external, subcommands. - /// In these cases you can't know the subcommand name ahead of time, so use a variable instead - /// with pattern matching! - /// - /// ```rust - /// # use clap::Command; - /// // Assume there is an external subcommand named "subcmd" - /// let mut app_m = Command::new("myprog") - /// .allow_external_subcommands(true) - /// .get_matches_from(vec![ - /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" - /// ]); - /// - /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty - /// // string argument name - /// match app_m.remove_subcommand() { - /// Some((external, mut sub_m)) => { - /// let ext_args: Vec = sub_m.remove_many("") - /// .expect("`file`is required") - /// .collect(); - /// assert_eq!(external, "subcmd"); - /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); - /// }, - /// _ => {}, - /// } - /// ``` - /// [subcommand]: crate::Command::subcommand - pub fn remove_subcommand(&mut self) -> Option<(String, ArgMatches)> { - self.subcommand.take().map(|sc| (sc.name, sc.matches)) - } - - /// The `ArgMatches` for the current [subcommand]. - /// - /// Subcommand values are put in a child [`ArgMatches`] - /// - /// Returns `None` if the subcommand wasn't present at runtime, - /// - /// # Panics - /// - /// If `id` is is not a valid subcommand. - /// - /// # Examples - /// - /// ```rust - /// # use clap::{Command, Arg, ArgAction}; - /// let app_m = Command::new("myprog") - /// .arg(Arg::new("debug") - /// .short('d') - /// .action(ArgAction::SetTrue) - /// ) - /// .subcommand(Command::new("test") - /// .arg(Arg::new("opt") - /// .long("option") - /// .takes_value(true))) - /// .get_matches_from(vec![ - /// "myprog", "-d", "test", "--option", "val" - /// ]); - /// - /// // Both parent commands, and child subcommands can have arguments present at the same times - /// assert!(*app_m.get_one::("debug").expect("defaulted by clap")); - /// - /// // Get the subcommand's ArgMatches instance - /// if let Some(sub_m) = app_m.subcommand_matches("test") { - /// // Use the struct like normal - /// assert_eq!(sub_m.get_one::("opt").map(|s| s.as_str()), Some("val")); - /// } - /// ``` - /// - /// [subcommand]: crate::Command::subcommand - /// [`Command`]: crate::Command - pub fn subcommand_matches(&self, id: T) -> Option<&ArgMatches> { - self.get_subcommand(&id.into()).map(|sc| &sc.matches) - } - - /// The name of the current [subcommand]. - /// - /// Returns `None` if the subcommand wasn't present at runtime, - /// - /// # Examples - /// - /// ```no_run - /// # use clap::{Command, Arg, }; - /// let app_m = Command::new("git") - /// .subcommand(Command::new("clone")) - /// .subcommand(Command::new("push")) - /// .subcommand(Command::new("commit")) - /// .get_matches(); - /// - /// match app_m.subcommand_name() { - /// Some("clone") => {}, // clone was used - /// Some("push") => {}, // push was used - /// Some("commit") => {}, // commit was used - /// _ => {}, // Either no subcommand or one not tested for... - /// } - /// ``` - /// [subcommand]: crate::Command::subcommand - /// [`Command`]: crate::Command - #[inline] - pub fn subcommand_name(&self) -> Option<&str> { - self.subcommand.as_ref().map(|sc| &*sc.name) - } - - /// Check if a subcommand can be queried - /// - /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer - /// mistakes. In some context, this doesn't work, so users can use this function to check - /// before they do a query on `ArgMatches`. - #[inline] - #[doc(hidden)] - pub fn is_valid_subcommand(&self, _id: impl Key) -> bool { - #[cfg(debug_assertions)] - { - let id = Id::from(_id); - self.disable_asserts || id == Id::empty_hash() || self.valid_subcommands.contains(&id) - } - #[cfg(not(debug_assertions))] - { - true - } - } -} - -/// # Advanced -impl ArgMatches { - /// Non-panicking version of [`ArgMatches::get_one`] - pub fn try_get_one( - &self, - id: &str, - ) -> Result, MatchesError> { - let id = Id::from(id); - let arg = self.try_get_arg_t::(&id)?; - let value = match arg.and_then(|a| a.first()) { - Some(value) => value, - None => { - return Ok(None); - } - }; - Ok(value - .downcast_ref::() - .map(Some) - .expect(INTERNAL_ERROR_MSG)) // enforced by `try_get_arg_t` - } - - /// Non-panicking version of [`ArgMatches::get_many`] - pub fn try_get_many( - &self, - id: &str, - ) -> Result>, MatchesError> { - let id = Id::from(id); - let arg = match self.try_get_arg_t::(&id)? { - Some(arg) => arg, - None => return Ok(None), - }; - let len = arg.num_vals(); - let values = arg.vals_flatten(); - let values = ValuesRef { - // enforced by `try_get_arg_t` - iter: values.map(|v| v.downcast_ref::().expect(INTERNAL_ERROR_MSG)), - len, - }; - Ok(Some(values)) - } - - /// Non-panicking version of [`ArgMatches::get_raw`] - pub fn try_get_raw(&self, id: &str) -> Result>, MatchesError> { - let id = Id::from(id); - let arg = match self.try_get_arg(&id)? { - Some(arg) => arg, - None => return Ok(None), - }; - let len = arg.num_vals(); - let values = arg.raw_vals_flatten(); - let values = RawValues { - iter: values.map(OsString::as_os_str), - len, - }; - Ok(Some(values)) - } - - /// Non-panicking version of [`ArgMatches::remove_one`] - pub fn try_remove_one( - &mut self, - id: &str, - ) -> Result, MatchesError> { - let id = Id::from(id); - match self.try_remove_arg_t::(&id)? { - Some(values) => Ok(values - .into_vals_flatten() - // enforced by `try_get_arg_t` - .map(|v| v.downcast_into::().expect(INTERNAL_ERROR_MSG)) - .next()), - None => Ok(None), - } - } - - /// Non-panicking version of [`ArgMatches::remove_many`] - pub fn try_remove_many( - &mut self, - id: &str, - ) -> Result>, MatchesError> { - let id = Id::from(id); - let arg = match self.try_remove_arg_t::(&id)? { - Some(arg) => arg, - None => return Ok(None), - }; - let len = arg.num_vals(); - let values = arg.into_vals_flatten(); - let values = Values2 { - // enforced by `try_get_arg_t` - iter: values.map(|v| v.downcast_into::().expect(INTERNAL_ERROR_MSG)), - len, - }; - Ok(Some(values)) - } - - /// Non-panicking version of [`ArgMatches::contains_id`] - pub fn try_contains_id(&self, id: &str) -> Result { - let id = Id::from(id); - - self.verify_arg(&id)?; - - let presence = self.args.contains_key(&id); - Ok(presence) - } -} - -// Private methods -impl ArgMatches { - #[inline] - fn try_get_arg(&self, arg: &Id) -> Result, MatchesError> { - self.verify_arg(arg)?; - Ok(self.args.get(arg)) - } - - #[inline] - fn try_get_arg_t( - &self, - arg: &Id, - ) -> Result, MatchesError> { - let arg = match self.try_get_arg(arg)? { - Some(arg) => arg, - None => { - return Ok(None); - } - }; - self.verify_arg_t::(arg)?; - Ok(Some(arg)) - } - - #[inline] - fn try_remove_arg_t( - &mut self, - arg: &Id, - ) -> Result, MatchesError> { - self.verify_arg(arg)?; - let matched = match self.args.remove(arg) { - Some(matched) => matched, - None => { - return Ok(None); - } - }; - - let expected = AnyValueId::of::(); - let actual = matched.infer_type_id(expected); - if actual == expected { - Ok(Some(matched)) - } else { - self.args.insert(arg.clone(), matched); - Err(MatchesError::Downcast { actual, expected }) - } - } - - fn verify_arg_t( - &self, - arg: &MatchedArg, - ) -> Result<(), MatchesError> { - let expected = AnyValueId::of::(); - let actual = arg.infer_type_id(expected); - if expected == actual { - Ok(()) - } else { - Err(MatchesError::Downcast { actual, expected }) - } - } - - #[inline] - fn verify_arg(&self, _arg: &Id) -> Result<(), MatchesError> { - #[cfg(debug_assertions)] - { - if self.disable_asserts || *_arg == Id::empty_hash() || self.valid_args.contains(_arg) { - } else if self.valid_subcommands.contains(_arg) { - debug!( - "Subcommand `{:?}` used where an argument or group name was expected.", - _arg - ); - return Err(MatchesError::UnknownArgument {}); - } else { - debug!( - "`{:?}` is not an id of an argument or a group.\n\ - Make sure you're using the name of the argument itself \ - and not the name of short or long flags.", - _arg - ); - return Err(MatchesError::UnknownArgument {}); - } - } - Ok(()) - } - - #[inline] - #[cfg_attr(debug_assertions, track_caller)] - fn get_arg(&self, arg: &Id) -> Option<&MatchedArg> { - #[cfg(debug_assertions)] - { - if self.disable_asserts || *arg == Id::empty_hash() || self.valid_args.contains(arg) { - } else if self.valid_subcommands.contains(arg) { - panic!( - "Subcommand `{:?}` used where an argument or group name was expected.", - arg - ); - } else { - panic!( - "`{:?}` is not an id of an argument or a group.\n\ - Make sure you're using the name of the argument itself \ - and not the name of short or long flags.", - arg - ); - } - } - - self.args.get(arg) - } - - #[inline] - #[cfg_attr(debug_assertions, track_caller)] - fn get_subcommand(&self, id: &Id) -> Option<&SubCommand> { - #[cfg(debug_assertions)] - { - if self.disable_asserts - || *id == Id::empty_hash() - || self.valid_subcommands.contains(id) - { - } else if self.valid_args.contains(id) { - panic!( - "Argument or group `{:?}` used where a subcommand name was expected.", - id - ); - } else { - panic!("`{:?}` is not a name of a subcommand.", id); - } - } - - if let Some(ref sc) = self.subcommand { - if sc.id == *id { - return Some(sc); - } - } - - None - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct SubCommand { - pub(crate) id: Id, - pub(crate) name: String, - pub(crate) matches: ArgMatches, -} - -/// Iterate over multiple values for an argument via [`ArgMatches::remove_many`]. -/// -/// # Examples -/// -/// ```rust -/// # use clap::{Command, Arg, ArgAction}; -/// let mut m = Command::new("myapp") -/// .arg(Arg::new("output") -/// .short('o') -/// .action(ArgAction::Append) -/// .takes_value(true)) -/// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]); -/// -/// let mut values = m.remove_many::("output") -/// .unwrap(); -/// -/// assert_eq!(values.next(), Some(String::from("val1"))); -/// assert_eq!(values.next(), Some(String::from("val2"))); -/// assert_eq!(values.next(), None); -/// ``` -#[derive(Clone, Debug)] -pub struct Values2 { - #[allow(clippy::type_complexity)] - iter: Map>>, fn(AnyValue) -> T>, - len: usize, -} - -impl Iterator for Values2 { - type Item = T; - - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl DoubleEndedIterator for Values2 { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} - -impl ExactSizeIterator for Values2 {} - -/// Creates an empty iterator. -impl Default for Values2 { - fn default() -> Self { - let empty: Vec> = Default::default(); - Values2 { - iter: empty.into_iter().flatten().map(|_| unreachable!()), - len: 0, - } - } -} - -/// Iterate over multiple values for an argument via [`ArgMatches::get_many`]. -/// -/// # Examples -/// -/// ```rust -/// # use clap::{Command, Arg, ArgAction}; -/// let m = Command::new("myapp") -/// .arg(Arg::new("output") -/// .short('o') -/// .action(ArgAction::Append) -/// .takes_value(true)) -/// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]); -/// -/// let mut values = m.get_many::("output") -/// .unwrap() -/// .map(|s| s.as_str()); -/// -/// assert_eq!(values.next(), Some("val1")); -/// assert_eq!(values.next(), Some("val2")); -/// assert_eq!(values.next(), None); -/// ``` -#[derive(Clone, Debug)] -pub struct ValuesRef<'a, T> { - #[allow(clippy::type_complexity)] - iter: Map>>, fn(&AnyValue) -> &T>, - len: usize, -} - -impl<'a, T: 'a> Iterator for ValuesRef<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a, T: 'a> DoubleEndedIterator for ValuesRef<'a, T> { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} - -impl<'a, T: 'a> ExactSizeIterator for ValuesRef<'a, T> {} - -/// Creates an empty iterator. -impl<'a, T: 'a> Default for ValuesRef<'a, T> { - fn default() -> Self { - static EMPTY: [Vec; 0] = []; - ValuesRef { - iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), - len: 0, - } - } -} - -/// Iterate over raw argument values via [`ArgMatches::get_raw`]. -/// -/// # Examples -/// -#[cfg_attr(not(unix), doc = " ```ignore")] -#[cfg_attr(unix, doc = " ```")] -/// # use clap::{Command, arg, value_parser}; -/// use std::ffi::OsString; -/// use std::os::unix::ffi::{OsStrExt,OsStringExt}; -/// -/// let m = Command::new("utf8") -/// .arg(arg!( "some arg") -/// .value_parser(value_parser!(OsString))) -/// .get_matches_from(vec![OsString::from("myprog"), -/// // "Hi {0xe9}!" -/// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); -/// assert_eq!( -/// &*m.get_raw("arg") -/// .unwrap() -/// .next().unwrap() -/// .as_bytes(), -/// [b'H', b'i', b' ', 0xe9, b'!'] -/// ); -/// ``` -#[derive(Clone, Debug)] -pub struct RawValues<'a> { - #[allow(clippy::type_complexity)] - iter: Map>>, fn(&OsString) -> &OsStr>, - len: usize, -} - -impl<'a> Iterator for RawValues<'a> { - type Item = &'a OsStr; - - fn next(&mut self) -> Option<&'a OsStr> { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a> DoubleEndedIterator for RawValues<'a> { - fn next_back(&mut self) -> Option<&'a OsStr> { - self.iter.next_back() - } -} - -impl<'a> ExactSizeIterator for RawValues<'a> {} - -/// Creates an empty iterator. -impl Default for RawValues<'_> { - fn default() -> Self { - static EMPTY: [Vec; 0] = []; - RawValues { - iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), - len: 0, - } - } -} - -// The following were taken and adapted from vec_map source -// repo: https://github.com/contain-rs/vec-map -// commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33 -// license: MIT - Copyright (c) 2015 The Rust Project Developers - -/// Deprecated, replaced with [`ArgMatches::get_many()`] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") -)] -#[derive(Clone, Debug)] -pub struct Values<'a> { - #[allow(clippy::type_complexity)] - iter: Map>>, for<'r> fn(&'r AnyValue) -> &'r str>, - len: usize, -} - -#[allow(deprecated)] -impl<'a> Iterator for Values<'a> { - type Item = &'a str; - - fn next(&mut self) -> Option<&'a str> { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -#[allow(deprecated)] -impl<'a> DoubleEndedIterator for Values<'a> { - fn next_back(&mut self) -> Option<&'a str> { - self.iter.next_back() - } -} - -#[allow(deprecated)] -impl<'a> ExactSizeIterator for Values<'a> {} - -/// Creates an empty iterator. -#[allow(deprecated)] -impl<'a> Default for Values<'a> { - fn default() -> Self { - static EMPTY: [Vec; 0] = []; - Values { - iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), - len: 0, - } - } -} - -#[derive(Clone)] -#[allow(missing_debug_implementations)] -pub struct GroupedValues<'a> { - #[allow(clippy::type_complexity)] - iter: Map>, fn(&Vec) -> Vec<&str>>, - len: usize, -} - -impl<'a> Iterator for GroupedValues<'a> { - type Item = Vec<&'a str>; - - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a> DoubleEndedIterator for GroupedValues<'a> { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} - -impl<'a> ExactSizeIterator for GroupedValues<'a> {} - -/// Creates an empty iterator. Used for `unwrap_or_default()`. -impl<'a> Default for GroupedValues<'a> { - fn default() -> Self { - #![allow(deprecated)] - static EMPTY: [Vec; 0] = []; - GroupedValues { - iter: EMPTY[..].iter().map(|_| unreachable!()), - len: 0, - } - } -} - -/// Deprecated, replaced with [`ArgMatches::get_many()`] -#[cfg_attr( - feature = "deprecated", - deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") -)] -#[derive(Clone, Debug)] -pub struct OsValues<'a> { - #[allow(clippy::type_complexity)] - iter: Map>>, fn(&AnyValue) -> &OsStr>, - len: usize, -} - -#[allow(deprecated)] -impl<'a> Iterator for OsValues<'a> { - type Item = &'a OsStr; - - fn next(&mut self) -> Option<&'a OsStr> { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -#[allow(deprecated)] -impl<'a> DoubleEndedIterator for OsValues<'a> { - fn next_back(&mut self) -> Option<&'a OsStr> { - self.iter.next_back() - } -} - -#[allow(deprecated)] -impl<'a> ExactSizeIterator for OsValues<'a> {} - -/// Creates an empty iterator. -#[allow(deprecated)] -impl Default for OsValues<'_> { - fn default() -> Self { - static EMPTY: [Vec; 0] = []; - OsValues { - iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), - len: 0, - } - } -} - -/// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`] -/// -/// # Examples -/// -/// ```rust -/// # use clap::{Command, Arg}; -/// let m = Command::new("myapp") -/// .arg(Arg::new("output") -/// .short('o') -/// .multiple_values(true) -/// .takes_value(true)) -/// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]); -/// -/// let mut indices = m.indices_of("output").unwrap(); -/// -/// assert_eq!(indices.next(), Some(2)); -/// assert_eq!(indices.next(), Some(3)); -/// assert_eq!(indices.next(), None); -/// ``` -/// [`ArgMatches::indices_of`]: ArgMatches::indices_of() -#[derive(Clone, Debug)] -pub struct Indices<'a> { - iter: Cloned>, - len: usize, -} - -impl<'a> Iterator for Indices<'a> { - type Item = usize; - - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a> DoubleEndedIterator for Indices<'a> { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} - -impl<'a> ExactSizeIterator for Indices<'a> {} - -/// Creates an empty iterator. -impl<'a> Default for Indices<'a> { - fn default() -> Self { - static EMPTY: [usize; 0] = []; - // This is never called because the iterator is empty: - Indices { - iter: EMPTY[..].iter().cloned(), - len: 0, - } - } -} - -#[cfg_attr(debug_assertions, track_caller)] -#[inline] -fn unwrap_string(value: &AnyValue) -> &str { - match value.downcast_ref::() { - Some(value) => value, - None => { - panic!("Must use `_os` lookups with `Arg::allow_invalid_utf8`",) - } - } -} - -#[cfg_attr(debug_assertions, track_caller)] -#[inline] -fn unwrap_string_arg<'v>(id: &Id, value: &'v AnyValue) -> &'v str { - match value.downcast_ref::() { - Some(value) => value, - None => { - panic!( - "Must use `_os` lookups with `Arg::allow_invalid_utf8` at `{:?}`", - id - ) - } - } -} - -#[cfg_attr(debug_assertions, track_caller)] -#[inline] -fn unwrap_os_string(value: &AnyValue) -> &OsStr { - match value.downcast_ref::() { - Some(value) => value, - None => { - panic!("Must use `Arg::allow_invalid_utf8` with `_os` lookups",) - } - } -} - -#[cfg_attr(debug_assertions, track_caller)] -#[inline] -fn unwrap_os_string_arg<'v>(id: &Id, value: &'v AnyValue) -> &'v OsStr { - match value.downcast_ref::() { - Some(value) => value, - None => { - panic!( - "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `{:?}`", - id - ) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn check_auto_traits() { - static_assertions::assert_impl_all!(ArgMatches: Send, Sync, Unpin); - } - - #[test] - fn test_default_values() { - #![allow(deprecated)] - let mut values: Values = Values::default(); - assert_eq!(values.next(), None); - } - - #[test] - fn test_default_osvalues() { - #![allow(deprecated)] - let mut values: OsValues = OsValues::default(); - assert_eq!(values.next(), None); - } - - #[test] - fn test_default_raw_values() { - let mut values: RawValues = Default::default(); - assert_eq!(values.next(), None); - } - - #[test] - fn test_default_indices() { - let mut indices: Indices = Indices::default(); - assert_eq!(indices.next(), None); - } - - #[test] - fn test_default_indices_with_shorter_lifetime() { - let matches = ArgMatches::default(); - let mut indices = matches.indices_of("").unwrap_or_default(); - assert_eq!(indices.next(), None); - } - - #[test] - fn values_exact_size() { - let l = crate::Command::new("test") - .arg( - crate::Arg::new("POTATO") - .takes_value(true) - .multiple_values(true) - .required(true), - ) - .try_get_matches_from(["test", "one"]) - .unwrap() - .get_many::("POTATO") - .expect("present") - .count(); - assert_eq!(l, 1); - } - - #[test] - fn os_values_exact_size() { - let l = crate::Command::new("test") - .arg( - crate::Arg::new("POTATO") - .takes_value(true) - .multiple_values(true) - .value_parser(crate::builder::ValueParser::os_string()) - .required(true), - ) - .try_get_matches_from(["test", "one"]) - .unwrap() - .get_many::("POTATO") - .expect("present") - .count(); - assert_eq!(l, 1); - } - - #[test] - fn indices_exact_size() { - let l = crate::Command::new("test") - .arg( - crate::Arg::new("POTATO") - .takes_value(true) - .multiple_values(true) - .required(true), - ) - .try_get_matches_from(["test", "one"]) - .unwrap() - .indices_of("POTATO") - .expect("present") - .len(); - assert_eq!(l, 1); - } -} diff --git a/vendor/clap/src/parser/matches/matched_arg.rs b/vendor/clap/src/parser/matches/matched_arg.rs deleted file mode 100644 index fde6d37f3..000000000 --- a/vendor/clap/src/parser/matches/matched_arg.rs +++ /dev/null @@ -1,240 +0,0 @@ -// Std -use std::{ - ffi::{OsStr, OsString}, - iter::{Cloned, Flatten}, - slice::Iter, -}; - -use crate::builder::ArgPredicate; -use crate::parser::AnyValue; -use crate::parser::AnyValueId; -use crate::parser::ValueSource; -use crate::util::eq_ignore_case; -use crate::INTERNAL_ERROR_MSG; - -#[derive(Debug, Clone)] -pub(crate) struct MatchedArg { - occurs: u64, - source: Option, - indices: Vec, - type_id: Option, - vals: Vec>, - raw_vals: Vec>, - ignore_case: bool, -} - -impl MatchedArg { - pub(crate) fn new_arg(arg: &crate::Arg) -> Self { - let ignore_case = arg.is_ignore_case_set(); - Self { - occurs: 0, - source: None, - indices: Vec::new(), - type_id: Some(arg.get_value_parser().type_id()), - vals: Vec::new(), - raw_vals: Vec::new(), - ignore_case, - } - } - - pub(crate) fn new_group() -> Self { - let ignore_case = false; - Self { - occurs: 0, - source: None, - indices: Vec::new(), - type_id: None, - vals: Vec::new(), - raw_vals: Vec::new(), - ignore_case, - } - } - - pub(crate) fn new_external(cmd: &crate::Command) -> Self { - let ignore_case = false; - Self { - occurs: 0, - source: None, - indices: Vec::new(), - type_id: Some( - cmd.get_external_subcommand_value_parser() - .expect(INTERNAL_ERROR_MSG) - .type_id(), - ), - vals: Vec::new(), - raw_vals: Vec::new(), - ignore_case, - } - } - - #[cfg_attr(feature = "deprecated", deprecated(since = "3.2.0"))] - pub(crate) fn inc_occurrences(&mut self) { - self.occurs += 1; - } - - #[cfg_attr(feature = "deprecated", deprecated(since = "3.2.0"))] - pub(crate) fn set_occurrences(&mut self, occurs: u64) { - self.occurs = occurs - } - - #[cfg_attr(feature = "deprecated", deprecated(since = "3.2.0"))] - pub(crate) fn get_occurrences(&self) -> u64 { - self.occurs - } - - pub(crate) fn indices(&self) -> Cloned> { - self.indices.iter().cloned() - } - - pub(crate) fn get_index(&self, index: usize) -> Option { - self.indices.get(index).cloned() - } - - pub(crate) fn push_index(&mut self, index: usize) { - self.indices.push(index) - } - - #[cfg(feature = "unstable-grouped")] - pub(crate) fn vals(&self) -> Iter> { - self.vals.iter() - } - - pub(crate) fn vals_flatten(&self) -> Flatten>> { - self.vals.iter().flatten() - } - - pub(crate) fn into_vals_flatten(self) -> Flatten>> { - self.vals.into_iter().flatten() - } - - pub(crate) fn raw_vals_flatten(&self) -> Flatten>> { - self.raw_vals.iter().flatten() - } - - pub(crate) fn first(&self) -> Option<&AnyValue> { - self.vals_flatten().next() - } - - #[cfg(test)] - pub(crate) fn first_raw(&self) -> Option<&OsString> { - self.raw_vals_flatten().next() - } - - pub(crate) fn new_val_group(&mut self) { - self.vals.push(vec![]); - self.raw_vals.push(vec![]); - } - - pub(crate) fn append_val(&mut self, val: AnyValue, raw_val: OsString) { - // We assume there is always a group created before. - self.vals.last_mut().expect(INTERNAL_ERROR_MSG).push(val); - self.raw_vals - .last_mut() - .expect(INTERNAL_ERROR_MSG) - .push(raw_val); - } - - pub(crate) fn num_vals(&self) -> usize { - self.vals.iter().map(|v| v.len()).sum() - } - - // Will be used later - #[allow(dead_code)] - pub(crate) fn num_vals_last_group(&self) -> usize { - self.vals.last().map(|x| x.len()).unwrap_or(0) - } - - pub(crate) fn all_val_groups_empty(&self) -> bool { - self.vals.iter().flatten().count() == 0 - } - - pub(crate) fn check_explicit(&self, predicate: ArgPredicate) -> bool { - if self.source == Some(ValueSource::DefaultValue) { - return false; - } - - match predicate { - ArgPredicate::Equals(val) => self.raw_vals_flatten().any(|v| { - if self.ignore_case { - // If `v` isn't utf8, it can't match `val`, so `OsStr::to_str` should be fine - eq_ignore_case(&v.to_string_lossy(), &val.to_string_lossy()) - } else { - OsString::as_os_str(v) == OsStr::new(val) - } - }), - ArgPredicate::IsPresent => true, - } - } - - pub(crate) fn source(&self) -> Option { - self.source - } - - pub(crate) fn set_source(&mut self, source: ValueSource) { - if let Some(existing) = self.source { - self.source = Some(existing.max(source)); - } else { - self.source = Some(source) - } - } - - pub(crate) fn type_id(&self) -> Option { - self.type_id - } - - pub(crate) fn infer_type_id(&self, expected: AnyValueId) -> AnyValueId { - self.type_id() - .or_else(|| { - self.vals_flatten() - .map(|v| v.type_id()) - .find(|actual| *actual != expected) - }) - .unwrap_or(expected) - } -} - -impl PartialEq for MatchedArg { - fn eq(&self, other: &MatchedArg) -> bool { - let MatchedArg { - occurs: self_occurs, - source: self_source, - indices: self_indices, - type_id: self_type_id, - vals: _, - raw_vals: self_raw_vals, - ignore_case: self_ignore_case, - } = self; - let MatchedArg { - occurs: other_occurs, - source: other_source, - indices: other_indices, - type_id: other_type_id, - vals: _, - raw_vals: other_raw_vals, - ignore_case: other_ignore_case, - } = other; - self_occurs == other_occurs - && self_source == other_source - && self_indices == other_indices - && self_type_id == other_type_id - && self_raw_vals == other_raw_vals - && self_ignore_case == other_ignore_case - } -} - -impl Eq for MatchedArg {} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_grouped_vals_first() { - let mut m = MatchedArg::new_group(); - m.new_val_group(); - m.new_val_group(); - m.append_val(AnyValue::new(String::from("bbb")), "bbb".into()); - m.append_val(AnyValue::new(String::from("ccc")), "ccc".into()); - assert_eq!(m.first_raw(), Some(&OsString::from("bbb"))); - } -} diff --git a/vendor/clap/src/parser/matches/mod.rs b/vendor/clap/src/parser/matches/mod.rs deleted file mode 100644 index 7b88eeca7..000000000 --- a/vendor/clap/src/parser/matches/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod any_value; -mod arg_matches; -mod matched_arg; -mod value_source; - -pub use any_value::AnyValueId; -pub use arg_matches::RawValues; -pub use arg_matches::ValuesRef; -pub use arg_matches::{ArgMatches, Indices}; -pub use value_source::ValueSource; - -pub(crate) use any_value::AnyValue; -pub(crate) use arg_matches::SubCommand; -pub(crate) use matched_arg::MatchedArg; - -#[allow(deprecated)] -pub use arg_matches::{OsValues, Values}; diff --git a/vendor/clap/src/parser/matches/value_source.rs b/vendor/clap/src/parser/matches/value_source.rs deleted file mode 100644 index fb762d2af..000000000 --- a/vendor/clap/src/parser/matches/value_source.rs +++ /dev/null @@ -1,11 +0,0 @@ -/// Origin of the argument's value -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[non_exhaustive] -pub enum ValueSource { - /// Value came [`Arg::default_value`][crate::Arg::default_value] - DefaultValue, - /// Value came [`Arg::env`][crate::Arg::env] - EnvVariable, - /// Value was passed in on the command-line - CommandLine, -} diff --git a/vendor/clap/src/parser/mod.rs b/vendor/clap/src/parser/mod.rs deleted file mode 100644 index da81648e1..000000000 --- a/vendor/clap/src/parser/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! [`Command`][crate::Command] line argument parser - -mod arg_matcher; -mod error; -mod matches; -#[allow(clippy::module_inception)] -mod parser; -mod validator; - -pub(crate) mod features; - -pub(crate) use self::arg_matcher::ArgMatcher; -pub(crate) use self::matches::AnyValue; -pub(crate) use self::matches::AnyValueId; -pub(crate) use self::matches::{MatchedArg, SubCommand}; -pub(crate) use self::parser::Identifier; -pub(crate) use self::parser::PendingArg; -pub(crate) use self::parser::{ParseState, Parser}; -pub(crate) use self::validator::Validator; - -pub use self::matches::RawValues; -pub use self::matches::ValuesRef; -pub use self::matches::{ArgMatches, Indices, ValueSource}; -pub use error::MatchesError; - -#[allow(deprecated)] -pub use self::matches::{OsValues, Values}; diff --git a/vendor/clap/src/parser/parser.rs b/vendor/clap/src/parser/parser.rs deleted file mode 100644 index ad2bc6e9c..000000000 --- a/vendor/clap/src/parser/parser.rs +++ /dev/null @@ -1,1729 +0,0 @@ -// Std -use std::{ - cell::Cell, - ffi::{OsStr, OsString}, -}; - -// Third Party -use clap_lex::RawOsStr; - -// Internal -use crate::builder::AppSettings as AS; -use crate::builder::{Arg, Command}; -use crate::error::Error as ClapError; -use crate::error::Result as ClapResult; -use crate::mkeymap::KeyType; -use crate::output::fmt::Stream; -use crate::output::{fmt::Colorizer, Usage}; -use crate::parser::features::suggestions; -use crate::parser::{ArgMatcher, SubCommand}; -use crate::parser::{Validator, ValueSource}; -use crate::util::Id; -use crate::ArgAction; -use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8}; - -pub(crate) struct Parser<'help, 'cmd> { - cmd: &'cmd mut Command<'help>, - cur_idx: Cell, - /// Index of the previous flag subcommand in a group of flags. - flag_subcmd_at: Option, - /// Counter indicating the number of items to skip - /// when revisiting the group of flags which includes the flag subcommand. - flag_subcmd_skip: usize, -} - -// Initializing Methods -impl<'help, 'cmd> Parser<'help, 'cmd> { - pub(crate) fn new(cmd: &'cmd mut Command<'help>) -> Self { - Parser { - cmd, - cur_idx: Cell::new(0), - flag_subcmd_at: None, - flag_subcmd_skip: 0, - } - } -} - -// Parsing Methods -impl<'help, 'cmd> Parser<'help, 'cmd> { - // The actual parsing function - #[allow(clippy::cognitive_complexity)] - pub(crate) fn get_matches_with( - &mut self, - matcher: &mut ArgMatcher, - raw_args: &mut clap_lex::RawArgs, - mut args_cursor: clap_lex::ArgCursor, - ) -> ClapResult<()> { - debug!("Parser::get_matches_with"); - // Verify all positional assertions pass - - let mut subcmd_name: Option = None; - let mut keep_state = false; - let mut parse_state = ParseState::ValuesDone; - let mut pos_counter = 1; - - // Already met any valid arg(then we shouldn't expect subcommands after it). - let mut valid_arg_found = false; - // If the user already passed '--'. Meaning only positional args follow. - let mut trailing_values = false; - - // Count of positional args - let positional_count = self - .cmd - .get_keymap() - .keys() - .filter(|x| x.is_position()) - .count(); - // If any arg sets .last(true) - let contains_last = self.cmd.get_arguments().any(|x| x.is_last_set()); - - while let Some(arg_os) = raw_args.next(&mut args_cursor) { - // Recover the replaced items if any. - if let Some(replaced_items) = arg_os - .to_value() - .ok() - .and_then(|a| self.cmd.get_replacement(a)) - { - debug!( - "Parser::get_matches_with: found replacer: {:?}, target: {:?}", - arg_os, replaced_items - ); - raw_args.insert(&args_cursor, replaced_items); - continue; - } - - debug!( - "Parser::get_matches_with: Begin parsing '{:?}' ({:?})", - arg_os.to_value_os(), - arg_os.to_value_os().as_raw_bytes() - ); - - // Has the user already passed '--'? Meaning only positional args follow - if !trailing_values { - if self.cmd.is_subcommand_precedence_over_arg_set() - || !matches!(parse_state, ParseState::Opt(_) | ParseState::Pos(_)) - { - // Does the arg match a subcommand name, or any of its aliases (if defined) - let sc_name = self.possible_subcommand(arg_os.to_value(), valid_arg_found); - debug!("Parser::get_matches_with: sc={:?}", sc_name); - if let Some(sc_name) = sc_name { - #[allow(deprecated)] - if sc_name == "help" - && !self.is_set(AS::NoAutoHelp) - && !self.cmd.is_disable_help_subcommand_set() - { - self.parse_help_subcommand(raw_args.remaining(&mut args_cursor))?; - unreachable!("`parse_help_subcommand` always errors"); - } else { - subcmd_name = Some(sc_name.to_owned()); - } - break; - } - } - - if arg_os.is_escape() { - if matches!(&parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if - self.cmd[opt].is_allow_hyphen_values_set()) - { - // ParseResult::MaybeHyphenValue, do nothing - } else { - debug!("Parser::get_matches_with: setting TrailingVals=true"); - trailing_values = true; - continue; - } - } else if let Some((long_arg, long_value)) = arg_os.to_long() { - let parse_result = self.parse_long_arg( - matcher, - long_arg, - long_value, - &parse_state, - &mut valid_arg_found, - trailing_values, - )?; - debug!( - "Parser::get_matches_with: After parse_long_arg {:?}", - parse_result - ); - match parse_result { - ParseResult::NoArg => { - unreachable!("`to_long` always has the flag specified") - } - ParseResult::ValuesDone => { - parse_state = ParseState::ValuesDone; - continue; - } - ParseResult::Opt(id) => { - parse_state = ParseState::Opt(id); - continue; - } - ParseResult::FlagSubCommand(name) => { - debug!( - "Parser::get_matches_with: FlagSubCommand found in long arg {:?}", - &name - ); - subcmd_name = Some(name); - break; - } - ParseResult::EqualsNotProvided { arg } => { - let _ = self.resolve_pending(matcher); - return Err(ClapError::no_equals( - self.cmd, - arg, - Usage::new(self.cmd).create_usage_with_title(&[]), - )); - } - ParseResult::NoMatchingArg { arg } => { - let _ = self.resolve_pending(matcher); - let remaining_args: Vec<_> = raw_args - .remaining(&mut args_cursor) - .map(|x| x.to_str().expect(INVALID_UTF8)) - .collect(); - return Err(self.did_you_mean_error(&arg, matcher, &remaining_args)); - } - ParseResult::UnneededAttachedValue { rest, used, arg } => { - let _ = self.resolve_pending(matcher); - return Err(ClapError::too_many_values( - self.cmd, - rest, - arg, - Usage::new(self.cmd).create_usage_no_title(&used), - )); - } - ParseResult::MaybeHyphenValue => { - // Maybe a hyphen value, do nothing. - } - ParseResult::AttachedValueNotConsumed => { - unreachable!() - } - } - } else if let Some(short_arg) = arg_os.to_short() { - // Arg looks like a short flag, and not a possible number - - // Try to parse short args like normal, if allow_hyphen_values or - // AllowNegativeNumbers is set, parse_short_arg will *not* throw - // an error, and instead return Ok(None) - let parse_result = self.parse_short_arg( - matcher, - short_arg, - &parse_state, - pos_counter, - &mut valid_arg_found, - trailing_values, - )?; - // If it's None, we then check if one of those two AppSettings was set - debug!( - "Parser::get_matches_with: After parse_short_arg {:?}", - parse_result - ); - match parse_result { - ParseResult::NoArg => { - // Is a single dash `-`, try positional. - } - ParseResult::ValuesDone => { - parse_state = ParseState::ValuesDone; - continue; - } - ParseResult::Opt(id) => { - parse_state = ParseState::Opt(id); - continue; - } - ParseResult::FlagSubCommand(name) => { - // If there are more short flags to be processed, we should keep the state, and later - // revisit the current group of short flags skipping the subcommand. - keep_state = self - .flag_subcmd_at - .map(|at| { - raw_args - .seek(&mut args_cursor, clap_lex::SeekFrom::Current(-1)); - // Since we are now saving the current state, the number of flags to skip during state recovery should - // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position. - self.flag_subcmd_skip = self.cur_idx.get() - at + 1; - }) - .is_some(); - - debug!( - "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}", - name, - keep_state, - self.flag_subcmd_skip - ); - - subcmd_name = Some(name); - break; - } - ParseResult::EqualsNotProvided { arg } => { - let _ = self.resolve_pending(matcher); - return Err(ClapError::no_equals( - self.cmd, - arg, - Usage::new(self.cmd).create_usage_with_title(&[]), - )); - } - ParseResult::NoMatchingArg { arg } => { - let _ = self.resolve_pending(matcher); - return Err(ClapError::unknown_argument( - self.cmd, - arg, - None, - Usage::new(self.cmd).create_usage_with_title(&[]), - )); - } - ParseResult::MaybeHyphenValue => { - // Maybe a hyphen value, do nothing. - } - ParseResult::UnneededAttachedValue { .. } - | ParseResult::AttachedValueNotConsumed => unreachable!(), - } - } - - if let ParseState::Opt(id) = &parse_state { - // Assume this is a value of a previous arg. - - // get the option so we can check the settings - let arg_values = matcher.pending_values_mut(id, None); - let arg = &self.cmd[id]; - let parse_result = self.split_arg_values( - arg, - arg_os.to_value_os(), - trailing_values, - arg_values, - ); - let parse_result = parse_result.unwrap_or_else(|| { - if matcher.needs_more_vals(arg) { - ParseResult::Opt(arg.id.clone()) - } else { - ParseResult::ValuesDone - } - }); - parse_state = match parse_result { - ParseResult::Opt(id) => ParseState::Opt(id), - ParseResult::ValuesDone => ParseState::ValuesDone, - _ => unreachable!(), - }; - // get the next value from the iterator - continue; - } - } - - // Correct pos_counter. - pos_counter = { - let is_second_to_last = pos_counter + 1 == positional_count; - - // The last positional argument, or second to last positional - // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)` - let low_index_mults = is_second_to_last - && self - .cmd - .get_positionals() - .any(|a| a.is_multiple() && (positional_count != a.index.unwrap_or(0))) - && self - .cmd - .get_positionals() - .last() - .map_or(false, |p_name| !p_name.is_last_set()); - - let missing_pos = self.cmd.is_allow_missing_positional_set() - && is_second_to_last - && !trailing_values; - - debug!( - "Parser::get_matches_with: Positional counter...{}", - pos_counter - ); - debug!( - "Parser::get_matches_with: Low index multiples...{:?}", - low_index_mults - ); - - if low_index_mults || missing_pos { - let skip_current = if let Some(n) = raw_args.peek(&args_cursor) { - if let Some(arg) = self - .cmd - .get_positionals() - .find(|a| a.index == Some(pos_counter)) - { - // If next value looks like a new_arg or it's a - // subcommand, skip positional argument under current - // pos_counter(which means current value cannot be a - // positional argument with a value next to it), assume - // current value matches the next arg. - self.is_new_arg(&n, arg) - || self - .possible_subcommand(n.to_value(), valid_arg_found) - .is_some() - } else { - true - } - } else { - true - }; - - if skip_current { - debug!("Parser::get_matches_with: Bumping the positional counter..."); - pos_counter + 1 - } else { - pos_counter - } - } else if trailing_values - && (self.cmd.is_allow_missing_positional_set() || contains_last) - { - // Came to -- and one positional has .last(true) set, so we go immediately - // to the last (highest index) positional - debug!("Parser::get_matches_with: .last(true) and --, setting last pos"); - positional_count - } else { - pos_counter - } - }; - - if let Some(arg) = self.cmd.get_keymap().get(&pos_counter) { - if arg.is_last_set() && !trailing_values { - let _ = self.resolve_pending(matcher); - return Err(ClapError::unknown_argument( - self.cmd, - arg_os.display().to_string(), - None, - Usage::new(self.cmd).create_usage_with_title(&[]), - )); - } - - if self.cmd.is_trailing_var_arg_set() && pos_counter == positional_count { - trailing_values = true; - } - - if matcher.pending_arg_id() != Some(&arg.id) || !arg.is_multiple_values_set() { - self.resolve_pending(matcher)?; - } - let arg_values = matcher.pending_values_mut(&arg.id, Some(Identifier::Index)); - let _parse_result = - self.split_arg_values(arg, arg_os.to_value_os(), trailing_values, arg_values); - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!( - "Parser::get_matches_with: Ignoring state {:?}; positionals do their own thing", - _parse_result - ); - } - } - - // Only increment the positional counter if it doesn't allow multiples - if !arg.is_multiple() { - pos_counter += 1; - parse_state = ParseState::ValuesDone; - } else { - parse_state = ParseState::Pos(arg.id.clone()); - } - valid_arg_found = true; - } else if let Some(external_parser) = - self.cmd.get_external_subcommand_value_parser().cloned() - { - // Get external subcommand name - let sc_name = match arg_os.to_value() { - Ok(s) => s.to_string(), - Err(_) => { - let _ = self.resolve_pending(matcher); - return Err(ClapError::invalid_utf8( - self.cmd, - Usage::new(self.cmd).create_usage_with_title(&[]), - )); - } - }; - - // Collect the external subcommand args - let mut sc_m = ArgMatcher::new(self.cmd); - if cfg!(feature = "unstable-v4") || !raw_args.is_end(&args_cursor) { - sc_m.start_occurrence_of_external(self.cmd); - } - - for raw_val in raw_args.remaining(&mut args_cursor) { - let val = external_parser.parse_ref(self.cmd, None, raw_val)?; - let external_id = &Id::empty_hash(); - sc_m.add_val_to(external_id, val, raw_val.to_os_string()); - } - - matcher.subcommand(SubCommand { - id: Id::from(&*sc_name), - name: sc_name, - matches: sc_m.into_inner(), - }); - - self.resolve_pending(matcher)?; - #[cfg(feature = "env")] - self.add_env(matcher)?; - self.add_defaults(matcher)?; - return Validator::new(self.cmd).validate(parse_state, matcher); - } else { - // Start error processing - let _ = self.resolve_pending(matcher); - return Err(self.match_arg_error(&arg_os, valid_arg_found, trailing_values)); - } - } - - if let Some(ref pos_sc_name) = subcmd_name { - let sc_name = self - .cmd - .find_subcommand(pos_sc_name) - .expect(INTERNAL_ERROR_MSG) - .get_name() - .to_owned(); - self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state)?; - } - - self.resolve_pending(matcher)?; - #[cfg(feature = "env")] - self.add_env(matcher)?; - self.add_defaults(matcher)?; - Validator::new(self.cmd).validate(parse_state, matcher) - } - - fn match_arg_error( - &self, - arg_os: &clap_lex::ParsedArg<'_>, - valid_arg_found: bool, - trailing_values: bool, - ) -> ClapError { - // If argument follows a `--` - if trailing_values { - // If the arg matches a subcommand name, or any of its aliases (if defined) - if self - .possible_subcommand(arg_os.to_value(), valid_arg_found) - .is_some() - { - return ClapError::unnecessary_double_dash( - self.cmd, - arg_os.display().to_string(), - Usage::new(self.cmd).create_usage_with_title(&[]), - ); - } - } - let candidates = suggestions::did_you_mean( - &arg_os.display().to_string(), - self.cmd.all_subcommand_names(), - ); - // If the argument looks like a subcommand. - if !candidates.is_empty() { - let candidates: Vec<_> = candidates - .iter() - .map(|candidate| format!("'{}'", candidate)) - .collect(); - return ClapError::invalid_subcommand( - self.cmd, - arg_os.display().to_string(), - candidates.join(" or "), - self.cmd - .get_bin_name() - .unwrap_or_else(|| self.cmd.get_name()) - .to_owned(), - Usage::new(self.cmd).create_usage_with_title(&[]), - ); - } - // If the argument must be a subcommand. - if !self.cmd.has_args() || self.cmd.is_infer_subcommands_set() && self.cmd.has_subcommands() - { - return ClapError::unrecognized_subcommand( - self.cmd, - arg_os.display().to_string(), - Usage::new(self.cmd).create_usage_with_title(&[]), - ); - } - ClapError::unknown_argument( - self.cmd, - arg_os.display().to_string(), - None, - Usage::new(self.cmd).create_usage_with_title(&[]), - ) - } - - // Checks if the arg matches a subcommand name, or any of its aliases (if defined) - fn possible_subcommand( - &self, - arg: Result<&str, &RawOsStr>, - valid_arg_found: bool, - ) -> Option<&str> { - debug!("Parser::possible_subcommand: arg={:?}", arg); - let arg = arg.ok()?; - - if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) { - if self.cmd.is_infer_subcommands_set() { - // For subcommand `test`, we accepts it's prefix: `t`, `te`, - // `tes` and `test`. - let v = self - .cmd - .all_subcommand_names() - .filter(|s| s.starts_with(arg)) - .collect::>(); - - if v.len() == 1 { - return Some(v[0]); - } - - // If there is any ambiguity, fallback to non-infer subcommand - // search. - } - if let Some(sc) = self.cmd.find_subcommand(arg) { - return Some(sc.get_name()); - } - } - None - } - - // Checks if the arg matches a long flag subcommand name, or any of its aliases (if defined) - fn possible_long_flag_subcommand(&self, arg: &str) -> Option<&str> { - debug!("Parser::possible_long_flag_subcommand: arg={:?}", arg); - if self.cmd.is_infer_subcommands_set() { - let options = self - .cmd - .get_subcommands() - .fold(Vec::new(), |mut options, sc| { - if let Some(long) = sc.get_long_flag() { - if long.starts_with(arg) { - options.push(long); - } - options.extend(sc.get_all_aliases().filter(|alias| alias.starts_with(arg))) - } - options - }); - if options.len() == 1 { - return Some(options[0]); - } - - for sc in options { - if sc == arg { - return Some(sc); - } - } - } else if let Some(sc_name) = self.cmd.find_long_subcmd(arg) { - return Some(sc_name); - } - None - } - - fn parse_help_subcommand( - &self, - cmds: impl Iterator, - ) -> ClapResult { - debug!("Parser::parse_help_subcommand"); - - let mut cmd = self.cmd.clone(); - let sc = { - let mut sc = &mut cmd; - - for cmd in cmds { - sc = if let Some(sc_name) = - sc.find_subcommand(cmd).map(|sc| sc.get_name().to_owned()) - { - sc._build_subcommand(&sc_name).unwrap() - } else { - return Err(ClapError::unrecognized_subcommand( - sc, - cmd.to_string_lossy().into_owned(), - Usage::new(sc).create_usage_with_title(&[]), - )); - }; - } - - sc - }; - let parser = Parser::new(sc); - - Err(parser.help_err(true, Stream::Stdout)) - } - - fn is_new_arg(&self, next: &clap_lex::ParsedArg<'_>, current_positional: &Arg) -> bool { - #![allow(clippy::needless_bool)] // Prefer consistent if/else-if ladder - - debug!( - "Parser::is_new_arg: {:?}:{:?}", - next.to_value_os(), - current_positional.name - ); - - if self.cmd.is_allow_hyphen_values_set() - || self.cmd[¤t_positional.id].is_allow_hyphen_values_set() - || (self.cmd.is_allow_negative_numbers_set() && next.is_number()) - { - // If allow hyphen, this isn't a new arg. - debug!("Parser::is_new_arg: Allow hyphen"); - false - } else if next.is_long() { - // If this is a long flag, this is a new arg. - debug!("Parser::is_new_arg: -- found"); - true - } else if next.is_short() { - // If this is a short flag, this is a new arg. But a singe '-' by - // itself is a value and typically means "stdin" on unix systems. - debug!("Parser::is_new_arg: - found"); - true - } else { - // Nothing special, this is a value. - debug!("Parser::is_new_arg: value"); - false - } - } - - fn parse_subcommand( - &mut self, - sc_name: &str, - matcher: &mut ArgMatcher, - raw_args: &mut clap_lex::RawArgs, - args_cursor: clap_lex::ArgCursor, - keep_state: bool, - ) -> ClapResult<()> { - debug!("Parser::parse_subcommand"); - - let partial_parsing_enabled = self.cmd.is_ignore_errors_set(); - - if let Some(sc) = self.cmd._build_subcommand(sc_name) { - let mut sc_matcher = ArgMatcher::new(sc); - - debug!( - "Parser::parse_subcommand: About to parse sc={}", - sc.get_name() - ); - - { - let mut p = Parser::new(sc); - // HACK: maintain indexes between parsers - // FlagSubCommand short arg needs to revisit the current short args, but skip the subcommand itself - if keep_state { - p.cur_idx.set(self.cur_idx.get()); - p.flag_subcmd_at = self.flag_subcmd_at; - p.flag_subcmd_skip = self.flag_subcmd_skip; - } - if let Err(error) = p.get_matches_with(&mut sc_matcher, raw_args, args_cursor) { - if partial_parsing_enabled { - debug!( - "Parser::parse_subcommand: ignored error in subcommand {}: {:?}", - sc_name, error - ); - } else { - return Err(error); - } - } - } - matcher.subcommand(SubCommand { - id: sc.get_id(), - name: sc.get_name().to_owned(), - matches: sc_matcher.into_inner(), - }); - } - Ok(()) - } - - fn parse_long_arg( - &mut self, - matcher: &mut ArgMatcher, - long_arg: Result<&str, &RawOsStr>, - long_value: Option<&RawOsStr>, - parse_state: &ParseState, - valid_arg_found: &mut bool, - trailing_values: bool, - ) -> ClapResult { - // maybe here lifetime should be 'a - debug!("Parser::parse_long_arg"); - - if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if - self.cmd[opt].is_allow_hyphen_values_set()) - { - return Ok(ParseResult::MaybeHyphenValue); - } - - debug!("Parser::parse_long_arg: Does it contain '='..."); - let long_arg = match long_arg { - Ok(long_arg) => long_arg, - Err(long_arg) => { - return Ok(ParseResult::NoMatchingArg { - arg: long_arg.to_str_lossy().into_owned(), - }); - } - }; - if long_arg.is_empty() { - debug_assert!( - long_value.is_some(), - "`--` should be filtered out before this point" - ); - } - - let arg = if let Some(arg) = self.cmd.get_keymap().get(long_arg) { - debug!( - "Parser::parse_long_arg: Found valid arg or flag '{}'", - arg.to_string() - ); - Some((long_arg, arg)) - } else if self.cmd.is_infer_long_args_set() { - self.cmd.get_arguments().find_map(|a| { - if let Some(long) = a.long { - if long.starts_with(long_arg) { - return Some((long, a)); - } - } - a.aliases - .iter() - .find_map(|(alias, _)| alias.starts_with(long_arg).then(|| (*alias, a))) - }) - } else { - None - }; - - if let Some((_long_arg, arg)) = arg { - let ident = Identifier::Long; - *valid_arg_found = true; - if arg.is_takes_value_set() { - debug!( - "Parser::parse_long_arg({:?}): Found an arg with value '{:?}'", - long_arg, &long_value - ); - let has_eq = long_value.is_some(); - self.parse_opt_value(ident, long_value, arg, matcher, trailing_values, has_eq) - } else if let Some(rest) = long_value { - let required = self.cmd.required_graph(); - debug!( - "Parser::parse_long_arg({:?}): Got invalid literal `{:?}`", - long_arg, rest - ); - let used: Vec = matcher - .arg_ids() - .filter(|arg_id| { - matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) - }) - .filter(|&n| { - self.cmd - .find(n) - .map_or(true, |a| !(a.is_hide_set() || required.contains(&a.id))) - }) - .cloned() - .collect(); - - Ok(ParseResult::UnneededAttachedValue { - rest: rest.to_str_lossy().into_owned(), - used, - arg: arg.to_string(), - }) - } else { - debug!("Parser::parse_long_arg({:?}): Presence validated", long_arg); - self.react(Some(ident), ValueSource::CommandLine, arg, vec![], matcher) - } - } else if let Some(sc_name) = self.possible_long_flag_subcommand(long_arg) { - Ok(ParseResult::FlagSubCommand(sc_name.to_string())) - } else if self.cmd.is_allow_hyphen_values_set() { - Ok(ParseResult::MaybeHyphenValue) - } else { - Ok(ParseResult::NoMatchingArg { - arg: long_arg.to_owned(), - }) - } - } - - fn parse_short_arg( - &mut self, - matcher: &mut ArgMatcher, - mut short_arg: clap_lex::ShortFlags<'_>, - parse_state: &ParseState, - // change this to possible pos_arg when removing the usage of &mut Parser. - pos_counter: usize, - valid_arg_found: &mut bool, - trailing_values: bool, - ) -> ClapResult { - debug!("Parser::parse_short_arg: short_arg={:?}", short_arg); - - #[allow(clippy::blocks_in_if_conditions)] - if self.cmd.is_allow_negative_numbers_set() && short_arg.is_number() { - debug!("Parser::parse_short_arg: negative number"); - return Ok(ParseResult::MaybeHyphenValue); - } else if self.cmd.is_allow_hyphen_values_set() - && short_arg - .clone() - .any(|c| !c.map(|c| self.cmd.contains_short(c)).unwrap_or_default()) - { - debug!("Parser::parse_short_args: contains non-short flag"); - return Ok(ParseResult::MaybeHyphenValue); - } else if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) - if self.cmd[opt].is_allow_hyphen_values_set()) - { - debug!("Parser::parse_short_args: prior arg accepts hyphenated values",); - return Ok(ParseResult::MaybeHyphenValue); - } else if self - .cmd - .get_keymap() - .get(&pos_counter) - .map_or(false, |arg| { - arg.is_allow_hyphen_values_set() && !arg.is_last_set() - }) - { - debug!( - "Parser::parse_short_args: positional at {} allows hyphens", - pos_counter - ); - return Ok(ParseResult::MaybeHyphenValue); - } - - let mut ret = ParseResult::NoArg; - - let skip = self.flag_subcmd_skip; - self.flag_subcmd_skip = 0; - let res = short_arg.advance_by(skip); - debug_assert_eq!( - res, - Ok(()), - "tracking of `flag_subcmd_skip` is off for `{:?}`", - short_arg - ); - while let Some(c) = short_arg.next_flag() { - let c = match c { - Ok(c) => c, - Err(rest) => { - return Ok(ParseResult::NoMatchingArg { - arg: format!("-{}", rest.to_str_lossy()), - }); - } - }; - debug!("Parser::parse_short_arg:iter:{}", c); - - // Check for matching short options, and return the name if there is no trailing - // concatenated value: -oval - // Option: -o - // Value: val - if let Some(arg) = self.cmd.get_keymap().get(&c) { - let ident = Identifier::Short; - debug!( - "Parser::parse_short_arg:iter:{}: Found valid opt or flag", - c - ); - *valid_arg_found = true; - if !arg.is_takes_value_set() { - ret = - self.react(Some(ident), ValueSource::CommandLine, arg, vec![], matcher)?; - continue; - } - - // Check for trailing concatenated value - // - // Cloning the iterator, so we rollback if it isn't there. - let val = short_arg.clone().next_value_os().unwrap_or_default(); - debug!( - "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii), short_arg={:?}", - c, val, val.as_raw_bytes(), short_arg - ); - let val = Some(val).filter(|v| !v.is_empty()); - - // Default to "we're expecting a value later". - // - // If attached value is not consumed, we may have more short - // flags to parse, continue. - // - // e.g. `-xvf`, when require_equals && x.min_vals == 0, we don't - // consume the `vf`, even if it's provided as value. - let (val, has_eq) = if let Some(val) = val.and_then(|v| v.strip_prefix('=')) { - (Some(val), true) - } else { - (val, false) - }; - match self.parse_opt_value(ident, val, arg, matcher, trailing_values, has_eq)? { - ParseResult::AttachedValueNotConsumed => continue, - x => return Ok(x), - } - } - - return if let Some(sc_name) = self.cmd.find_short_subcmd(c) { - debug!("Parser::parse_short_arg:iter:{}: subcommand={}", c, sc_name); - // Make sure indices get updated before reading `self.cur_idx` - self.resolve_pending(matcher)?; - self.cur_idx.set(self.cur_idx.get() + 1); - debug!("Parser::parse_short_arg: cur_idx:={}", self.cur_idx.get()); - - let name = sc_name.to_string(); - // Get the index of the previously saved flag subcommand in the group of flags (if exists). - // If it is a new flag subcommand, then the formentioned index should be the current one - // (ie. `cur_idx`), and should be registered. - let cur_idx = self.cur_idx.get(); - self.flag_subcmd_at.get_or_insert(cur_idx); - let done_short_args = short_arg.is_empty(); - if done_short_args { - self.flag_subcmd_at = None; - } - Ok(ParseResult::FlagSubCommand(name)) - } else { - Ok(ParseResult::NoMatchingArg { - arg: format!("-{}", c), - }) - }; - } - Ok(ret) - } - - fn parse_opt_value( - &self, - ident: Identifier, - attached_value: Option<&RawOsStr>, - arg: &Arg<'help>, - matcher: &mut ArgMatcher, - trailing_values: bool, - has_eq: bool, - ) -> ClapResult { - debug!( - "Parser::parse_opt_value; arg={}, val={:?}, has_eq={:?}", - arg.name, attached_value, has_eq - ); - debug!("Parser::parse_opt_value; arg.settings={:?}", arg.settings); - - debug!("Parser::parse_opt_value; Checking for val..."); - // require_equals is set, but no '=' is provided, try throwing error. - if arg.is_require_equals_set() && !has_eq { - if arg.min_vals == Some(0) { - debug!("Requires equals, but min_vals == 0"); - let mut arg_values = Vec::new(); - // We assume this case is valid: require equals, but min_vals == 0. - if !arg.default_missing_vals.is_empty() { - debug!("Parser::parse_opt_value: has default_missing_vals"); - for v in arg.default_missing_vals.iter() { - let trailing_values = false; // CLI should not be affecting default_missing_values - let _parse_result = self.split_arg_values( - arg, - &RawOsStr::new(v), - trailing_values, - &mut arg_values, - ); - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!("Parser::parse_opt_value: Ignoring state {:?}; no values accepted after default_missing_values", _parse_result); - } - } - } - }; - let react_result = self.react( - Some(ident), - ValueSource::CommandLine, - arg, - arg_values, - matcher, - )?; - debug_assert_eq!(react_result, ParseResult::ValuesDone); - if attached_value.is_some() { - Ok(ParseResult::AttachedValueNotConsumed) - } else { - Ok(ParseResult::ValuesDone) - } - } else { - debug!("Requires equals but not provided. Error."); - Ok(ParseResult::EqualsNotProvided { - arg: arg.to_string(), - }) - } - } else if let Some(v) = attached_value { - let mut arg_values = Vec::new(); - let parse_result = self.split_arg_values(arg, v, trailing_values, &mut arg_values); - let react_result = self.react( - Some(ident), - ValueSource::CommandLine, - arg, - arg_values, - matcher, - )?; - debug_assert_eq!(react_result, ParseResult::ValuesDone); - let mut parse_result = parse_result.unwrap_or_else(|| { - if matcher.needs_more_vals(arg) { - ParseResult::Opt(arg.id.clone()) - } else { - ParseResult::ValuesDone - } - }); - if parse_result != ParseResult::ValuesDone { - debug!("Parser::parse_opt_value: Overriding state {:?}; no values accepted after attached", parse_result); - parse_result = ParseResult::ValuesDone; - } - Ok(parse_result) - } else { - debug!("Parser::parse_opt_value: More arg vals required..."); - self.resolve_pending(matcher)?; - matcher.pending_values_mut(&arg.id, Some(ident)); - Ok(ParseResult::Opt(arg.id.clone())) - } - } - - fn split_arg_values( - &self, - arg: &Arg<'help>, - val: &RawOsStr, - trailing_values: bool, - output: &mut Vec, - ) -> Option { - debug!("Parser::split_arg_values; arg={}, val={:?}", arg.name, val); - debug!( - "Parser::split_arg_values; trailing_values={:?}, DontDelimTrailingVals={:?}", - trailing_values, - self.cmd.is_dont_delimit_trailing_values_set() - ); - - let mut delim = arg.val_delim; - if trailing_values && self.cmd.is_dont_delimit_trailing_values_set() { - delim = None; - } - match delim { - Some(delim) if val.contains(delim) => { - let vals = val.split(delim).map(|x| x.to_os_str().into_owned()); - for raw_val in vals { - if Some(raw_val.as_os_str()) == arg.terminator.map(OsStr::new) { - return Some(ParseResult::ValuesDone); - } - output.push(raw_val); - } - // Delimited values are always considered the final value - Some(ParseResult::ValuesDone) - } - _ if Some(val) == arg.terminator.map(RawOsStr::from_str) => { - Some(ParseResult::ValuesDone) - } - _ => { - output.push(val.to_os_str().into_owned()); - if arg.is_require_value_delimiter_set() { - Some(ParseResult::ValuesDone) - } else { - None - } - } - } - } - - fn push_arg_values( - &self, - arg: &Arg<'help>, - raw_vals: Vec, - matcher: &mut ArgMatcher, - ) -> ClapResult<()> { - debug!("Parser::push_arg_values: {:?}", raw_vals); - - for raw_val in raw_vals { - // update the current index because each value is a distinct index to clap - self.cur_idx.set(self.cur_idx.get() + 1); - debug!( - "Parser::add_single_val_to_arg: cur_idx:={}", - self.cur_idx.get() - ); - let value_parser = arg.get_value_parser(); - let val = value_parser.parse_ref(self.cmd, Some(arg), &raw_val)?; - - // Increment or create the group "args" - for group in self.cmd.groups_for_arg(&arg.id) { - matcher.add_val_to(&group, val.clone(), raw_val.clone()); - } - - matcher.add_val_to(&arg.id, val, raw_val); - matcher.add_index_to(&arg.id, self.cur_idx.get()); - } - - Ok(()) - } - - fn resolve_pending(&self, matcher: &mut ArgMatcher) -> ClapResult<()> { - let pending = match matcher.take_pending() { - Some(pending) => pending, - None => { - return Ok(()); - } - }; - - debug!("Parser::resolve_pending: id={:?}", pending.id); - let arg = self.cmd.find(&pending.id).expect(INTERNAL_ERROR_MSG); - let _ = self.react( - pending.ident, - ValueSource::CommandLine, - arg, - pending.raw_vals, - matcher, - )?; - - Ok(()) - } - - fn react( - &self, - ident: Option, - source: ValueSource, - arg: &Arg<'help>, - raw_vals: Vec, - matcher: &mut ArgMatcher, - ) -> ClapResult { - self.resolve_pending(matcher)?; - - debug!( - "Parser::react action={:?}, identifier={:?}, source={:?}", - arg.get_action(), - ident, - source - ); - match arg.get_action() { - ArgAction::Set => { - if source == ValueSource::CommandLine - && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) - { - // Record flag's index - self.cur_idx.set(self.cur_idx.get() + 1); - debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); - } - matcher.remove(&arg.id); - self.start_custom_arg(matcher, arg, source); - self.push_arg_values(arg, raw_vals, matcher)?; - if cfg!(debug_assertions) && matcher.needs_more_vals(arg) { - debug!( - "Parser::react not enough values passed in, leaving it to the validator to complain", - ); - } - Ok(ParseResult::ValuesDone) - } - ArgAction::Append => { - if source == ValueSource::CommandLine - && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) - { - // Record flag's index - self.cur_idx.set(self.cur_idx.get() + 1); - debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); - } - self.start_custom_arg(matcher, arg, source); - self.push_arg_values(arg, raw_vals, matcher)?; - if cfg!(debug_assertions) && matcher.needs_more_vals(arg) { - debug!( - "Parser::react not enough values passed in, leaving it to the validator to complain", - ); - } - Ok(ParseResult::ValuesDone) - } - #[allow(deprecated)] - ArgAction::StoreValue => { - if ident == Some(Identifier::Index) - && arg.is_multiple_values_set() - && matcher.contains(&arg.id) - { - // HACK: Reuse existing occurrence - } else if source == ValueSource::CommandLine { - if matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) { - // Record flag's index - self.cur_idx.set(self.cur_idx.get() + 1); - debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); - } - self.start_occurrence_of_arg(matcher, arg); - } else { - self.start_custom_arg(matcher, arg, source); - } - self.push_arg_values(arg, raw_vals, matcher)?; - if ident == Some(Identifier::Index) && arg.is_multiple_values_set() { - // HACK: Maintain existing occurrence behavior - let matched = matcher.get_mut(&arg.id).unwrap(); - #[allow(deprecated)] - matched.set_occurrences(matched.num_vals() as u64); - } - if cfg!(debug_assertions) && matcher.needs_more_vals(arg) { - debug!( - "Parser::react not enough values passed in, leaving it to the validator to complain", - ); - } - Ok(ParseResult::ValuesDone) - } - #[allow(deprecated)] - ArgAction::IncOccurrence => { - debug_assert_eq!(raw_vals, Vec::::new()); - if source == ValueSource::CommandLine { - if matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) { - // Record flag's index - self.cur_idx.set(self.cur_idx.get() + 1); - debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); - } - self.start_occurrence_of_arg(matcher, arg); - } else { - self.start_custom_arg(matcher, arg, source); - } - matcher.add_index_to(&arg.id, self.cur_idx.get()); - Ok(ParseResult::ValuesDone) - } - ArgAction::SetTrue => { - let raw_vals = match raw_vals.len() { - 0 => { - vec![OsString::from("true")] - } - 1 => raw_vals, - _ => { - debug!("Parser::react ignoring trailing values: {:?}", raw_vals); - let mut raw_vals = raw_vals; - raw_vals.resize(1, Default::default()); - raw_vals - } - }; - - matcher.remove(&arg.id); - self.start_custom_arg(matcher, arg, source); - self.push_arg_values(arg, raw_vals, matcher)?; - Ok(ParseResult::ValuesDone) - } - ArgAction::SetFalse => { - let raw_vals = match raw_vals.len() { - 0 => { - vec![OsString::from("false")] - } - 1 => raw_vals, - _ => { - debug!("Parser::react ignoring trailing values: {:?}", raw_vals); - let mut raw_vals = raw_vals; - raw_vals.resize(1, Default::default()); - raw_vals - } - }; - - matcher.remove(&arg.id); - self.start_custom_arg(matcher, arg, source); - self.push_arg_values(arg, raw_vals, matcher)?; - Ok(ParseResult::ValuesDone) - } - ArgAction::Count => { - let raw_vals = match raw_vals.len() { - 0 => { - let existing_value = *matcher - .get_one::(arg.get_id()) - .unwrap_or(&0); - let next_value = existing_value.saturating_add(1); - vec![OsString::from(next_value.to_string())] - } - 1 => raw_vals, - _ => { - debug!("Parser::react ignoring trailing values: {:?}", raw_vals); - let mut raw_vals = raw_vals; - raw_vals.resize(1, Default::default()); - raw_vals - } - }; - - matcher.remove(&arg.id); - self.start_custom_arg(matcher, arg, source); - self.push_arg_values(arg, raw_vals, matcher)?; - Ok(ParseResult::ValuesDone) - } - ArgAction::Help => { - debug_assert_eq!(raw_vals, Vec::::new()); - let use_long = match ident { - Some(Identifier::Long) => true, - Some(Identifier::Short) => false, - Some(Identifier::Index) => true, - None => true, - }; - debug!("Help: use_long={}", use_long); - Err(self.help_err(use_long, Stream::Stdout)) - } - ArgAction::Version => { - debug_assert_eq!(raw_vals, Vec::::new()); - let use_long = match ident { - Some(Identifier::Long) => true, - Some(Identifier::Short) => false, - Some(Identifier::Index) => true, - None => true, - }; - debug!("Version: use_long={}", use_long); - Err(self.version_err(use_long)) - } - } - } - - fn remove_overrides(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) { - debug!("Parser::remove_overrides: id={:?}", arg.id); - for override_id in &arg.overrides { - debug!("Parser::remove_overrides:iter:{:?}: removing", override_id); - matcher.remove(override_id); - } - - // Override anything that can override us - let mut transitive = Vec::new(); - for arg_id in matcher.arg_ids() { - if let Some(overrider) = self.cmd.find(arg_id) { - if overrider.overrides.contains(&arg.id) { - transitive.push(&overrider.id); - } - } - } - for overrider_id in transitive { - debug!("Parser::remove_overrides:iter:{:?}: removing", overrider_id); - matcher.remove(overrider_id); - } - } - - #[cfg(feature = "env")] - fn add_env(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> { - debug!("Parser::add_env"); - use crate::util::str_to_bool; - - let trailing_values = false; // defaults are independent of the commandline - for arg in self.cmd.get_arguments() { - // Use env only if the arg was absent among command line args, - // early return if this is not the case. - if matcher.contains(&arg.id) { - debug!("Parser::add_env: Skipping existing arg `{}`", arg); - continue; - } - - debug!("Parser::add_env: Checking arg `{}`", arg); - if let Some((_, Some(ref val))) = arg.env { - let val = RawOsStr::new(val); - - if arg.is_takes_value_set() { - debug!( - "Parser::add_env: Found an opt with value={:?}, trailing={:?}", - val, trailing_values - ); - let mut arg_values = Vec::new(); - let _parse_result = - self.split_arg_values(arg, &val, trailing_values, &mut arg_values); - let _ = self.react(None, ValueSource::EnvVariable, arg, arg_values, matcher)?; - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!("Parser::add_env: Ignoring state {:?}; env variables are outside of the parse loop", _parse_result); - } - } - } else { - match arg.get_action() { - #[allow(deprecated)] - ArgAction::StoreValue => unreachable!("{:?} is not a flag", arg.get_id()), - #[allow(deprecated)] - ArgAction::IncOccurrence => { - debug!("Parser::add_env: Found a flag with value `{:?}`", val); - let predicate = str_to_bool(val.to_str_lossy()); - debug!("Parser::add_env: Found boolean literal `{:?}`", predicate); - if predicate.unwrap_or(true) { - let _ = self.react( - None, - ValueSource::EnvVariable, - arg, - vec![], - matcher, - )?; - } - } - ArgAction::Set - | ArgAction::Append - | ArgAction::SetTrue - | ArgAction::SetFalse - | ArgAction::Count => { - let mut arg_values = Vec::new(); - let _parse_result = - self.split_arg_values(arg, &val, trailing_values, &mut arg_values); - let _ = self.react( - None, - ValueSource::EnvVariable, - arg, - arg_values, - matcher, - )?; - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!("Parser::add_env: Ignoring state {:?}; env variables are outside of the parse loop", _parse_result); - } - } - } - // Early return on `Help` or `Version`. - ArgAction::Help | ArgAction::Version => { - let _ = - self.react(None, ValueSource::EnvVariable, arg, vec![], matcher)?; - } - } - } - } - } - - Ok(()) - } - - fn add_defaults(&self, matcher: &mut ArgMatcher) -> ClapResult<()> { - debug!("Parser::add_defaults"); - - for arg in self.cmd.get_arguments() { - debug!("Parser::add_defaults:iter:{}:", arg.name); - self.add_default_value(arg, matcher)?; - } - - Ok(()) - } - - fn add_default_value(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) -> ClapResult<()> { - let trailing_values = false; // defaults are independent of the commandline - - if !arg.default_missing_vals.is_empty() { - debug!( - "Parser::add_default_value:iter:{}: has default missing vals", - arg.name - ); - match matcher.get(&arg.id) { - Some(ma) if ma.all_val_groups_empty() => { - debug!( - "Parser::add_default_value:iter:{}: has no user defined vals", - arg.name - ); - // The flag occurred, we just want to add the val groups - let mut arg_values = Vec::new(); - for v in arg.default_missing_vals.iter() { - let _parse_result = self.split_arg_values( - arg, - &RawOsStr::new(v), - trailing_values, - &mut arg_values, - ); - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result); - } - } - } - self.start_custom_arg(matcher, arg, ValueSource::CommandLine); - self.push_arg_values(arg, arg_values, matcher)?; - } - None => { - debug!("Parser::add_default_value:iter:{}: wasn't used", arg.name); - // do nothing - } - _ => { - debug!( - "Parser::add_default_value:iter:{}: has user defined vals", - arg.name - ); - // do nothing - } - } - } else { - debug!( - "Parser::add_default_value:iter:{}: doesn't have default missing vals", - arg.name - ); - // do nothing - } - - if !arg.default_vals_ifs.is_empty() { - debug!("Parser::add_default_value: has conditional defaults"); - if !matcher.contains(&arg.id) { - for (id, val, default) in arg.default_vals_ifs.iter() { - let add = if let Some(a) = matcher.get(id) { - match val { - crate::builder::ArgPredicate::Equals(v) => { - a.raw_vals_flatten().any(|value| v == value) - } - crate::builder::ArgPredicate::IsPresent => true, - } - } else { - false - }; - - if add { - if let Some(default) = default { - let mut arg_values = Vec::new(); - let _parse_result = self.split_arg_values( - arg, - &RawOsStr::new(default), - trailing_values, - &mut arg_values, - ); - let _ = self.react( - None, - ValueSource::DefaultValue, - arg, - arg_values, - matcher, - )?; - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result); - } - } - } - return Ok(()); - } - } - } - } else { - debug!("Parser::add_default_value: doesn't have conditional defaults"); - } - - if !arg.default_vals.is_empty() { - debug!( - "Parser::add_default_value:iter:{}: has default vals", - arg.name - ); - if matcher.contains(&arg.id) { - debug!("Parser::add_default_value:iter:{}: was used", arg.name); - // do nothing - } else { - debug!("Parser::add_default_value:iter:{}: wasn't used", arg.name); - let mut arg_values = Vec::new(); - for v in arg.default_vals.iter() { - let _parse_result = self.split_arg_values( - arg, - &RawOsStr::new(v), - trailing_values, - &mut arg_values, - ); - if let Some(_parse_result) = _parse_result { - if _parse_result != ParseResult::ValuesDone { - debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result); - } - } - } - let _ = self.react(None, ValueSource::DefaultValue, arg, arg_values, matcher)?; - } - } else { - debug!( - "Parser::add_default_value:iter:{}: doesn't have default vals", - arg.name - ); - - // do nothing - } - - Ok(()) - } - - fn start_custom_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>, source: ValueSource) { - if source == ValueSource::CommandLine { - // With each new occurrence, remove overrides from prior occurrences - self.remove_overrides(arg, matcher); - } - matcher.start_custom_arg(arg, source); - for group in self.cmd.groups_for_arg(&arg.id) { - matcher.start_custom_group(&group, source); - } - } - - /// Increase occurrence of specific argument and the grouped arg it's in. - fn start_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>) { - // With each new occurrence, remove overrides from prior occurrences - self.remove_overrides(arg, matcher); - - matcher.start_occurrence_of_arg(arg); - // Increment or create the group "args" - for group in self.cmd.groups_for_arg(&arg.id) { - matcher.start_occurrence_of_group(&group); - } - } -} - -// Error, Help, and Version Methods -impl<'help, 'cmd> Parser<'help, 'cmd> { - /// Is only used for the long flag(which is the only one needs fuzzy searching) - fn did_you_mean_error( - &mut self, - arg: &str, - matcher: &mut ArgMatcher, - remaining_args: &[&str], - ) -> ClapError { - debug!("Parser::did_you_mean_error: arg={}", arg); - // Didn't match a flag or option - let longs = self - .cmd - .get_keymap() - .keys() - .filter_map(|x| match x { - KeyType::Long(l) => Some(l.to_string_lossy().into_owned()), - _ => None, - }) - .collect::>(); - debug!("Parser::did_you_mean_error: longs={:?}", longs); - - let did_you_mean = suggestions::did_you_mean_flag( - arg, - remaining_args, - longs.iter().map(|x| &x[..]), - self.cmd.get_subcommands_mut(), - ); - - // Add the arg to the matches to build a proper usage string - if let Some((name, _)) = did_you_mean.as_ref() { - if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) { - self.start_occurrence_of_arg(matcher, arg); - } - } - - let required = self.cmd.required_graph(); - let used: Vec = matcher - .arg_ids() - .filter(|arg_id| { - matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) - }) - .filter(|n| self.cmd.find(n).map_or(true, |a| !a.is_hide_set())) - .cloned() - .collect(); - - ClapError::unknown_argument( - self.cmd, - format!("--{}", arg), - did_you_mean, - Usage::new(self.cmd) - .required(&required) - .create_usage_with_title(&*used), - ) - } - - fn help_err(&self, use_long: bool, stream: Stream) -> ClapError { - match self.cmd.write_help_err(use_long, stream) { - Ok(c) => ClapError::display_help(self.cmd, c), - Err(e) => e, - } - } - - fn version_err(&self, use_long: bool) -> ClapError { - debug!("Parser::version_err"); - - let msg = self.cmd._render_version(use_long); - let mut c = Colorizer::new(Stream::Stdout, self.cmd.color_help()); - c.none(msg); - ClapError::display_version(self.cmd, c) - } -} - -// Query Methods -impl<'help, 'cmd> Parser<'help, 'cmd> { - pub(crate) fn is_set(&self, s: AS) -> bool { - self.cmd.is_set(s) - } -} - -#[derive(Debug, PartialEq, Eq)] -pub(crate) enum ParseState { - ValuesDone, - Opt(Id), - Pos(Id), -} - -/// Recoverable Parsing results. -#[derive(Debug, PartialEq, Clone)] -#[must_use] -enum ParseResult { - FlagSubCommand(String), - Opt(Id), - ValuesDone, - /// Value attached to the short flag is not consumed(e.g. 'u' for `-cu` is - /// not consumed). - AttachedValueNotConsumed, - /// This long flag doesn't need a value but is provided one. - UnneededAttachedValue { - rest: String, - used: Vec, - arg: String, - }, - /// This flag might be an hyphen Value. - MaybeHyphenValue, - /// Equals required but not provided. - EqualsNotProvided { - arg: String, - }, - /// Failed to match a Arg. - NoMatchingArg { - arg: String, - }, - /// No argument found e.g. parser is given `-` when parsing a flag. - NoArg, -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub(crate) struct PendingArg { - pub(crate) id: Id, - pub(crate) ident: Option, - pub(crate) raw_vals: Vec, -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub(crate) enum Identifier { - Short, - Long, - Index, -} diff --git a/vendor/clap/src/parser/validator.rs b/vendor/clap/src/parser/validator.rs deleted file mode 100644 index ebf2b234d..000000000 --- a/vendor/clap/src/parser/validator.rs +++ /dev/null @@ -1,692 +0,0 @@ -// Internal -use crate::builder::{AppSettings, Arg, ArgPredicate, Command, PossibleValue}; -use crate::error::{Error, Result as ClapResult}; -use crate::output::fmt::Stream; -use crate::output::Usage; -use crate::parser::{ArgMatcher, MatchedArg, ParseState}; -use crate::util::ChildGraph; -use crate::util::Id; -use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8}; - -pub(crate) struct Validator<'help, 'cmd> { - cmd: &'cmd Command<'help>, - required: ChildGraph, -} - -impl<'help, 'cmd> Validator<'help, 'cmd> { - pub(crate) fn new(cmd: &'cmd Command<'help>) -> Self { - let required = cmd.required_graph(); - Validator { cmd, required } - } - - pub(crate) fn validate( - &mut self, - parse_state: ParseState, - matcher: &mut ArgMatcher, - ) -> ClapResult<()> { - debug!("Validator::validate"); - let mut conflicts = Conflicts::new(); - let has_subcmd = matcher.subcommand_name().is_some(); - - if let ParseState::Opt(a) = parse_state { - debug!("Validator::validate: needs_val_of={:?}", a); - - let o = &self.cmd[&a]; - let should_err = if let Some(v) = matcher.args.get(&o.id) { - v.all_val_groups_empty() && !(o.min_vals.is_some() && o.min_vals.unwrap() == 0) - } else { - true - }; - if should_err { - return Err(Error::empty_value( - self.cmd, - &get_possible_values(o) - .iter() - .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) - .collect::>(), - o.to_string(), - )); - } - } - - if !has_subcmd && self.cmd.is_arg_required_else_help_set() { - let num_user_values = matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - .count(); - if num_user_values == 0 { - let message = self.cmd.write_help_err(false, Stream::Stderr)?; - return Err(Error::display_help_error(self.cmd, message)); - } - } - #[allow(deprecated)] - if !has_subcmd && self.cmd.is_subcommand_required_set() { - let bn = self - .cmd - .get_bin_name() - .unwrap_or_else(|| self.cmd.get_name()); - return Err(Error::missing_subcommand( - self.cmd, - bn.to_string(), - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )); - } else if !has_subcmd && self.cmd.is_set(AppSettings::SubcommandRequiredElseHelp) { - debug!("Validator::new::get_matches_with: SubcommandRequiredElseHelp=true"); - let message = self.cmd.write_help_err(false, Stream::Stderr)?; - return Err(Error::display_help_error(self.cmd, message)); - } - - self.validate_conflicts(matcher, &mut conflicts)?; - if !(self.cmd.is_subcommand_negates_reqs_set() && has_subcmd) { - self.validate_required(matcher, &mut conflicts)?; - } - self.validate_matched_args(matcher)?; - - Ok(()) - } - - fn validate_arg_values(&self, arg: &Arg, ma: &MatchedArg) -> ClapResult<()> { - debug!("Validator::validate_arg_values: arg={:?}", arg.name); - for val in ma.raw_vals_flatten() { - if !arg.possible_vals.is_empty() { - debug!( - "Validator::validate_arg_values: possible_vals={:?}", - arg.possible_vals - ); - let val_str = val.to_string_lossy(); - let ok = arg - .possible_vals - .iter() - .any(|pv| pv.matches(&val_str, arg.is_ignore_case_set())); - if !ok { - return Err(Error::invalid_value( - self.cmd, - val_str.into_owned(), - &arg.possible_vals - .iter() - .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) - .collect::>(), - arg.to_string(), - )); - } - } - { - #![allow(deprecated)] - if arg.is_forbid_empty_values_set() && val.is_empty() { - debug!("Validator::validate_arg_values: illegal empty val found"); - return Err(Error::empty_value( - self.cmd, - &get_possible_values(arg) - .iter() - .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) - .collect::>(), - arg.to_string(), - )); - } - } - - if let Some(ref vtor) = arg.validator { - debug!("Validator::validate_arg_values: checking validator..."); - let mut vtor = vtor.lock().unwrap(); - if let Err(e) = vtor(&*val.to_string_lossy()) { - debug!("error"); - return Err(Error::value_validation( - arg.to_string(), - val.to_string_lossy().into_owned(), - e, - ) - .with_cmd(self.cmd)); - } else { - debug!("good"); - } - } - if let Some(ref vtor) = arg.validator_os { - debug!("Validator::validate_arg_values: checking validator_os..."); - let mut vtor = vtor.lock().unwrap(); - if let Err(e) = vtor(val) { - debug!("error"); - return Err(Error::value_validation( - arg.to_string(), - val.to_string_lossy().into(), - e, - ) - .with_cmd(self.cmd)); - } else { - debug!("good"); - } - } - } - Ok(()) - } - - fn validate_conflicts( - &mut self, - matcher: &ArgMatcher, - conflicts: &mut Conflicts, - ) -> ClapResult<()> { - debug!("Validator::validate_conflicts"); - - self.validate_exclusive(matcher)?; - - for arg_id in matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - .filter(|arg_id| self.cmd.find(arg_id).is_some()) - { - debug!("Validator::validate_conflicts::iter: id={:?}", arg_id); - let conflicts = conflicts.gather_conflicts(self.cmd, matcher, arg_id); - self.build_conflict_err(arg_id, &conflicts, matcher)?; - } - - Ok(()) - } - - fn validate_exclusive(&self, matcher: &ArgMatcher) -> ClapResult<()> { - debug!("Validator::validate_exclusive"); - let args_count = matcher - .arg_ids() - .filter(|arg_id| { - matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) - }) - .count(); - if args_count <= 1 { - // Nothing present to conflict with - return Ok(()); - } - - matcher - .arg_ids() - .filter(|arg_id| { - matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) - }) - .filter_map(|name| { - debug!("Validator::validate_exclusive:iter:{:?}", name); - self.cmd - .find(name) - // Find `arg`s which are exclusive but also appear with other args. - .filter(|&arg| arg.is_exclusive_set() && args_count > 1) - }) - // Throw an error for the first conflict found. - .try_for_each(|arg| { - Err(Error::argument_conflict( - self.cmd, - arg.to_string(), - Vec::new(), - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )) - }) - } - - fn build_conflict_err( - &self, - name: &Id, - conflict_ids: &[Id], - matcher: &ArgMatcher, - ) -> ClapResult<()> { - if conflict_ids.is_empty() { - return Ok(()); - } - - debug!("Validator::build_conflict_err: name={:?}", name); - let mut seen = std::collections::HashSet::new(); - let conflicts = conflict_ids - .iter() - .flat_map(|c_id| { - if self.cmd.find_group(c_id).is_some() { - self.cmd.unroll_args_in_group(c_id) - } else { - vec![c_id.clone()] - } - }) - .filter_map(|c_id| { - seen.insert(c_id.clone()).then(|| { - let c_arg = self.cmd.find(&c_id).expect(INTERNAL_ERROR_MSG); - c_arg.to_string() - }) - }) - .collect(); - - let former_arg = self.cmd.find(name).expect(INTERNAL_ERROR_MSG); - let usg = self.build_conflict_err_usage(matcher, conflict_ids); - Err(Error::argument_conflict( - self.cmd, - former_arg.to_string(), - conflicts, - usg, - )) - } - - fn build_conflict_err_usage(&self, matcher: &ArgMatcher, conflicting_keys: &[Id]) -> String { - let used_filtered: Vec = matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - .filter(|n| { - // Filter out the args we don't want to specify. - self.cmd.find(n).map_or(true, |a| !a.is_hide_set()) - }) - .filter(|key| !conflicting_keys.contains(key)) - .cloned() - .collect(); - let required: Vec = used_filtered - .iter() - .filter_map(|key| self.cmd.find(key)) - .flat_map(|arg| arg.requires.iter().map(|item| &item.1)) - .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key)) - .chain(used_filtered.iter()) - .cloned() - .collect(); - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&required) - } - - fn gather_requires(&mut self, matcher: &ArgMatcher) { - debug!("Validator::gather_requires"); - for name in matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - { - debug!("Validator::gather_requires:iter:{:?}", name); - if let Some(arg) = self.cmd.find(name) { - let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option { - let required = matcher.check_explicit(&arg.id, *val); - required.then(|| req_arg.clone()) - }; - - for req in self.cmd.unroll_arg_requires(is_relevant, &arg.id) { - self.required.insert(req); - } - } else if let Some(g) = self.cmd.find_group(name) { - debug!("Validator::gather_requires:iter:{:?}:group", name); - for r in &g.requires { - self.required.insert(r.clone()); - } - } - } - } - - fn validate_matched_args(&self, matcher: &ArgMatcher) -> ClapResult<()> { - debug!("Validator::validate_matched_args"); - matcher.iter().try_for_each(|(name, ma)| { - debug!( - "Validator::validate_matched_args:iter:{:?}: vals={:#?}", - name, - ma.vals_flatten() - ); - if let Some(arg) = self.cmd.find(name) { - self.validate_arg_num_vals(arg, ma)?; - self.validate_arg_values(arg, ma)?; - self.validate_arg_num_occurs(arg, ma)?; - } - Ok(()) - }) - } - - fn validate_arg_num_occurs(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> { - #![allow(deprecated)] - debug!( - "Validator::validate_arg_num_occurs: {:?}={}", - a.name, - ma.get_occurrences() - ); - // Occurrence of positional argument equals to number of values rather - // than number of grouped values. - if ma.get_occurrences() > 1 && !a.is_multiple_occurrences_set() && !a.is_positional() { - // Not the first time, and we don't allow multiples - return Err(Error::unexpected_multiple_usage( - self.cmd, - a.to_string(), - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )); - } - if let Some(max_occurs) = a.max_occurs { - debug!( - "Validator::validate_arg_num_occurs: max_occurs set...{}", - max_occurs - ); - let occurs = ma.get_occurrences() as usize; - if occurs > max_occurs { - return Err(Error::too_many_occurrences( - self.cmd, - a.to_string(), - max_occurs, - occurs, - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )); - } - } - - Ok(()) - } - - fn validate_arg_num_vals(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> { - debug!("Validator::validate_arg_num_vals"); - if let Some(num) = a.num_vals { - let total_num = ma.num_vals(); - debug!("Validator::validate_arg_num_vals: num_vals set...{}", num); - #[allow(deprecated)] - let should_err = if a.is_multiple_occurrences_set() { - total_num % num != 0 - } else { - num != total_num - }; - if should_err { - debug!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues"); - return Err(Error::wrong_number_of_values( - self.cmd, - a.to_string(), - num, - #[allow(deprecated)] - if a.is_multiple_occurrences_set() { - total_num % num - } else { - total_num - }, - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )); - } - } - if let Some(num) = a.max_vals { - debug!("Validator::validate_arg_num_vals: max_vals set...{}", num); - if ma.num_vals() > num { - debug!("Validator::validate_arg_num_vals: Sending error TooManyValues"); - return Err(Error::too_many_values( - self.cmd, - ma.raw_vals_flatten() - .last() - .expect(INTERNAL_ERROR_MSG) - .to_str() - .expect(INVALID_UTF8) - .to_string(), - a.to_string(), - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )); - } - } - let min_vals_zero = if let Some(num) = a.min_vals { - debug!("Validator::validate_arg_num_vals: min_vals set: {}", num); - if ma.num_vals() < num && num != 0 { - debug!("Validator::validate_arg_num_vals: Sending error TooFewValues"); - return Err(Error::too_few_values( - self.cmd, - a.to_string(), - num, - ma.num_vals(), - Usage::new(self.cmd) - .required(&self.required) - .create_usage_with_title(&[]), - )); - } - num == 0 - } else { - false - }; - // Issue 665 (https://github.com/clap-rs/clap/issues/665) - // Issue 1105 (https://github.com/clap-rs/clap/issues/1105) - if a.is_takes_value_set() && !min_vals_zero && ma.all_val_groups_empty() { - return Err(Error::empty_value( - self.cmd, - &get_possible_values(a) - .iter() - .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) - .collect::>(), - a.to_string(), - )); - } - Ok(()) - } - - fn validate_required( - &mut self, - matcher: &ArgMatcher, - conflicts: &mut Conflicts, - ) -> ClapResult<()> { - debug!("Validator::validate_required: required={:?}", self.required); - self.gather_requires(matcher); - - let is_exclusive_present = matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - .any(|id| { - self.cmd - .find(id) - .map(|arg| arg.is_exclusive_set()) - .unwrap_or_default() - }); - debug!( - "Validator::validate_required: is_exclusive_present={}", - is_exclusive_present - ); - - for arg_or_group in self - .required - .iter() - .filter(|r| !matcher.check_explicit(r, ArgPredicate::IsPresent)) - { - debug!("Validator::validate_required:iter:aog={:?}", arg_or_group); - if let Some(arg) = self.cmd.find(arg_or_group) { - debug!("Validator::validate_required:iter: This is an arg"); - if !is_exclusive_present && !self.is_missing_required_ok(arg, matcher, conflicts) { - return self.missing_required_error(matcher, vec![]); - } - } else if let Some(group) = self.cmd.find_group(arg_or_group) { - debug!("Validator::validate_required:iter: This is a group"); - if !self - .cmd - .unroll_args_in_group(&group.id) - .iter() - .any(|a| matcher.check_explicit(a, ArgPredicate::IsPresent)) - { - return self.missing_required_error(matcher, vec![]); - } - } - } - - // Validate the conditionally required args - for a in self.cmd.get_arguments() { - for (other, val) in &a.r_ifs { - if matcher.check_explicit(other, ArgPredicate::Equals(std::ffi::OsStr::new(*val))) - && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent) - { - return self.missing_required_error(matcher, vec![a.id.clone()]); - } - } - - let match_all = a.r_ifs_all.iter().all(|(other, val)| { - matcher.check_explicit(other, ArgPredicate::Equals(std::ffi::OsStr::new(*val))) - }); - if match_all - && !a.r_ifs_all.is_empty() - && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent) - { - return self.missing_required_error(matcher, vec![a.id.clone()]); - } - } - - self.validate_required_unless(matcher)?; - - Ok(()) - } - - fn is_missing_required_ok( - &self, - a: &Arg<'help>, - matcher: &ArgMatcher, - conflicts: &mut Conflicts, - ) -> bool { - debug!("Validator::is_missing_required_ok: {}", a.name); - let conflicts = conflicts.gather_conflicts(self.cmd, matcher, &a.id); - !conflicts.is_empty() - } - - fn validate_required_unless(&self, matcher: &ArgMatcher) -> ClapResult<()> { - debug!("Validator::validate_required_unless"); - let failed_args: Vec<_> = self - .cmd - .get_arguments() - .filter(|&a| { - (!a.r_unless.is_empty() || !a.r_unless_all.is_empty()) - && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent) - && self.fails_arg_required_unless(a, matcher) - }) - .map(|a| a.id.clone()) - .collect(); - if failed_args.is_empty() { - Ok(()) - } else { - self.missing_required_error(matcher, failed_args) - } - } - - // Failing a required unless means, the arg's "unless" wasn't present, and neither were they - fn fails_arg_required_unless(&self, a: &Arg<'help>, matcher: &ArgMatcher) -> bool { - debug!("Validator::fails_arg_required_unless: a={:?}", a.name); - let exists = |id| matcher.check_explicit(id, ArgPredicate::IsPresent); - - (a.r_unless_all.is_empty() || !a.r_unless_all.iter().all(exists)) - && !a.r_unless.iter().any(exists) - } - - // `incl`: an arg to include in the error even if not used - fn missing_required_error(&self, matcher: &ArgMatcher, incl: Vec) -> ClapResult<()> { - debug!("Validator::missing_required_error; incl={:?}", incl); - debug!( - "Validator::missing_required_error: reqs={:?}", - self.required - ); - - let usg = Usage::new(self.cmd).required(&self.required); - - let req_args = usg - .get_required_usage_from(&incl, Some(matcher), true) - .into_iter() - .collect::>(); - - debug!( - "Validator::missing_required_error: req_args={:#?}", - req_args - ); - - let used: Vec = matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - .filter(|n| { - // Filter out the args we don't want to specify. - self.cmd.find(n).map_or(true, |a| !a.is_hide_set()) - }) - .cloned() - .chain(incl) - .collect(); - - Err(Error::missing_required_argument( - self.cmd, - req_args, - usg.create_usage_with_title(&used), - )) - } -} - -#[derive(Default, Clone, Debug)] -struct Conflicts { - potential: std::collections::HashMap>, -} - -impl Conflicts { - fn new() -> Self { - Self::default() - } - - fn gather_conflicts(&mut self, cmd: &Command, matcher: &ArgMatcher, arg_id: &Id) -> Vec { - debug!("Conflicts::gather_conflicts: arg={:?}", arg_id); - let mut conflicts = Vec::new(); - for other_arg_id in matcher - .arg_ids() - .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) - { - if arg_id == other_arg_id { - continue; - } - - if self - .gather_direct_conflicts(cmd, arg_id) - .contains(other_arg_id) - { - conflicts.push(other_arg_id.clone()); - } - if self - .gather_direct_conflicts(cmd, other_arg_id) - .contains(arg_id) - { - conflicts.push(other_arg_id.clone()); - } - } - debug!("Conflicts::gather_conflicts: conflicts={:?}", conflicts); - conflicts - } - - fn gather_direct_conflicts(&mut self, cmd: &Command, arg_id: &Id) -> &[Id] { - self.potential.entry(arg_id.clone()).or_insert_with(|| { - let conf = if let Some(arg) = cmd.find(arg_id) { - let mut conf = arg.blacklist.clone(); - for group_id in cmd.groups_for_arg(arg_id) { - let group = cmd.find_group(&group_id).expect(INTERNAL_ERROR_MSG); - conf.extend(group.conflicts.iter().cloned()); - if !group.multiple { - for member_id in &group.args { - if member_id != arg_id { - conf.push(member_id.clone()); - } - } - } - } - - // Overrides are implicitly conflicts - conf.extend(arg.overrides.iter().cloned()); - - conf - } else if let Some(group) = cmd.find_group(arg_id) { - group.conflicts.clone() - } else { - debug_assert!(false, "id={:?} is unknown", arg_id); - Vec::new() - }; - debug!( - "Conflicts::gather_direct_conflicts id={:?}, conflicts={:?}", - arg_id, conf - ); - conf - }) - } -} - -fn get_possible_values<'help>(a: &Arg<'help>) -> Vec> { - #![allow(deprecated)] - if !a.is_takes_value_set() { - vec![] - } else if let Some(pvs) = a.get_possible_values() { - // Check old first in case the user explicitly set possible values and the derive inferred - // a `ValueParser` with some. - pvs.to_vec() - } else { - a.get_value_parser() - .possible_values() - .map(|pvs| pvs.collect()) - .unwrap_or_default() - } -} diff --git a/vendor/clap/src/util/color.rs b/vendor/clap/src/util/color.rs deleted file mode 100644 index 15c9901a0..000000000 --- a/vendor/clap/src/util/color.rs +++ /dev/null @@ -1,62 +0,0 @@ -/// Represents the color preferences for program output -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum ColorChoice { - /// Enables colored output only when the output is going to a terminal or TTY. - /// - /// **NOTE:** This is the default behavior of `clap`. - /// - /// # Platform Specific - /// - /// This setting only applies to Unix, Linux, and macOS (i.e. non-Windows platforms). - /// - /// # Examples - /// - #[cfg_attr(not(feature = "color"), doc = " ```ignore")] - #[cfg_attr(feature = "color", doc = " ```no_run")] - /// # use clap::{Command, ColorChoice}; - /// Command::new("myprog") - /// .color(ColorChoice::Auto) - /// .get_matches(); - /// ``` - Auto, - - /// Enables colored output regardless of whether or not the output is going to a terminal/TTY. - /// - /// # Platform Specific - /// - /// This setting only applies to Unix, Linux, and macOS (i.e. non-Windows platforms). - /// - /// # Examples - /// - #[cfg_attr(not(feature = "color"), doc = " ```ignore")] - #[cfg_attr(feature = "color", doc = " ```no_run")] - /// # use clap::{Command, ColorChoice}; - /// Command::new("myprog") - /// .color(ColorChoice::Always) - /// .get_matches(); - /// ``` - Always, - - /// Disables colored output no matter if the output is going to a terminal/TTY, or not. - /// - /// # Platform Specific - /// - /// This setting only applies to Unix, Linux, and macOS (i.e. non-Windows platforms) - /// - /// # Examples - /// - #[cfg_attr(not(feature = "color"), doc = " ```ignore")] - #[cfg_attr(feature = "color", doc = " ```no_run")] - /// # use clap::{Command, ColorChoice}; - /// Command::new("myprog") - /// .color(ColorChoice::Never) - /// .get_matches(); - /// ``` - Never, -} - -impl Default for ColorChoice { - fn default() -> Self { - Self::Auto - } -} diff --git a/vendor/clap/src/util/fnv.rs b/vendor/clap/src/util/fnv.rs deleted file mode 100644 index 4602300a4..000000000 --- a/vendor/clap/src/util/fnv.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::{ - fmt::Display, - hash::{Hash, Hasher}, -}; - -const MAGIC_INIT: u64 = 0x811C_9DC5; - -// TODO: Docs -pub trait Key: Hash + Display { - fn key(&self) -> u64; -} - -impl Key for T -where - T: Hash + Display, -{ - fn key(&self) -> u64 { - let mut hasher = FnvHasher::new(); - self.hash(&mut hasher); - hasher.finish() - } -} - -pub(crate) struct FnvHasher(u64); - -impl FnvHasher { - pub(crate) fn new() -> Self { - FnvHasher(MAGIC_INIT) - } -} - -impl Hasher for FnvHasher { - fn finish(&self) -> u64 { - self.0 - } - fn write(&mut self, bytes: &[u8]) { - let FnvHasher(mut hash) = *self; - - for byte in bytes.iter() { - hash ^= u64::from(*byte); - hash = hash.wrapping_mul(0x0100_0000_01b3); - } - - *self = FnvHasher(hash); - } -} diff --git a/vendor/clap/src/util/graph.rs b/vendor/clap/src/util/graph.rs deleted file mode 100644 index d646400b0..000000000 --- a/vendor/clap/src/util/graph.rs +++ /dev/null @@ -1,49 +0,0 @@ -#[derive(Debug)] -struct Child { - id: T, - children: Vec, -} - -impl Child { - fn new(id: T) -> Self { - Child { - id, - children: vec![], - } - } -} - -#[derive(Debug)] -pub(crate) struct ChildGraph(Vec>); - -impl ChildGraph -where - T: Sized + PartialEq + Clone, -{ - pub(crate) fn with_capacity(s: usize) -> Self { - ChildGraph(Vec::with_capacity(s)) - } - - pub(crate) fn insert(&mut self, req: T) -> usize { - self.0.iter().position(|e| e.id == req).unwrap_or_else(|| { - let idx = self.0.len(); - self.0.push(Child::new(req)); - idx - }) - } - - pub(crate) fn insert_child(&mut self, parent: usize, child: T) -> usize { - let c_idx = self.0.len(); - self.0.push(Child::new(child)); - self.0[parent].children.push(c_idx); - c_idx - } - - pub(crate) fn iter(&self) -> impl Iterator { - self.0.iter().map(|r| &r.id) - } - - pub(crate) fn contains(&self, req: &T) -> bool { - self.0.iter().any(|r| r.id == *req) - } -} diff --git a/vendor/clap/src/util/id.rs b/vendor/clap/src/util/id.rs deleted file mode 100644 index 63a7e003e..000000000 --- a/vendor/clap/src/util/id.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::util::fnv::Key; - -use std::{ - fmt::{Debug, Formatter, Result}, - hash::{Hash, Hasher}, - ops::Deref, -}; - -#[derive(Clone, Eq, Default)] -#[cfg_attr(not(debug_assertions), repr(transparent))] -pub(crate) struct Id { - #[cfg(debug_assertions)] - name: String, - id: u64, -} - -macro_rules! precomputed_hashes { - ($($fn_name:ident, $const:expr, $name:expr;)*) => { - impl Id { - $( - pub(crate) fn $fn_name() -> Self { - Id { - #[cfg(debug_assertions)] - name: $name.into(), - id: $const, - } - } - )* - } - }; -} - -// precompute some common values -precomputed_hashes! { - empty_hash, 0x1C9D_3ADB_639F_298E, ""; - help_hash, 0x5963_6393_CFFB_FE5F, "help"; - version_hash, 0x30FF_0B7C_4D07_9478, "version"; -} - -impl Id { - pub(crate) fn from_ref(val: T) -> Self { - Id { - #[cfg(debug_assertions)] - name: val.to_string(), - id: val.key(), - } - } -} - -impl Debug for Id { - fn fmt(&self, f: &mut Formatter) -> Result { - #[cfg(debug_assertions)] - write!(f, "{}", self.name)?; - #[cfg(not(debug_assertions))] - write!(f, "[hash: {:X}]", self.id)?; - - Ok(()) - } -} - -impl Deref for Id { - type Target = u64; - - fn deref(&self) -> &Self::Target { - &self.id - } -} - -impl From for Id { - fn from(val: T) -> Self { - Id { - #[cfg(debug_assertions)] - name: val.to_string(), - id: val.key(), - } - } -} - -impl Hash for Id { - fn hash(&self, state: &mut H) - where - H: Hasher, - { - self.id.hash(state) - } -} - -impl PartialEq for Id { - fn eq(&self, other: &Id) -> bool { - self.id == other.id - } -} diff --git a/vendor/clap/src/util/mod.rs b/vendor/clap/src/util/mod.rs deleted file mode 100644 index 8adc8db17..000000000 --- a/vendor/clap/src/util/mod.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow(clippy::single_component_path_imports)] - -mod fnv; -mod graph; -mod id; -mod str_to_bool; - -pub use self::fnv::Key; - -pub(crate) use self::str_to_bool::str_to_bool; -pub(crate) use self::str_to_bool::FALSE_LITERALS; -pub(crate) use self::str_to_bool::TRUE_LITERALS; -pub(crate) use self::{graph::ChildGraph, id::Id}; - -pub(crate) mod color; - -pub(crate) const SUCCESS_CODE: i32 = 0; -// While sysexists.h defines EX_USAGE as 64, this doesn't seem to be used much in practice but -// instead 2 seems to be frequently used. -// Examples -// - GNU `ls` returns 2 -// - Python's `argparse` returns 2 -pub(crate) const USAGE_CODE: i32 = 2; - -pub(crate) fn safe_exit(code: i32) -> ! { - use std::io::Write; - - let _ = std::io::stdout().lock().flush(); - let _ = std::io::stderr().lock().flush(); - - std::process::exit(code) -} - -#[cfg(not(feature = "unicode"))] -pub(crate) fn eq_ignore_case(left: &str, right: &str) -> bool { - left.eq_ignore_ascii_case(right) -} - -#[cfg(feature = "unicode")] -pub(crate) use unicase::eq as eq_ignore_case; diff --git a/vendor/clap/src/util/str_to_bool.rs b/vendor/clap/src/util/str_to_bool.rs deleted file mode 100644 index 1fbdc7531..000000000 --- a/vendor/clap/src/util/str_to_bool.rs +++ /dev/null @@ -1,21 +0,0 @@ -/// True values are `y`, `yes`, `t`, `true`, `on`, and `1`. -pub(crate) const TRUE_LITERALS: [&str; 6] = ["y", "yes", "t", "true", "on", "1"]; - -/// False values are `n`, `no`, `f`, `false`, `off`, and `0`. -pub(crate) const FALSE_LITERALS: [&str; 6] = ["n", "no", "f", "false", "off", "0"]; - -/// Converts a string literal representation of truth to true or false. -/// -/// `false` values are `n`, `no`, `f`, `false`, `off`, and `0` (case insensitive). -/// -/// Any other value will be considered as `true`. -pub(crate) fn str_to_bool(val: impl AsRef) -> Option { - let pat: &str = &val.as_ref().to_lowercase(); - if TRUE_LITERALS.contains(&pat) { - Some(true) - } else if FALSE_LITERALS.contains(&pat) { - Some(false) - } else { - None - } -} diff --git a/vendor/clap_lex-0.2.2/.cargo-checksum.json b/vendor/clap_lex-0.2.2/.cargo-checksum.json new file mode 100644 index 000000000..d1fc5c2fe --- /dev/null +++ b/vendor/clap_lex-0.2.2/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"8141410d44a74e1783beeec03f35ac2b89ead0f2d0e0fb6ddc71dcc064749a89","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"b68af9a7bf1ad292ee5cfccb123dc639c5c1ad9b57645e533209965c394bf05d","src/lib.rs":"d78b54dc0fe6bd1a3a0ae764d31616a83b1a3b596ec75ad8f182c119c8c30b74"},"package":"5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"} \ No newline at end of file diff --git a/vendor/clap_lex-0.2.2/Cargo.toml b/vendor/clap_lex-0.2.2/Cargo.toml new file mode 100644 index 000000000..b089dcde8 --- /dev/null +++ b/vendor/clap_lex-0.2.2/Cargo.toml @@ -0,0 +1,89 @@ +# 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 = "2021" +rust-version = "1.56.0" +name = "clap_lex" +version = "0.2.2" +include = [ + "build.rs", + "src/**/*", + "Cargo.toml", + "LICENSE*", + "README.md", + "benches/**/*", + "examples/**/*", +] +description = "Minimal, flexible command line parser" +documentation = "https://docs.rs/clap_lex" +readme = "README.md" +keywords = [ + "argument", + "cli", + "arg", + "parser", + "parse", +] +categories = ["command-line-interface"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/clap-rs/clap/tree/master/clap_lex" +resolver = "2" + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "Unreleased" +replace = "{{version}}" +min = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = '\.\.\.HEAD' +replace = "...{{tag_name}}" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "ReleaseDate" +replace = "{{date}}" +min = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "" +replace = """ + +## [Unreleased] - ReleaseDate +""" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "" +replace = """ + +[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD""" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "README.md" +search = "github.com/clap-rs/clap/blob/[^/]+/" +replace = "github.com/clap-rs/clap/blob/{{tag_name}}/" +exactly = 4 +prerelease = true + +[lib] +bench = false + +[dependencies.os_str_bytes] +version = "6.0" +features = ["raw_os_str"] +default-features = false diff --git a/vendor/clap_lex-0.2.2/LICENSE-APACHE b/vendor/clap_lex-0.2.2/LICENSE-APACHE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/clap_lex-0.2.2/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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 [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/clap_lex-0.2.2/LICENSE-MIT b/vendor/clap_lex-0.2.2/LICENSE-MIT new file mode 100644 index 000000000..5acedf041 --- /dev/null +++ b/vendor/clap_lex-0.2.2/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2016 Kevin B. Knapp + +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. diff --git a/vendor/clap_lex-0.2.2/README.md b/vendor/clap_lex-0.2.2/README.md new file mode 100644 index 000000000..0c21bc819 --- /dev/null +++ b/vendor/clap_lex-0.2.2/README.md @@ -0,0 +1,19 @@ + +# clap_lex + +> **Minimal, flexible command line parser** + +[![Crates.io](https://img.shields.io/crates/v/clap_lex?style=flat-square)](https://crates.io/crates/clap_lex) +[![Crates.io](https://img.shields.io/crates/d/clap_lex?style=flat-square)](https://crates.io/crates/clap_lex) +[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/LICENSE-APACHE) +[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/LICENSE-MIT) + +Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). + +1. [About](#about) +2. [API Reference](https://docs.rs/clap_lex) +3. [Questions & Discussions](https://github.com/clap-rs/clap/discussions) +4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/clap_lex/CONTRIBUTING.md) +5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/README.md#sponsors) + +## About diff --git a/vendor/clap_lex-0.2.2/src/lib.rs b/vendor/clap_lex-0.2.2/src/lib.rs new file mode 100644 index 000000000..f205c3de0 --- /dev/null +++ b/vendor/clap_lex-0.2.2/src/lib.rs @@ -0,0 +1,484 @@ +//! Minimal, flexible command-line parser +//! +//! As opposed to a declarative parser, this processes arguments as a stream of tokens. As lexing +//! a command-line is not context-free, we rely on the caller to decide how to interpret the +//! arguments. +//! +//! # Examples +//! +//! ```rust +//! # use std::path::PathBuf; +//! # type BoxedError = Box; +//! #[derive(Debug)] +//! struct Args { +//! paths: Vec, +//! color: Color, +//! verbosity: usize, +//! } +//! +//! #[derive(Debug)] +//! enum Color { +//! Always, +//! Auto, +//! Never, +//! } +//! +//! impl Color { +//! fn parse(s: Option<&clap_lex::RawOsStr>) -> Result { +//! let s = s.map(|s| s.to_str().ok_or(s)); +//! match s { +//! Some(Ok("always")) | Some(Ok("")) | None => { +//! Ok(Color::Always) +//! } +//! Some(Ok("auto")) => { +//! Ok(Color::Auto) +//! } +//! Some(Ok("never")) => { +//! Ok(Color::Never) +//! } +//! Some(invalid) => { +//! Err(format!("Invalid value for `--color`, {:?}", invalid).into()) +//! } +//! } +//! } +//! } +//! +//! fn parse_args( +//! raw: impl IntoIterator> +//! ) -> Result { +//! let mut args = Args { +//! paths: Vec::new(), +//! color: Color::Auto, +//! verbosity: 0, +//! }; +//! +//! let raw = clap_lex::RawArgs::new(raw); +//! let mut cursor = raw.cursor(); +//! raw.next(&mut cursor); // Skip the bin +//! while let Some(arg) = raw.next(&mut cursor) { +//! if arg.is_escape() { +//! args.paths.extend(raw.remaining(&mut cursor).map(PathBuf::from)); +//! } else if arg.is_stdio() { +//! args.paths.push(PathBuf::from("-")); +//! } else if let Some((long, value)) = arg.to_long() { +//! match long { +//! Ok("verbose") => { +//! if let Some(value) = value { +//! return Err(format!("`--verbose` does not take a value, got `{:?}`", value).into()); +//! } +//! args.verbosity += 1; +//! } +//! Ok("color") => { +//! args.color = Color::parse(value)?; +//! } +//! _ => { +//! return Err( +//! format!("Unexpected flag: --{}", arg.display()).into() +//! ); +//! } +//! } +//! } else if let Some(mut shorts) = arg.to_short() { +//! while let Some(short) = shorts.next_flag() { +//! match short { +//! Ok('v') => { +//! args.verbosity += 1; +//! } +//! Ok('c') => { +//! let value = shorts.next_value_os(); +//! args.color = Color::parse(value)?; +//! } +//! Ok(c) => { +//! return Err(format!("Unexpected flag: -{}", c).into()); +//! } +//! Err(e) => { +//! return Err(format!("Unexpected flag: -{}", e.to_str_lossy()).into()); +//! } +//! } +//! } +//! } else { +//! args.paths.push(PathBuf::from(arg.to_value_os().to_os_str().into_owned())); +//! } +//! } +//! +//! Ok(args) +//! } +//! +//! let args = parse_args(["bin", "--hello", "world"]); +//! println!("{:?}", args); +//! ``` + +use std::ffi::OsStr; +use std::ffi::OsString; + +pub use std::io::SeekFrom; + +pub use os_str_bytes::RawOsStr; +pub use os_str_bytes::RawOsString; + +/// Command-line arguments +#[derive(Default, Clone, Debug, PartialEq, Eq)] +pub struct RawArgs { + items: Vec, +} + +impl RawArgs { + //// Create an argument list to parse + /// + /// **NOTE:** The argument returned will be the current binary. + /// + /// # Example + /// + /// ```rust,no_run + /// # use std::path::PathBuf; + /// let raw = clap_lex::RawArgs::from_args(); + /// let mut cursor = raw.cursor(); + /// let _bin = raw.next_os(&mut cursor); + /// + /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); + /// println!("{:?}", paths); + /// ``` + pub fn from_args() -> Self { + Self::new(std::env::args_os()) + } + + //// Create an argument list to parse + /// + /// # Example + /// + /// ```rust,no_run + /// # use std::path::PathBuf; + /// let raw = clap_lex::RawArgs::new(["bin", "foo.txt"]); + /// let mut cursor = raw.cursor(); + /// let _bin = raw.next_os(&mut cursor); + /// + /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); + /// println!("{:?}", paths); + /// ``` + pub fn new(iter: impl IntoIterator>) -> Self { + let iter = iter.into_iter(); + Self::from(iter) + } + + /// Create a cursor for walking the arguments + /// + /// # Example + /// + /// ```rust,no_run + /// # use std::path::PathBuf; + /// let raw = clap_lex::RawArgs::new(["bin", "foo.txt"]); + /// let mut cursor = raw.cursor(); + /// let _bin = raw.next_os(&mut cursor); + /// + /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); + /// println!("{:?}", paths); + /// ``` + pub fn cursor(&self) -> ArgCursor { + ArgCursor::new() + } + + /// Advance the cursor, returning the next [`ParsedArg`] + pub fn next(&self, cursor: &mut ArgCursor) -> Option> { + self.next_os(cursor).map(ParsedArg::new) + } + + /// Advance the cursor, returning a raw argument value. + pub fn next_os(&self, cursor: &mut ArgCursor) -> Option<&OsStr> { + let next = self.items.get(cursor.cursor).map(|s| s.as_os_str()); + cursor.cursor = cursor.cursor.saturating_add(1); + next + } + + /// Return the next [`ParsedArg`] + pub fn peek(&self, cursor: &ArgCursor) -> Option> { + self.peek_os(cursor).map(ParsedArg::new) + } + + /// Return a raw argument value. + pub fn peek_os(&self, cursor: &ArgCursor) -> Option<&OsStr> { + self.items.get(cursor.cursor).map(|s| s.as_os_str()) + } + + /// Return all remaining raw arguments, advancing the cursor to the end + /// + /// # Example + /// + /// ```rust,no_run + /// # use std::path::PathBuf; + /// let raw = clap_lex::RawArgs::new(["bin", "foo.txt"]); + /// let mut cursor = raw.cursor(); + /// let _bin = raw.next_os(&mut cursor); + /// + /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); + /// println!("{:?}", paths); + /// ``` + pub fn remaining(&self, cursor: &mut ArgCursor) -> impl Iterator { + let remaining = self.items[cursor.cursor..].iter().map(|s| s.as_os_str()); + cursor.cursor = self.items.len(); + remaining + } + + /// Adjust the cursor's position + pub fn seek(&self, cursor: &mut ArgCursor, pos: SeekFrom) { + let pos = match pos { + SeekFrom::Start(pos) => pos, + SeekFrom::End(pos) => (self.items.len() as i64).saturating_add(pos).max(0) as u64, + SeekFrom::Current(pos) => (cursor.cursor as i64).saturating_add(pos).max(0) as u64, + }; + let pos = (pos as usize).min(self.items.len()); + cursor.cursor = pos; + } + + /// Inject arguments before the [`RawArgs::next`] + pub fn insert(&mut self, cursor: &ArgCursor, insert_items: &[&str]) { + self.items.splice( + cursor.cursor..cursor.cursor, + insert_items.iter().map(OsString::from), + ); + } + + /// Any remaining args? + pub fn is_end(&self, cursor: &ArgCursor) -> bool { + self.peek_os(cursor).is_none() + } +} + +impl From for RawArgs +where + I: Iterator, + T: Into, +{ + fn from(val: I) -> Self { + Self { + items: val.map(|x| x.into()).collect(), + } + } +} + +/// Position within [`RawArgs`] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct ArgCursor { + cursor: usize, +} + +impl ArgCursor { + fn new() -> Self { + Self { cursor: 0 } + } +} + +/// Command-line Argument +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ParsedArg<'s> { + inner: std::borrow::Cow<'s, RawOsStr>, + utf8: Option<&'s str>, +} + +impl<'s> ParsedArg<'s> { + fn new(inner: &'s OsStr) -> Self { + let utf8 = inner.to_str(); + let inner = RawOsStr::new(inner); + Self { inner, utf8 } + } + + /// Argument is length of 0 + pub fn is_empty(&self) -> bool { + self.inner.as_ref().is_empty() + } + + /// Does the argument look like a stdio argument (`-`) + pub fn is_stdio(&self) -> bool { + self.inner.as_ref() == "-" + } + + /// Does the argument look like an argument escape (`--`) + pub fn is_escape(&self) -> bool { + self.inner.as_ref() == "--" + } + + /// Does the argument look like a number + pub fn is_number(&self) -> bool { + self.to_value() + .map(|s| s.parse::().is_ok()) + .unwrap_or_default() + } + + /// Treat as a long-flag + pub fn to_long(&self) -> Option<(Result<&str, &RawOsStr>, Option<&RawOsStr>)> { + if let Some(raw) = self.utf8 { + let remainder = raw.strip_prefix("--")?; + if remainder.is_empty() { + debug_assert!(self.is_escape()); + return None; + } + + let (flag, value) = if let Some((p0, p1)) = remainder.split_once('=') { + (p0, Some(p1)) + } else { + (remainder, None) + }; + let flag = Ok(flag); + let value = value.map(RawOsStr::from_str); + Some((flag, value)) + } else { + let raw = self.inner.as_ref(); + let remainder = raw.strip_prefix("--")?; + if remainder.is_empty() { + debug_assert!(self.is_escape()); + return None; + } + + let (flag, value) = if let Some((p0, p1)) = remainder.split_once('=') { + (p0, Some(p1)) + } else { + (remainder, None) + }; + let flag = flag.to_str().ok_or(flag); + Some((flag, value)) + } + } + + /// Can treat as a long-flag + pub fn is_long(&self) -> bool { + self.inner.as_ref().starts_with("--") && !self.is_escape() + } + + /// Treat as a short-flag + pub fn to_short(&self) -> Option> { + if let Some(remainder_os) = self.inner.as_ref().strip_prefix('-') { + if remainder_os.starts_with('-') { + None + } else if remainder_os.is_empty() { + debug_assert!(self.is_stdio()); + None + } else { + let remainder = self.utf8.map(|s| &s[1..]); + Some(ShortFlags::new(remainder_os, remainder)) + } + } else { + None + } + } + + /// Can treat as a short-flag + pub fn is_short(&self) -> bool { + self.inner.as_ref().starts_with('-') + && !self.is_stdio() + && !self.inner.as_ref().starts_with("--") + } + + /// Treat as a value + /// + /// **NOTE:** May return a flag or an escape. + pub fn to_value_os(&self) -> &RawOsStr { + self.inner.as_ref() + } + + /// Treat as a value + /// + /// **NOTE:** May return a flag or an escape. + pub fn to_value(&self) -> Result<&str, &RawOsStr> { + self.utf8.ok_or_else(|| self.inner.as_ref()) + } + + /// Safely print an argument that may contain non-UTF8 content + /// + /// This may perform lossy conversion, depending on the platform. If you would like an implementation which escapes the path please use Debug instead. + pub fn display(&self) -> impl std::fmt::Display + '_ { + self.inner.to_str_lossy() + } +} + +/// Walk through short flags within a [`ParsedArg`] +#[derive(Clone, Debug)] +pub struct ShortFlags<'s> { + inner: &'s RawOsStr, + utf8_prefix: std::str::CharIndices<'s>, + invalid_suffix: Option<&'s RawOsStr>, +} + +impl<'s> ShortFlags<'s> { + fn new(inner: &'s RawOsStr, utf8: Option<&'s str>) -> Self { + let (utf8_prefix, invalid_suffix) = if let Some(utf8) = utf8 { + (utf8, None) + } else { + split_nonutf8_once(inner) + }; + let utf8_prefix = utf8_prefix.char_indices(); + Self { + inner, + utf8_prefix, + invalid_suffix, + } + } + + /// Move the iterator forward by `n` short flags + pub fn advance_by(&mut self, n: usize) -> Result<(), usize> { + for i in 0..n { + self.next().ok_or(i)?.map_err(|_| i)?; + } + Ok(()) + } + + /// No short flags left + pub fn is_empty(&self) -> bool { + self.invalid_suffix.is_none() && self.utf8_prefix.as_str().is_empty() + } + + /// Does the short flag look like a number + /// + /// Ideally call this before doing any iterator + pub fn is_number(&self) -> bool { + self.invalid_suffix.is_none() && self.utf8_prefix.as_str().parse::().is_ok() + } + + /// Advance the iterator, returning the next short flag on success + /// + /// On error, returns the invalid-UTF8 value + pub fn next_flag(&mut self) -> Option> { + if let Some((_, flag)) = self.utf8_prefix.next() { + return Some(Ok(flag)); + } + + if let Some(suffix) = self.invalid_suffix { + self.invalid_suffix = None; + return Some(Err(suffix)); + } + + None + } + + /// Advance the iterator, returning everything left as a value + pub fn next_value_os(&mut self) -> Option<&'s RawOsStr> { + if let Some((index, _)) = self.utf8_prefix.next() { + self.utf8_prefix = "".char_indices(); + self.invalid_suffix = None; + return Some(&self.inner[index..]); + } + + if let Some(suffix) = self.invalid_suffix { + self.invalid_suffix = None; + return Some(suffix); + } + + None + } +} + +impl<'s> Iterator for ShortFlags<'s> { + type Item = Result; + + fn next(&mut self) -> Option { + self.next_flag() + } +} + +fn split_nonutf8_once(b: &RawOsStr) -> (&str, Option<&RawOsStr>) { + match std::str::from_utf8(b.as_raw_bytes()) { + Ok(s) => (s, None), + Err(err) => { + let (valid, after_valid) = b.split_at(err.valid_up_to()); + let valid = std::str::from_utf8(valid.as_raw_bytes()).unwrap(); + (valid, Some(after_valid)) + } + } +} diff --git a/vendor/clap_lex/.cargo-checksum.json b/vendor/clap_lex/.cargo-checksum.json deleted file mode 100644 index d1fc5c2fe..000000000 --- a/vendor/clap_lex/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"8141410d44a74e1783beeec03f35ac2b89ead0f2d0e0fb6ddc71dcc064749a89","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"b68af9a7bf1ad292ee5cfccb123dc639c5c1ad9b57645e533209965c394bf05d","src/lib.rs":"d78b54dc0fe6bd1a3a0ae764d31616a83b1a3b596ec75ad8f182c119c8c30b74"},"package":"5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"} \ No newline at end of file diff --git a/vendor/clap_lex/Cargo.toml b/vendor/clap_lex/Cargo.toml deleted file mode 100644 index b089dcde8..000000000 --- a/vendor/clap_lex/Cargo.toml +++ /dev/null @@ -1,89 +0,0 @@ -# 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 = "2021" -rust-version = "1.56.0" -name = "clap_lex" -version = "0.2.2" -include = [ - "build.rs", - "src/**/*", - "Cargo.toml", - "LICENSE*", - "README.md", - "benches/**/*", - "examples/**/*", -] -description = "Minimal, flexible command line parser" -documentation = "https://docs.rs/clap_lex" -readme = "README.md" -keywords = [ - "argument", - "cli", - "arg", - "parser", - "parse", -] -categories = ["command-line-interface"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/clap-rs/clap/tree/master/clap_lex" -resolver = "2" - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "Unreleased" -replace = "{{version}}" -min = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = '\.\.\.HEAD' -replace = "...{{tag_name}}" -exactly = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "ReleaseDate" -replace = "{{date}}" -min = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "" -replace = """ - -## [Unreleased] - ReleaseDate -""" -exactly = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "" -replace = """ - -[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD""" -exactly = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "README.md" -search = "github.com/clap-rs/clap/blob/[^/]+/" -replace = "github.com/clap-rs/clap/blob/{{tag_name}}/" -exactly = 4 -prerelease = true - -[lib] -bench = false - -[dependencies.os_str_bytes] -version = "6.0" -features = ["raw_os_str"] -default-features = false diff --git a/vendor/clap_lex/LICENSE-APACHE b/vendor/clap_lex/LICENSE-APACHE deleted file mode 100644 index 261eeb9e9..000000000 --- a/vendor/clap_lex/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - 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 [yyyy] [name of copyright owner] - - 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. diff --git a/vendor/clap_lex/LICENSE-MIT b/vendor/clap_lex/LICENSE-MIT deleted file mode 100644 index 5acedf041..000000000 --- a/vendor/clap_lex/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2016 Kevin B. Knapp - -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. diff --git a/vendor/clap_lex/README.md b/vendor/clap_lex/README.md deleted file mode 100644 index 0c21bc819..000000000 --- a/vendor/clap_lex/README.md +++ /dev/null @@ -1,19 +0,0 @@ - -# clap_lex - -> **Minimal, flexible command line parser** - -[![Crates.io](https://img.shields.io/crates/v/clap_lex?style=flat-square)](https://crates.io/crates/clap_lex) -[![Crates.io](https://img.shields.io/crates/d/clap_lex?style=flat-square)](https://crates.io/crates/clap_lex) -[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/LICENSE-APACHE) -[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/LICENSE-MIT) - -Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). - -1. [About](#about) -2. [API Reference](https://docs.rs/clap_lex) -3. [Questions & Discussions](https://github.com/clap-rs/clap/discussions) -4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/clap_lex/CONTRIBUTING.md) -5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_lex-v0.2.2/README.md#sponsors) - -## About diff --git a/vendor/clap_lex/src/lib.rs b/vendor/clap_lex/src/lib.rs deleted file mode 100644 index f205c3de0..000000000 --- a/vendor/clap_lex/src/lib.rs +++ /dev/null @@ -1,484 +0,0 @@ -//! Minimal, flexible command-line parser -//! -//! As opposed to a declarative parser, this processes arguments as a stream of tokens. As lexing -//! a command-line is not context-free, we rely on the caller to decide how to interpret the -//! arguments. -//! -//! # Examples -//! -//! ```rust -//! # use std::path::PathBuf; -//! # type BoxedError = Box; -//! #[derive(Debug)] -//! struct Args { -//! paths: Vec, -//! color: Color, -//! verbosity: usize, -//! } -//! -//! #[derive(Debug)] -//! enum Color { -//! Always, -//! Auto, -//! Never, -//! } -//! -//! impl Color { -//! fn parse(s: Option<&clap_lex::RawOsStr>) -> Result { -//! let s = s.map(|s| s.to_str().ok_or(s)); -//! match s { -//! Some(Ok("always")) | Some(Ok("")) | None => { -//! Ok(Color::Always) -//! } -//! Some(Ok("auto")) => { -//! Ok(Color::Auto) -//! } -//! Some(Ok("never")) => { -//! Ok(Color::Never) -//! } -//! Some(invalid) => { -//! Err(format!("Invalid value for `--color`, {:?}", invalid).into()) -//! } -//! } -//! } -//! } -//! -//! fn parse_args( -//! raw: impl IntoIterator> -//! ) -> Result { -//! let mut args = Args { -//! paths: Vec::new(), -//! color: Color::Auto, -//! verbosity: 0, -//! }; -//! -//! let raw = clap_lex::RawArgs::new(raw); -//! let mut cursor = raw.cursor(); -//! raw.next(&mut cursor); // Skip the bin -//! while let Some(arg) = raw.next(&mut cursor) { -//! if arg.is_escape() { -//! args.paths.extend(raw.remaining(&mut cursor).map(PathBuf::from)); -//! } else if arg.is_stdio() { -//! args.paths.push(PathBuf::from("-")); -//! } else if let Some((long, value)) = arg.to_long() { -//! match long { -//! Ok("verbose") => { -//! if let Some(value) = value { -//! return Err(format!("`--verbose` does not take a value, got `{:?}`", value).into()); -//! } -//! args.verbosity += 1; -//! } -//! Ok("color") => { -//! args.color = Color::parse(value)?; -//! } -//! _ => { -//! return Err( -//! format!("Unexpected flag: --{}", arg.display()).into() -//! ); -//! } -//! } -//! } else if let Some(mut shorts) = arg.to_short() { -//! while let Some(short) = shorts.next_flag() { -//! match short { -//! Ok('v') => { -//! args.verbosity += 1; -//! } -//! Ok('c') => { -//! let value = shorts.next_value_os(); -//! args.color = Color::parse(value)?; -//! } -//! Ok(c) => { -//! return Err(format!("Unexpected flag: -{}", c).into()); -//! } -//! Err(e) => { -//! return Err(format!("Unexpected flag: -{}", e.to_str_lossy()).into()); -//! } -//! } -//! } -//! } else { -//! args.paths.push(PathBuf::from(arg.to_value_os().to_os_str().into_owned())); -//! } -//! } -//! -//! Ok(args) -//! } -//! -//! let args = parse_args(["bin", "--hello", "world"]); -//! println!("{:?}", args); -//! ``` - -use std::ffi::OsStr; -use std::ffi::OsString; - -pub use std::io::SeekFrom; - -pub use os_str_bytes::RawOsStr; -pub use os_str_bytes::RawOsString; - -/// Command-line arguments -#[derive(Default, Clone, Debug, PartialEq, Eq)] -pub struct RawArgs { - items: Vec, -} - -impl RawArgs { - //// Create an argument list to parse - /// - /// **NOTE:** The argument returned will be the current binary. - /// - /// # Example - /// - /// ```rust,no_run - /// # use std::path::PathBuf; - /// let raw = clap_lex::RawArgs::from_args(); - /// let mut cursor = raw.cursor(); - /// let _bin = raw.next_os(&mut cursor); - /// - /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); - /// println!("{:?}", paths); - /// ``` - pub fn from_args() -> Self { - Self::new(std::env::args_os()) - } - - //// Create an argument list to parse - /// - /// # Example - /// - /// ```rust,no_run - /// # use std::path::PathBuf; - /// let raw = clap_lex::RawArgs::new(["bin", "foo.txt"]); - /// let mut cursor = raw.cursor(); - /// let _bin = raw.next_os(&mut cursor); - /// - /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); - /// println!("{:?}", paths); - /// ``` - pub fn new(iter: impl IntoIterator>) -> Self { - let iter = iter.into_iter(); - Self::from(iter) - } - - /// Create a cursor for walking the arguments - /// - /// # Example - /// - /// ```rust,no_run - /// # use std::path::PathBuf; - /// let raw = clap_lex::RawArgs::new(["bin", "foo.txt"]); - /// let mut cursor = raw.cursor(); - /// let _bin = raw.next_os(&mut cursor); - /// - /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); - /// println!("{:?}", paths); - /// ``` - pub fn cursor(&self) -> ArgCursor { - ArgCursor::new() - } - - /// Advance the cursor, returning the next [`ParsedArg`] - pub fn next(&self, cursor: &mut ArgCursor) -> Option> { - self.next_os(cursor).map(ParsedArg::new) - } - - /// Advance the cursor, returning a raw argument value. - pub fn next_os(&self, cursor: &mut ArgCursor) -> Option<&OsStr> { - let next = self.items.get(cursor.cursor).map(|s| s.as_os_str()); - cursor.cursor = cursor.cursor.saturating_add(1); - next - } - - /// Return the next [`ParsedArg`] - pub fn peek(&self, cursor: &ArgCursor) -> Option> { - self.peek_os(cursor).map(ParsedArg::new) - } - - /// Return a raw argument value. - pub fn peek_os(&self, cursor: &ArgCursor) -> Option<&OsStr> { - self.items.get(cursor.cursor).map(|s| s.as_os_str()) - } - - /// Return all remaining raw arguments, advancing the cursor to the end - /// - /// # Example - /// - /// ```rust,no_run - /// # use std::path::PathBuf; - /// let raw = clap_lex::RawArgs::new(["bin", "foo.txt"]); - /// let mut cursor = raw.cursor(); - /// let _bin = raw.next_os(&mut cursor); - /// - /// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::>(); - /// println!("{:?}", paths); - /// ``` - pub fn remaining(&self, cursor: &mut ArgCursor) -> impl Iterator { - let remaining = self.items[cursor.cursor..].iter().map(|s| s.as_os_str()); - cursor.cursor = self.items.len(); - remaining - } - - /// Adjust the cursor's position - pub fn seek(&self, cursor: &mut ArgCursor, pos: SeekFrom) { - let pos = match pos { - SeekFrom::Start(pos) => pos, - SeekFrom::End(pos) => (self.items.len() as i64).saturating_add(pos).max(0) as u64, - SeekFrom::Current(pos) => (cursor.cursor as i64).saturating_add(pos).max(0) as u64, - }; - let pos = (pos as usize).min(self.items.len()); - cursor.cursor = pos; - } - - /// Inject arguments before the [`RawArgs::next`] - pub fn insert(&mut self, cursor: &ArgCursor, insert_items: &[&str]) { - self.items.splice( - cursor.cursor..cursor.cursor, - insert_items.iter().map(OsString::from), - ); - } - - /// Any remaining args? - pub fn is_end(&self, cursor: &ArgCursor) -> bool { - self.peek_os(cursor).is_none() - } -} - -impl From for RawArgs -where - I: Iterator, - T: Into, -{ - fn from(val: I) -> Self { - Self { - items: val.map(|x| x.into()).collect(), - } - } -} - -/// Position within [`RawArgs`] -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct ArgCursor { - cursor: usize, -} - -impl ArgCursor { - fn new() -> Self { - Self { cursor: 0 } - } -} - -/// Command-line Argument -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ParsedArg<'s> { - inner: std::borrow::Cow<'s, RawOsStr>, - utf8: Option<&'s str>, -} - -impl<'s> ParsedArg<'s> { - fn new(inner: &'s OsStr) -> Self { - let utf8 = inner.to_str(); - let inner = RawOsStr::new(inner); - Self { inner, utf8 } - } - - /// Argument is length of 0 - pub fn is_empty(&self) -> bool { - self.inner.as_ref().is_empty() - } - - /// Does the argument look like a stdio argument (`-`) - pub fn is_stdio(&self) -> bool { - self.inner.as_ref() == "-" - } - - /// Does the argument look like an argument escape (`--`) - pub fn is_escape(&self) -> bool { - self.inner.as_ref() == "--" - } - - /// Does the argument look like a number - pub fn is_number(&self) -> bool { - self.to_value() - .map(|s| s.parse::().is_ok()) - .unwrap_or_default() - } - - /// Treat as a long-flag - pub fn to_long(&self) -> Option<(Result<&str, &RawOsStr>, Option<&RawOsStr>)> { - if let Some(raw) = self.utf8 { - let remainder = raw.strip_prefix("--")?; - if remainder.is_empty() { - debug_assert!(self.is_escape()); - return None; - } - - let (flag, value) = if let Some((p0, p1)) = remainder.split_once('=') { - (p0, Some(p1)) - } else { - (remainder, None) - }; - let flag = Ok(flag); - let value = value.map(RawOsStr::from_str); - Some((flag, value)) - } else { - let raw = self.inner.as_ref(); - let remainder = raw.strip_prefix("--")?; - if remainder.is_empty() { - debug_assert!(self.is_escape()); - return None; - } - - let (flag, value) = if let Some((p0, p1)) = remainder.split_once('=') { - (p0, Some(p1)) - } else { - (remainder, None) - }; - let flag = flag.to_str().ok_or(flag); - Some((flag, value)) - } - } - - /// Can treat as a long-flag - pub fn is_long(&self) -> bool { - self.inner.as_ref().starts_with("--") && !self.is_escape() - } - - /// Treat as a short-flag - pub fn to_short(&self) -> Option> { - if let Some(remainder_os) = self.inner.as_ref().strip_prefix('-') { - if remainder_os.starts_with('-') { - None - } else if remainder_os.is_empty() { - debug_assert!(self.is_stdio()); - None - } else { - let remainder = self.utf8.map(|s| &s[1..]); - Some(ShortFlags::new(remainder_os, remainder)) - } - } else { - None - } - } - - /// Can treat as a short-flag - pub fn is_short(&self) -> bool { - self.inner.as_ref().starts_with('-') - && !self.is_stdio() - && !self.inner.as_ref().starts_with("--") - } - - /// Treat as a value - /// - /// **NOTE:** May return a flag or an escape. - pub fn to_value_os(&self) -> &RawOsStr { - self.inner.as_ref() - } - - /// Treat as a value - /// - /// **NOTE:** May return a flag or an escape. - pub fn to_value(&self) -> Result<&str, &RawOsStr> { - self.utf8.ok_or_else(|| self.inner.as_ref()) - } - - /// Safely print an argument that may contain non-UTF8 content - /// - /// This may perform lossy conversion, depending on the platform. If you would like an implementation which escapes the path please use Debug instead. - pub fn display(&self) -> impl std::fmt::Display + '_ { - self.inner.to_str_lossy() - } -} - -/// Walk through short flags within a [`ParsedArg`] -#[derive(Clone, Debug)] -pub struct ShortFlags<'s> { - inner: &'s RawOsStr, - utf8_prefix: std::str::CharIndices<'s>, - invalid_suffix: Option<&'s RawOsStr>, -} - -impl<'s> ShortFlags<'s> { - fn new(inner: &'s RawOsStr, utf8: Option<&'s str>) -> Self { - let (utf8_prefix, invalid_suffix) = if let Some(utf8) = utf8 { - (utf8, None) - } else { - split_nonutf8_once(inner) - }; - let utf8_prefix = utf8_prefix.char_indices(); - Self { - inner, - utf8_prefix, - invalid_suffix, - } - } - - /// Move the iterator forward by `n` short flags - pub fn advance_by(&mut self, n: usize) -> Result<(), usize> { - for i in 0..n { - self.next().ok_or(i)?.map_err(|_| i)?; - } - Ok(()) - } - - /// No short flags left - pub fn is_empty(&self) -> bool { - self.invalid_suffix.is_none() && self.utf8_prefix.as_str().is_empty() - } - - /// Does the short flag look like a number - /// - /// Ideally call this before doing any iterator - pub fn is_number(&self) -> bool { - self.invalid_suffix.is_none() && self.utf8_prefix.as_str().parse::().is_ok() - } - - /// Advance the iterator, returning the next short flag on success - /// - /// On error, returns the invalid-UTF8 value - pub fn next_flag(&mut self) -> Option> { - if let Some((_, flag)) = self.utf8_prefix.next() { - return Some(Ok(flag)); - } - - if let Some(suffix) = self.invalid_suffix { - self.invalid_suffix = None; - return Some(Err(suffix)); - } - - None - } - - /// Advance the iterator, returning everything left as a value - pub fn next_value_os(&mut self) -> Option<&'s RawOsStr> { - if let Some((index, _)) = self.utf8_prefix.next() { - self.utf8_prefix = "".char_indices(); - self.invalid_suffix = None; - return Some(&self.inner[index..]); - } - - if let Some(suffix) = self.invalid_suffix { - self.invalid_suffix = None; - return Some(suffix); - } - - None - } -} - -impl<'s> Iterator for ShortFlags<'s> { - type Item = Result; - - fn next(&mut self) -> Option { - self.next_flag() - } -} - -fn split_nonutf8_once(b: &RawOsStr) -> (&str, Option<&RawOsStr>) { - match std::str::from_utf8(b.as_raw_bytes()) { - Ok(s) => (s, None), - Err(err) => { - let (valid, after_valid) = b.split_at(err.valid_up_to()); - let valid = std::str::from_utf8(valid.as_raw_bytes()).unwrap(); - (valid, Some(after_valid)) - } - } -} diff --git a/vendor/compiler_builtins/.cargo-checksum.json b/vendor/compiler_builtins/.cargo-checksum.json index 3310b9b76..90052bb9e 100644 --- a/vendor/compiler_builtins/.cargo-checksum.json +++ b/vendor/compiler_builtins/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"b0b1672fdd0af3eb8158670383772f3ce12d656d1481ec46657da2e9b26b19dd","Cargo.toml":"a49915bc5e86d21f27cfecb8465fe38a8e9cef628cca9619bfd2332cba170ac7","README.md":"5eb36fbab30693dbbe9f0de54749c95bd06fd6e42013b5b9eff3c062b9fdd34f","build.rs":"0c006642fbbe9fa5372a88cbbbb0bb4b391f635b2bde0c497de10740c1458c5e","examples/intrinsics.rs":"a7aa69c17af3aa8f6edff32c214e80827d3cbe3aea386a2be42244444752d253","libm/src/math/acos.rs":"fb066ba84aba1372d706425ec14f35ff8d971756d15eeebd22ecf42a716493bb","libm/src/math/acosf.rs":"a112b82309bba1d35c4e3d6ad4d6c21ef305343d9ab601ddf4bc61d43bc9f1af","libm/src/math/acosh.rs":"99de01ded7922bb93a882ad5ad8b472b5cae0059dea0bdca2077f65e94483150","libm/src/math/acoshf.rs":"10750c4d39ef6717b20a15ef1ce43e15eb851682d2f820f7e94501adec98b9a5","libm/src/math/asin.rs":"095a1e98996daff45df0b154ca0ec35bbf31db964ee9fdda0207308cb20df441","libm/src/math/asinf.rs":"49cccb4db2881982643a4a7d5453f4f8daf527711bbb67313607a3c178856d61","libm/src/math/asinh.rs":"4dd51affa71cce34a192ad66154e248f8d1c4b40fb497f29052333e425bb740f","libm/src/math/asinhf.rs":"914bfecf449f5e2bce786aa12c056d419073c6011d41c1bab7c39ba765fa4c53","libm/src/math/atan.rs":"d4fe46e1c5739dd09997869dcfbc3c85f03c534af52e700d6c6bcf9c3fedda07","libm/src/math/atan2.rs":"2623bc8ca707d13a7092ce49adf68e9cbf4452ad1bf4a861dc40ca858606a747","libm/src/math/atan2f.rs":"dd01943e0e1f1955912e5c3ffc9467529cf64bd02ac0a6ad5ab31dbe6657f05d","libm/src/math/atanf.rs":"e41b41569474a59c970ede3538e00bda4072cf4d90040017101cc79d7dc28caa","libm/src/math/atanh.rs":"57a8fb3f0f116fa4a966ac6bc2abd5f80236ead8e79013f468bd3786921f7110","libm/src/math/atanhf.rs":"6f2e57aaec1b5fc7609cb3938b3d155f51b4237dbda530739c34a0448cd9beb9","libm/src/math/cbrt.rs":"f2c45612d2eecd93cfcdd9ebf824c754fc8f8dfd6d16862c0b9c4ccea78c2a0f","libm/src/math/cbrtf.rs":"ad0b483854aa9f17a44d36c049bf0e8ebab34c27e90b787c05f45cc230ec7d19","libm/src/math/ceil.rs":"57ba5b6e207a0ccbd34190d1aa544389ca12126be23821dfb5746497f620ce03","libm/src/math/ceilf.rs":"c922a0475a599b9ea5473e615f74700b99707cebd6927f24ea59cb2a3cb3bbc3","libm/src/math/copysign.rs":"8b6440a251f0f1509d87f18122f74d0d5c03d0b60517e89e441434a3c5d84591","libm/src/math/copysignf.rs":"87d35436d224852ada93a2e93f6730cf1a727b808dd10e7d49ab4585866e336b","libm/src/math/cos.rs":"74babdc13ede78e400c5ca1854c3e22d2e08cbdc5618aefa5bba6f9303ef65b6","libm/src/math/cosf.rs":"09c40f93c445b741e22477ceedf163ca33b6a47f973f7c9876cfba2692edb29c","libm/src/math/cosh.rs":"0d0a7cef18577f321996b8b87561963139f754ad7f2ea0a3b3883811f3f0693a","libm/src/math/coshf.rs":"be8ca8739e4cf1978425b349f941cb4838bba8c10cb559c7940b9fd4fdde21ad","libm/src/math/erf.rs":"52cc9d9d54074a692001fb2d8215cd6903b645d4291ea20482455bc7f6947726","libm/src/math/erff.rs":"d37af67007fe4e9bce994c8c9805dd8af1b0ada68a10db8d8db13424dce65d09","libm/src/math/exp.rs":"ca7405ad0d1993fffcf9aae96f9256307bed3c4916545aaebd1cf1d2df1807fa","libm/src/math/exp10.rs":"2e136c6ecedd8e57a6c31796f57fae4546fcfd8bc6be66c836f553df9c74b907","libm/src/math/exp10f.rs":"9a3ce506ec587066a355ab74e0eb69a03a214ac405718087ae9772365050b20b","libm/src/math/exp2.rs":"94a9304a2ce3bc81f6d2aefd3cde6faa30f13260d46cb13692863cdea1c9a3a1","libm/src/math/exp2f.rs":"785f2630accd35118ec07bf60273e219ed91a215b956b1552eeea5bc2a708cc8","libm/src/math/expf.rs":"ec14c18f891a9e37735ec39e6fc2e9bf674a2c2e083f22e2533b481177359c98","libm/src/math/expm1.rs":"124069f456c8ad331f265c7509d9e223b2a300e461bbfd3d6adfdcdd2ee5b8ac","libm/src/math/expm1f.rs":"18e2116d31ea8410051cc709b9d04b754b0e3ba6758ee1bf0b48749f4999b840","libm/src/math/expo2.rs":"4f4f9fecfccb43f30c2784aa7c0bb656754a52b8ab431f7d1b551c673ab133f1","libm/src/math/fabs.rs":"e6c7db39f98508098cdf64ac0c2f53866c466149a7490afb9fe22b44c4dd81b3","libm/src/math/fabsf.rs":"83a1f5f4d9ca899ba2b701d7332e18b40258b83e111db4c5d8fab2cc1be58aa3","libm/src/math/fdim.rs":"8ec091996005207297c2389ae563e1b18dbc6a9eac951de29a976c5cd7bc32a7","libm/src/math/fdimf.rs":"c7f3f2269834d55be26b6580ddc07c42531577955fa4de35bad1e2a361085614","libm/src/math/fenv.rs":"916ae11e4763588518d64dee82afb41be9d1ee38ecc0679c821d4e7e22cd3dc5","libm/src/math/floor.rs":"5050804cae173af6775c0678d6c1aafb5ca2b744bc8a2f50d9d03b95dcee1fb0","libm/src/math/floorf.rs":"c903e0c57bc60a888c513eb7a873a87a4759ba68fc791b6b931652f8ee74cc03","libm/src/math/fma.rs":"d88e01c2c2d11333dd49b61166caa036ff5f08f3a8c5973b9e3c9574bf2eb675","libm/src/math/fmaf.rs":"1db6ee0d47ddbdb441cfe167edf89b431239f5805708fd0376cf5c01349a4bd6","libm/src/math/fmax.rs":"f6c8e96a8b1a170648d2fa3513e7b6b459085d708c839869f82e305fe58fac37","libm/src/math/fmaxf.rs":"dff0025433232e8a5ec7bd54d847ccf596d762ea4e35f5c54fbaac9404d732fd","libm/src/math/fmin.rs":"95b6cb66ca0e0e22276f0bf88dbe8fb69796a69a196a7491bd4802efbcf2e298","libm/src/math/fminf.rs":"304bc839b15ea3d84e68d2af9f40524ec120d30a36a667b22fcb98a6c258f4c7","libm/src/math/fmod.rs":"a1c0550fc7df8164733d914e222ff0966a2ab886d6e75a1098f24fe0283ae227","libm/src/math/fmodf.rs":"ee51ed092c0eeb8195f35735ff725cfd46612e0d689a7c483538bd92fbe61828","libm/src/math/frexp.rs":"28af70026922a8ab979744c7ad4d8faba6079c4743b7eeb6d14c983a982fbbcc","libm/src/math/frexpf.rs":"2e2593ae8002ba420809ebfaf737ef001cdc912354be3d978a8c0cb930350d4d","libm/src/math/hypot.rs":"841131c4a0cea75bc8a86e29f3f6d0815a61fc99731c9984651ce83d3050d218","libm/src/math/hypotf.rs":"5f317323edc2eb699580fe54b074b7e570a7734d51a0a149c0b49b54470a836c","libm/src/math/ilogb.rs":"d178ad7ca3439f82d565962b143f20448e45b2e2c51357b127abaec683297e32","libm/src/math/ilogbf.rs":"00f2b1b0496e21c6a42d68aea74d7156fa2ff0a735741b9051f3ca1cf0f57586","libm/src/math/j0.rs":"9572b6396c489927d332d0e717920e61ec0618e5e9c31f7eeeec70f5e4abab06","libm/src/math/j0f.rs":"802c8254bded9b3afb6eea8b9af240038a5a4a5d811396729f69ca509e3e7d87","libm/src/math/j1.rs":"97b1af1611fa3d110c2b349ee8e4176100132ea1391b619086b47ac063b81803","libm/src/math/j1f.rs":"9c9b128752e8ea2e7d81b637ba84907ab54a545e7602c49167b313743927930b","libm/src/math/jn.rs":"847d122334e5707ad9627146cddccc082a1f2f5bcd3e5ef54399013a7007ce88","libm/src/math/jnf.rs":"4045076f7d1a1b89882ed60d4dd60a4cbbc66b85cfb90491378c8015effcc476","libm/src/math/k_cos.rs":"f34a69e44d6b8901b03b578a75972f438ab20a7b98a0903fc1903d6fde3899be","libm/src/math/k_cosf.rs":"8f7117ff21cebf8e890a5bcfd7ea858a94172f4172b79a66d53824c2cb0888b1","libm/src/math/k_expo2.rs":"eb4ca9e6a525b7ea6da868c3cb136896682cc46f8396ba2a2ebc3ae9e9ba54b0","libm/src/math/k_expo2f.rs":"d51ad5df61cb5d1258bdb90c52bfed4572bb446a9337de9c04411ed9454ae0cb","libm/src/math/k_sin.rs":"14b2aba6ca07150c92768b5a72acaf5cde6a11d6619e14896512a7ba242e289a","libm/src/math/k_sinf.rs":"2775fcc710807164e6f37a4f8da3c8143cd5f16e19ce7c31c5591522151d7a96","libm/src/math/k_tan.rs":"a72beae4ccd9631eeeb61d6365bbeecae81c8411f3120a999c515cca0d5ea5c5","libm/src/math/k_tanf.rs":"6a794be56fa4b2f60452b9bab19af01c388f174560acbf829a351378ea39495d","libm/src/math/ldexp.rs":"b647f0096e80e4d926d8dd18d294c892ee2cb1778effe2c5e1b2664ae5cb1a4e","libm/src/math/ldexpf.rs":"98743fad2cd97a7be496f40ba3157ac1438fce0d0c25d5ab90c3b8c71c3fd0ed","libm/src/math/lgamma.rs":"0edd18e4f96bfcbe8b1b5af3eeca5208cd6d2d479dfa5ad117c9dfeccecf614f","libm/src/math/lgamma_r.rs":"f44a37aeccd56559ef784ae8edf217d14ad5cc2d910f0a65e70ffc86d7dc23dd","libm/src/math/lgammaf.rs":"967845357758b868a571857ec001f9f9154001110b8e97c08b6d10586bed9c49","libm/src/math/lgammaf_r.rs":"7143016d60e11fa235d53968125e57231b1104ce52149b5e1eed39629e0d1ff0","libm/src/math/log.rs":"b5e0c5f30d9e94351488732801be3107c12b854c3f95ad37e256dd88eeca408f","libm/src/math/log10.rs":"3425ff8be001fd1646ba15e254eb6ef4bdc6ccaf0cbee27ddf1fa84e04178b90","libm/src/math/log10f.rs":"fee4f71879bc4c99259e68c0c641364901629fb29a8ebddfcc0d090102cceddd","libm/src/math/log1p.rs":"9cf400852f165e6be19b97036ae9521fb9ca857d0a9a91c117d9123221622185","libm/src/math/log1pf.rs":"2716e6d2afa271996b7c8f47fd9e4952c88f4c1fd8c07c3e8ce8c62794bf71d8","libm/src/math/log2.rs":"dbbbfbaaa8aa6a4dbefea554ea3983090a9691228b011910c751f6adca912c40","libm/src/math/log2f.rs":"92a90350d8edce21c31c285c3e620fca7c62a2366008921715945c2c73b5b79f","libm/src/math/logf.rs":"845342cffc34d3db1f5ec12d8e5b773cd5a79056e28662fcb9bcd80207596f50","libm/src/math/mod.rs":"9de65aedb36910356bc47d25b1468b40ab63faf7e319e599e478a239681bdf9c","libm/src/math/modf.rs":"d012ed5a708ef52b6d1313c22a46cadaf5764dde1220816e3df2f03a0fcc60ae","libm/src/math/modff.rs":"f8f1e4c27a85d2cdb3c8e74439d59ef64aa543b948f22c23227d02d8388d61c2","libm/src/math/nextafter.rs":"3282e7eef214a32736fb6928d490198ad394b26b402b45495115b104839eebfe","libm/src/math/nextafterf.rs":"0937dc8a8155c19842c12181e741cec1f7df1f7a00cee81fcb2475e2842761b7","libm/src/math/pow.rs":"17c38297c5bf99accd915f292b777f8716ecf328916297c8bb9dfde6fd8ce522","libm/src/math/powf.rs":"2c423a0ea57fdc4e20f3533f744c6e6288c998b4de8f2914fafaa0e78be81b04","libm/src/math/rem_pio2.rs":"3e53234977daf61c89c29c940791714aad2f676a6f38188c7d17543a2aa8806f","libm/src/math/rem_pio2_large.rs":"482f31ff4e4eacf885f6130ae26a1d59f76b382059d6c742f30e5036811d3ca8","libm/src/math/rem_pio2f.rs":"07fb48f6d5cbadfd32ce4124b2b74af98b8391a2a6f36ce2a7d32e4500cb65ac","libm/src/math/remainder.rs":"63865f4370853c476b45bb27a5c54a4072146aa4a626835ae5263871a4e7e5dc","libm/src/math/remainderf.rs":"dd3fa432dbda8f2135428198be7bd69c57f8d13df3f365b12f52bf6a82352ac4","libm/src/math/remquo.rs":"3cc0bf55069f165c4843f2c358b3a27279c01e8cdd99f9057a3f7f31f45408f2","libm/src/math/remquof.rs":"cc749e18ecb7e766b8b8eeabdbf89ac99087d3d587e71e30f690676a3d2c1f9b","libm/src/math/round.rs":"f10797ef15dd34a74e912ba8621d60bc0200c87b94308c9de3cc88d7aec4feb4","libm/src/math/roundf.rs":"27e37cfcf82373709e7debf9c0c18f7ed00ae0f5d97a214c388041f7a6996d35","libm/src/math/scalbn.rs":"b5c9d6d4177fe393cbfe1c634d75ce14b754f6cbce87c5bf979a9661491748a2","libm/src/math/scalbnf.rs":"4f198d06db1896386256fb9a5ac5b805b16b836226c18780a475cf18d7c1449c","libm/src/math/sin.rs":"bb483a2138ca779e03a191222636f0c60fd75a77a2a12f263bda4b6aa9136317","libm/src/math/sincos.rs":"1cf62a16c215e367f51078a3ba23a3f257682032a8f3c657293029a886b18d82","libm/src/math/sincosf.rs":"b0f589e6ada8215944d7784f420c6721c90387d799e349ce7676674f3c475e75","libm/src/math/sinf.rs":"dcddac1d56b084cbb8d0e019433c9c5fe2201d9b257a7dcf2f85c9a8f14b79cf","libm/src/math/sinh.rs":"d8ee4c7af883a526f36c1a6da13bb81fba9181b477e2f2538161a2bee97edc35","libm/src/math/sinhf.rs":"d06eb030ba9dbf7094df127262bfe99f149b4db49fa8ab8c15499660f1e46b26","libm/src/math/sqrt.rs":"824570a631c2542ccee68b65e3eb08fe79c037a29bbaaf54da5367e7b236124a","libm/src/math/sqrtf.rs":"4cf418d74f7751d522a642a9a8d6b86ee3472c6aaef44f0eb1bc26f4d8a90985","libm/src/math/tan.rs":"930ecedaadc60f704c2dfa4e15186f59713c1ba7d948529d215223b424827db5","libm/src/math/tanf.rs":"894156a3b107aee08461eb4e7e412fc049aa237d176ae705c6e3e2d7060d94e3","libm/src/math/tanh.rs":"f1f08eb98ed959a17370a7aaf0177be36e3764543424e78feb033ed3f5e8ec98","libm/src/math/tanhf.rs":"74027b0c672a4e64bdef6d7a3069b90caec50e1e7dbb2c12d2828f310502f41e","libm/src/math/tgamma.rs":"c889cfa49bbeb4dbb0941fe9fac3b4da7d5879dcf04a3b9bb6e56de529baf374","libm/src/math/tgammaf.rs":"0737b34777095d0e4d07fe533e8f105082dd4e8ece411bba6ae5993b45b9388c","libm/src/math/trunc.rs":"642264897cc1505e720c8cf313be81aa9fd53aae866644a2e988d01dbc77fd8a","libm/src/math/truncf.rs":"dee3607baf1af0f01deae46e429e097234c50b268eaefebbe716f19f38597900","src/arm.rs":"acf149932aa46a2755cf8cd2eb7d6ae249e46b1e10ad45ce5f924561945d1273","src/arm_linux.rs":"35a4cb7b75015543feb15b0c692da0faf0e6037d3b97a4a18067ba416eae1a70","src/float/add.rs":"3ec32ceaf470a89777b54f9cde61832fdadeade0f4894f268a949e968520bc57","src/float/cmp.rs":"79b1fdc8d5f943c4ad5ea4ad32623b18f63e17ac3852fbc64a4942228007e1fc","src/float/conv.rs":"cb9a830e0d440ed825aa897f268e4ae067204da4ffc162ba963977a4b309007f","src/float/div.rs":"bc808a5372d041b96aa603ac814165e1e7dbd690e4ab9b026d9465c1cbc2c583","src/float/extend.rs":"180b2e791c58e0526de0a798845c580ce3222c8a15c8665e6e6a4bf5cf1a34aa","src/float/mod.rs":"48d76632575789a6ecf99213b1ed38c21c86ad5a5c3fa33ccb31f77829271b79","src/float/mul.rs":"0d0c1f0c28c149ecadeafd459d3c4c9327e4cfcae2cba479957bb8010ef51a01","src/float/pow.rs":"2ada190738731eb6f24104f8fb8c4d6f03cfb16451536dbee32f2b33db0c4b19","src/float/sub.rs":"c2a87f4628f51d5d908d0f25b5d51ce0599dc559d5a72b20e131261f484d5848","src/float/trunc.rs":"d21d2a2f9a1918b4bbb594691e397972a7c04b74b2acf04016c55693abf6d24b","src/int/addsub.rs":"7ec45ce1ba15b56a5b7129d3e5722c4db764c6545306d3fa9090983bcabd6f17","src/int/leading_zeros.rs":"ccf5e9d098c80034dcf6e38437c9a2eb670fa8043558bbfb574f2293164729a6","src/int/mod.rs":"bab1b77535ceebdebb89fd4e59e7105f8c45347bb638351a626615b24544a0b1","src/int/mul.rs":"bb48d8fd42d8f9f5fe9271d8d0f7a92dbae320bf4346e19d1071eb2093cb8ed9","src/int/sdiv.rs":"ace4cb0ec388a38834e01cab2c5bc87182d31588dfc0b1ae117c11ed0c4781cf","src/int/shift.rs":"3967c28a8d61279546e91958d64745fec63f15aee9175eb0602cc6353830da6c","src/int/specialized_div_rem/asymmetric.rs":"27f5bf70a35109f9d4e4e1ad1e8003aa17da5a1e436bf3e63a493d7528a3a566","src/int/specialized_div_rem/binary_long.rs":"9f1ced81a394f000a21a329683144d68ee431a954136a3634eb55b1ee2cf6d51","src/int/specialized_div_rem/delegate.rs":"9df141af98e391361e25d71ae38d5e845a91d896edd2c041132fd46af8268e85","src/int/specialized_div_rem/mod.rs":"c32a7c416f2c81d6368720053864c3e7082417bca983c329520a8e7dc8c34736","src/int/specialized_div_rem/norm_shift.rs":"3be7ee0dea545c1f702d9daf67dad2b624bf7b17b075c8b90d3d3f7b53df4c21","src/int/specialized_div_rem/trifecta.rs":"87eef69da255b809fd710b14f2eb3f9f59e3dac625f8564ebc8ba78f9763523b","src/int/udiv.rs":"3732b490a472505411577f008b92f489287745968ce6791665201201377d3475","src/lib.rs":"d0e85291d12a57c61791257e3adefb8f2222e1ba6f9e5cd4cf7fba59d26477f4","src/macros.rs":"a3261b40b1db041fb779b32bfc2bf3cba7a7c85f10fd02997163b3396658a3d7","src/math.rs":"ac6063d7c8927e3b8fe6e41acf83261db2a57e02f7c5a30bc52dbb03c0df9c72","src/mem/impls.rs":"a8d1c28a77d9b334872abbebfcba3fd1802175bef53c0b545e85242860698780","src/mem/mod.rs":"5034543d963149c14a6823bee32a1fb9dfd950c32153d37f97e9df1dc6c23129","src/mem/x86_64.rs":"9f740891f666acf384159128eef233d9e15c6120da8016370c6f9f05cc29d653","src/probestack.rs":"ef5c07e9b95de7b2b77a937789fcfefd9846274317489ad6d623e377c9888601","src/riscv.rs":"8aa8cde1106a179e9a37724193bc5cea5defe212eb38e3049c23b254578f78d4","src/x86.rs":"117b50d6725ee0af0a7b3d197ea580655561f66a870ebc450d96af22bf7f39f6","src/x86_64.rs":"4f16bc9fad7757d48a6da3a078c715dd3a22154aadb4f1998d4c1b5d91396f9e"},"package":"4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"} \ No newline at end of file +{"files":{"Cargo.lock":"d76ea6435a58ea3155de70652b8c03e08e0c96645dcf7e2f8f3650c06cb699e2","Cargo.toml":"97342c77c2e481ff977fafc2a84d7c729f26e08dee2cf1d00b6be8ddad303797","LICENSE.txt":"0e13fed90654e0bc677d624a2d770833a09541fe0c0bdb3d051b3d081207393a","README.md":"5eb36fbab30693dbbe9f0de54749c95bd06fd6e42013b5b9eff3c062b9fdd34f","build.rs":"0c006642fbbe9fa5372a88cbbbb0bb4b391f635b2bde0c497de10740c1458c5e","examples/intrinsics.rs":"a7aa69c17af3aa8f6edff32c214e80827d3cbe3aea386a2be42244444752d253","libm/src/math/acos.rs":"fb066ba84aba1372d706425ec14f35ff8d971756d15eeebd22ecf42a716493bb","libm/src/math/acosf.rs":"a112b82309bba1d35c4e3d6ad4d6c21ef305343d9ab601ddf4bc61d43bc9f1af","libm/src/math/acosh.rs":"99de01ded7922bb93a882ad5ad8b472b5cae0059dea0bdca2077f65e94483150","libm/src/math/acoshf.rs":"10750c4d39ef6717b20a15ef1ce43e15eb851682d2f820f7e94501adec98b9a5","libm/src/math/asin.rs":"095a1e98996daff45df0b154ca0ec35bbf31db964ee9fdda0207308cb20df441","libm/src/math/asinf.rs":"49cccb4db2881982643a4a7d5453f4f8daf527711bbb67313607a3c178856d61","libm/src/math/asinh.rs":"4dd51affa71cce34a192ad66154e248f8d1c4b40fb497f29052333e425bb740f","libm/src/math/asinhf.rs":"914bfecf449f5e2bce786aa12c056d419073c6011d41c1bab7c39ba765fa4c53","libm/src/math/atan.rs":"d4fe46e1c5739dd09997869dcfbc3c85f03c534af52e700d6c6bcf9c3fedda07","libm/src/math/atan2.rs":"2623bc8ca707d13a7092ce49adf68e9cbf4452ad1bf4a861dc40ca858606a747","libm/src/math/atan2f.rs":"dd01943e0e1f1955912e5c3ffc9467529cf64bd02ac0a6ad5ab31dbe6657f05d","libm/src/math/atanf.rs":"e41b41569474a59c970ede3538e00bda4072cf4d90040017101cc79d7dc28caa","libm/src/math/atanh.rs":"57a8fb3f0f116fa4a966ac6bc2abd5f80236ead8e79013f468bd3786921f7110","libm/src/math/atanhf.rs":"6f2e57aaec1b5fc7609cb3938b3d155f51b4237dbda530739c34a0448cd9beb9","libm/src/math/cbrt.rs":"f2c45612d2eecd93cfcdd9ebf824c754fc8f8dfd6d16862c0b9c4ccea78c2a0f","libm/src/math/cbrtf.rs":"ad0b483854aa9f17a44d36c049bf0e8ebab34c27e90b787c05f45cc230ec7d19","libm/src/math/ceil.rs":"57ba5b6e207a0ccbd34190d1aa544389ca12126be23821dfb5746497f620ce03","libm/src/math/ceilf.rs":"c922a0475a599b9ea5473e615f74700b99707cebd6927f24ea59cb2a3cb3bbc3","libm/src/math/copysign.rs":"8b6440a251f0f1509d87f18122f74d0d5c03d0b60517e89e441434a3c5d84591","libm/src/math/copysignf.rs":"87d35436d224852ada93a2e93f6730cf1a727b808dd10e7d49ab4585866e336b","libm/src/math/cos.rs":"74babdc13ede78e400c5ca1854c3e22d2e08cbdc5618aefa5bba6f9303ef65b6","libm/src/math/cosf.rs":"09c40f93c445b741e22477ceedf163ca33b6a47f973f7c9876cfba2692edb29c","libm/src/math/cosh.rs":"0d0a7cef18577f321996b8b87561963139f754ad7f2ea0a3b3883811f3f0693a","libm/src/math/coshf.rs":"be8ca8739e4cf1978425b349f941cb4838bba8c10cb559c7940b9fd4fdde21ad","libm/src/math/erf.rs":"52cc9d9d54074a692001fb2d8215cd6903b645d4291ea20482455bc7f6947726","libm/src/math/erff.rs":"d37af67007fe4e9bce994c8c9805dd8af1b0ada68a10db8d8db13424dce65d09","libm/src/math/exp.rs":"ca7405ad0d1993fffcf9aae96f9256307bed3c4916545aaebd1cf1d2df1807fa","libm/src/math/exp10.rs":"2e136c6ecedd8e57a6c31796f57fae4546fcfd8bc6be66c836f553df9c74b907","libm/src/math/exp10f.rs":"9a3ce506ec587066a355ab74e0eb69a03a214ac405718087ae9772365050b20b","libm/src/math/exp2.rs":"94a9304a2ce3bc81f6d2aefd3cde6faa30f13260d46cb13692863cdea1c9a3a1","libm/src/math/exp2f.rs":"785f2630accd35118ec07bf60273e219ed91a215b956b1552eeea5bc2a708cc8","libm/src/math/expf.rs":"ec14c18f891a9e37735ec39e6fc2e9bf674a2c2e083f22e2533b481177359c98","libm/src/math/expm1.rs":"124069f456c8ad331f265c7509d9e223b2a300e461bbfd3d6adfdcdd2ee5b8ac","libm/src/math/expm1f.rs":"18e2116d31ea8410051cc709b9d04b754b0e3ba6758ee1bf0b48749f4999b840","libm/src/math/expo2.rs":"4f4f9fecfccb43f30c2784aa7c0bb656754a52b8ab431f7d1b551c673ab133f1","libm/src/math/fabs.rs":"e6c7db39f98508098cdf64ac0c2f53866c466149a7490afb9fe22b44c4dd81b3","libm/src/math/fabsf.rs":"83a1f5f4d9ca899ba2b701d7332e18b40258b83e111db4c5d8fab2cc1be58aa3","libm/src/math/fdim.rs":"8ec091996005207297c2389ae563e1b18dbc6a9eac951de29a976c5cd7bc32a7","libm/src/math/fdimf.rs":"c7f3f2269834d55be26b6580ddc07c42531577955fa4de35bad1e2a361085614","libm/src/math/fenv.rs":"916ae11e4763588518d64dee82afb41be9d1ee38ecc0679c821d4e7e22cd3dc5","libm/src/math/floor.rs":"5050804cae173af6775c0678d6c1aafb5ca2b744bc8a2f50d9d03b95dcee1fb0","libm/src/math/floorf.rs":"c903e0c57bc60a888c513eb7a873a87a4759ba68fc791b6b931652f8ee74cc03","libm/src/math/fma.rs":"d88e01c2c2d11333dd49b61166caa036ff5f08f3a8c5973b9e3c9574bf2eb675","libm/src/math/fmaf.rs":"1db6ee0d47ddbdb441cfe167edf89b431239f5805708fd0376cf5c01349a4bd6","libm/src/math/fmax.rs":"f6c8e96a8b1a170648d2fa3513e7b6b459085d708c839869f82e305fe58fac37","libm/src/math/fmaxf.rs":"dff0025433232e8a5ec7bd54d847ccf596d762ea4e35f5c54fbaac9404d732fd","libm/src/math/fmin.rs":"95b6cb66ca0e0e22276f0bf88dbe8fb69796a69a196a7491bd4802efbcf2e298","libm/src/math/fminf.rs":"304bc839b15ea3d84e68d2af9f40524ec120d30a36a667b22fcb98a6c258f4c7","libm/src/math/fmod.rs":"a1c0550fc7df8164733d914e222ff0966a2ab886d6e75a1098f24fe0283ae227","libm/src/math/fmodf.rs":"ee51ed092c0eeb8195f35735ff725cfd46612e0d689a7c483538bd92fbe61828","libm/src/math/frexp.rs":"28af70026922a8ab979744c7ad4d8faba6079c4743b7eeb6d14c983a982fbbcc","libm/src/math/frexpf.rs":"2e2593ae8002ba420809ebfaf737ef001cdc912354be3d978a8c0cb930350d4d","libm/src/math/hypot.rs":"841131c4a0cea75bc8a86e29f3f6d0815a61fc99731c9984651ce83d3050d218","libm/src/math/hypotf.rs":"5f317323edc2eb699580fe54b074b7e570a7734d51a0a149c0b49b54470a836c","libm/src/math/ilogb.rs":"d178ad7ca3439f82d565962b143f20448e45b2e2c51357b127abaec683297e32","libm/src/math/ilogbf.rs":"00f2b1b0496e21c6a42d68aea74d7156fa2ff0a735741b9051f3ca1cf0f57586","libm/src/math/j0.rs":"9572b6396c489927d332d0e717920e61ec0618e5e9c31f7eeeec70f5e4abab06","libm/src/math/j0f.rs":"802c8254bded9b3afb6eea8b9af240038a5a4a5d811396729f69ca509e3e7d87","libm/src/math/j1.rs":"97b1af1611fa3d110c2b349ee8e4176100132ea1391b619086b47ac063b81803","libm/src/math/j1f.rs":"9c9b128752e8ea2e7d81b637ba84907ab54a545e7602c49167b313743927930b","libm/src/math/jn.rs":"847d122334e5707ad9627146cddccc082a1f2f5bcd3e5ef54399013a7007ce88","libm/src/math/jnf.rs":"4045076f7d1a1b89882ed60d4dd60a4cbbc66b85cfb90491378c8015effcc476","libm/src/math/k_cos.rs":"f34a69e44d6b8901b03b578a75972f438ab20a7b98a0903fc1903d6fde3899be","libm/src/math/k_cosf.rs":"8f7117ff21cebf8e890a5bcfd7ea858a94172f4172b79a66d53824c2cb0888b1","libm/src/math/k_expo2.rs":"eb4ca9e6a525b7ea6da868c3cb136896682cc46f8396ba2a2ebc3ae9e9ba54b0","libm/src/math/k_expo2f.rs":"d51ad5df61cb5d1258bdb90c52bfed4572bb446a9337de9c04411ed9454ae0cb","libm/src/math/k_sin.rs":"14b2aba6ca07150c92768b5a72acaf5cde6a11d6619e14896512a7ba242e289a","libm/src/math/k_sinf.rs":"2775fcc710807164e6f37a4f8da3c8143cd5f16e19ce7c31c5591522151d7a96","libm/src/math/k_tan.rs":"a72beae4ccd9631eeeb61d6365bbeecae81c8411f3120a999c515cca0d5ea5c5","libm/src/math/k_tanf.rs":"6a794be56fa4b2f60452b9bab19af01c388f174560acbf829a351378ea39495d","libm/src/math/ldexp.rs":"b647f0096e80e4d926d8dd18d294c892ee2cb1778effe2c5e1b2664ae5cb1a4e","libm/src/math/ldexpf.rs":"98743fad2cd97a7be496f40ba3157ac1438fce0d0c25d5ab90c3b8c71c3fd0ed","libm/src/math/lgamma.rs":"0edd18e4f96bfcbe8b1b5af3eeca5208cd6d2d479dfa5ad117c9dfeccecf614f","libm/src/math/lgamma_r.rs":"f44a37aeccd56559ef784ae8edf217d14ad5cc2d910f0a65e70ffc86d7dc23dd","libm/src/math/lgammaf.rs":"967845357758b868a571857ec001f9f9154001110b8e97c08b6d10586bed9c49","libm/src/math/lgammaf_r.rs":"7143016d60e11fa235d53968125e57231b1104ce52149b5e1eed39629e0d1ff0","libm/src/math/log.rs":"b5e0c5f30d9e94351488732801be3107c12b854c3f95ad37e256dd88eeca408f","libm/src/math/log10.rs":"3425ff8be001fd1646ba15e254eb6ef4bdc6ccaf0cbee27ddf1fa84e04178b90","libm/src/math/log10f.rs":"fee4f71879bc4c99259e68c0c641364901629fb29a8ebddfcc0d090102cceddd","libm/src/math/log1p.rs":"9cf400852f165e6be19b97036ae9521fb9ca857d0a9a91c117d9123221622185","libm/src/math/log1pf.rs":"2716e6d2afa271996b7c8f47fd9e4952c88f4c1fd8c07c3e8ce8c62794bf71d8","libm/src/math/log2.rs":"dbbbfbaaa8aa6a4dbefea554ea3983090a9691228b011910c751f6adca912c40","libm/src/math/log2f.rs":"92a90350d8edce21c31c285c3e620fca7c62a2366008921715945c2c73b5b79f","libm/src/math/logf.rs":"845342cffc34d3db1f5ec12d8e5b773cd5a79056e28662fcb9bcd80207596f50","libm/src/math/mod.rs":"9de65aedb36910356bc47d25b1468b40ab63faf7e319e599e478a239681bdf9c","libm/src/math/modf.rs":"d012ed5a708ef52b6d1313c22a46cadaf5764dde1220816e3df2f03a0fcc60ae","libm/src/math/modff.rs":"f8f1e4c27a85d2cdb3c8e74439d59ef64aa543b948f22c23227d02d8388d61c2","libm/src/math/nextafter.rs":"3282e7eef214a32736fb6928d490198ad394b26b402b45495115b104839eebfe","libm/src/math/nextafterf.rs":"0937dc8a8155c19842c12181e741cec1f7df1f7a00cee81fcb2475e2842761b7","libm/src/math/pow.rs":"17c38297c5bf99accd915f292b777f8716ecf328916297c8bb9dfde6fd8ce522","libm/src/math/powf.rs":"2c423a0ea57fdc4e20f3533f744c6e6288c998b4de8f2914fafaa0e78be81b04","libm/src/math/rem_pio2.rs":"3e53234977daf61c89c29c940791714aad2f676a6f38188c7d17543a2aa8806f","libm/src/math/rem_pio2_large.rs":"482f31ff4e4eacf885f6130ae26a1d59f76b382059d6c742f30e5036811d3ca8","libm/src/math/rem_pio2f.rs":"07fb48f6d5cbadfd32ce4124b2b74af98b8391a2a6f36ce2a7d32e4500cb65ac","libm/src/math/remainder.rs":"63865f4370853c476b45bb27a5c54a4072146aa4a626835ae5263871a4e7e5dc","libm/src/math/remainderf.rs":"dd3fa432dbda8f2135428198be7bd69c57f8d13df3f365b12f52bf6a82352ac4","libm/src/math/remquo.rs":"3cc0bf55069f165c4843f2c358b3a27279c01e8cdd99f9057a3f7f31f45408f2","libm/src/math/remquof.rs":"cc749e18ecb7e766b8b8eeabdbf89ac99087d3d587e71e30f690676a3d2c1f9b","libm/src/math/round.rs":"f10797ef15dd34a74e912ba8621d60bc0200c87b94308c9de3cc88d7aec4feb4","libm/src/math/roundf.rs":"27e37cfcf82373709e7debf9c0c18f7ed00ae0f5d97a214c388041f7a6996d35","libm/src/math/scalbn.rs":"b5c9d6d4177fe393cbfe1c634d75ce14b754f6cbce87c5bf979a9661491748a2","libm/src/math/scalbnf.rs":"4f198d06db1896386256fb9a5ac5b805b16b836226c18780a475cf18d7c1449c","libm/src/math/sin.rs":"bb483a2138ca779e03a191222636f0c60fd75a77a2a12f263bda4b6aa9136317","libm/src/math/sincos.rs":"1cf62a16c215e367f51078a3ba23a3f257682032a8f3c657293029a886b18d82","libm/src/math/sincosf.rs":"b0f589e6ada8215944d7784f420c6721c90387d799e349ce7676674f3c475e75","libm/src/math/sinf.rs":"dcddac1d56b084cbb8d0e019433c9c5fe2201d9b257a7dcf2f85c9a8f14b79cf","libm/src/math/sinh.rs":"d8ee4c7af883a526f36c1a6da13bb81fba9181b477e2f2538161a2bee97edc35","libm/src/math/sinhf.rs":"d06eb030ba9dbf7094df127262bfe99f149b4db49fa8ab8c15499660f1e46b26","libm/src/math/sqrt.rs":"824570a631c2542ccee68b65e3eb08fe79c037a29bbaaf54da5367e7b236124a","libm/src/math/sqrtf.rs":"4cf418d74f7751d522a642a9a8d6b86ee3472c6aaef44f0eb1bc26f4d8a90985","libm/src/math/tan.rs":"930ecedaadc60f704c2dfa4e15186f59713c1ba7d948529d215223b424827db5","libm/src/math/tanf.rs":"894156a3b107aee08461eb4e7e412fc049aa237d176ae705c6e3e2d7060d94e3","libm/src/math/tanh.rs":"f1f08eb98ed959a17370a7aaf0177be36e3764543424e78feb033ed3f5e8ec98","libm/src/math/tanhf.rs":"74027b0c672a4e64bdef6d7a3069b90caec50e1e7dbb2c12d2828f310502f41e","libm/src/math/tgamma.rs":"c889cfa49bbeb4dbb0941fe9fac3b4da7d5879dcf04a3b9bb6e56de529baf374","libm/src/math/tgammaf.rs":"0737b34777095d0e4d07fe533e8f105082dd4e8ece411bba6ae5993b45b9388c","libm/src/math/trunc.rs":"642264897cc1505e720c8cf313be81aa9fd53aae866644a2e988d01dbc77fd8a","libm/src/math/truncf.rs":"dee3607baf1af0f01deae46e429e097234c50b268eaefebbe716f19f38597900","src/arm.rs":"acf149932aa46a2755cf8cd2eb7d6ae249e46b1e10ad45ce5f924561945d1273","src/arm_linux.rs":"35a4cb7b75015543feb15b0c692da0faf0e6037d3b97a4a18067ba416eae1a70","src/float/add.rs":"3ec32ceaf470a89777b54f9cde61832fdadeade0f4894f268a949e968520bc57","src/float/cmp.rs":"79b1fdc8d5f943c4ad5ea4ad32623b18f63e17ac3852fbc64a4942228007e1fc","src/float/conv.rs":"e2b5e6fe398f35c7db4af62ba1fd79b39591fe1bfaf304ae825ed3c8cf902d9c","src/float/div.rs":"fe21115ecb1b3330569fd85cb51c650bf80683f152333db988d8e0d564a9ae11","src/float/extend.rs":"180b2e791c58e0526de0a798845c580ce3222c8a15c8665e6e6a4bf5cf1a34aa","src/float/mod.rs":"48d76632575789a6ecf99213b1ed38c21c86ad5a5c3fa33ccb31f77829271b79","src/float/mul.rs":"0d0c1f0c28c149ecadeafd459d3c4c9327e4cfcae2cba479957bb8010ef51a01","src/float/pow.rs":"2ada190738731eb6f24104f8fb8c4d6f03cfb16451536dbee32f2b33db0c4b19","src/float/sub.rs":"c2a87f4628f51d5d908d0f25b5d51ce0599dc559d5a72b20e131261f484d5848","src/float/trunc.rs":"d21d2a2f9a1918b4bbb594691e397972a7c04b74b2acf04016c55693abf6d24b","src/int/addsub.rs":"7ec45ce1ba15b56a5b7129d3e5722c4db764c6545306d3fa9090983bcabd6f17","src/int/leading_zeros.rs":"ccf5e9d098c80034dcf6e38437c9a2eb670fa8043558bbfb574f2293164729a6","src/int/mod.rs":"bab1b77535ceebdebb89fd4e59e7105f8c45347bb638351a626615b24544a0b1","src/int/mul.rs":"bb48d8fd42d8f9f5fe9271d8d0f7a92dbae320bf4346e19d1071eb2093cb8ed9","src/int/sdiv.rs":"ace4cb0ec388a38834e01cab2c5bc87182d31588dfc0b1ae117c11ed0c4781cf","src/int/shift.rs":"3967c28a8d61279546e91958d64745fec63f15aee9175eb0602cc6353830da6c","src/int/specialized_div_rem/asymmetric.rs":"27f5bf70a35109f9d4e4e1ad1e8003aa17da5a1e436bf3e63a493d7528a3a566","src/int/specialized_div_rem/binary_long.rs":"9f1ced81a394f000a21a329683144d68ee431a954136a3634eb55b1ee2cf6d51","src/int/specialized_div_rem/delegate.rs":"9df141af98e391361e25d71ae38d5e845a91d896edd2c041132fd46af8268e85","src/int/specialized_div_rem/mod.rs":"73c98b9f69cc9b101ae4c9081e82d66af1df4a58cf0c9bb2a8c8659265687f12","src/int/specialized_div_rem/norm_shift.rs":"3be7ee0dea545c1f702d9daf67dad2b624bf7b17b075c8b90d3d3f7b53df4c21","src/int/specialized_div_rem/trifecta.rs":"87eef69da255b809fd710b14f2eb3f9f59e3dac625f8564ebc8ba78f9763523b","src/int/udiv.rs":"3732b490a472505411577f008b92f489287745968ce6791665201201377d3475","src/lib.rs":"d0e85291d12a57c61791257e3adefb8f2222e1ba6f9e5cd4cf7fba59d26477f4","src/macros.rs":"de690dffc59a5884ed06c67d38f06c41ed02fcd6318189397a0d4aafbd375ad8","src/math.rs":"7cafdf3d65e083b31a9ceebab9510236b2c7290dbf1927f435d0f9b2d62d2a0b","src/mem/impls.rs":"a8d1c28a77d9b334872abbebfcba3fd1802175bef53c0b545e85242860698780","src/mem/mod.rs":"5034543d963149c14a6823bee32a1fb9dfd950c32153d37f97e9df1dc6c23129","src/mem/x86_64.rs":"9f740891f666acf384159128eef233d9e15c6120da8016370c6f9f05cc29d653","src/probestack.rs":"ef5c07e9b95de7b2b77a937789fcfefd9846274317489ad6d623e377c9888601","src/riscv.rs":"8aa8cde1106a179e9a37724193bc5cea5defe212eb38e3049c23b254578f78d4","src/x86.rs":"117b50d6725ee0af0a7b3d197ea580655561f66a870ebc450d96af22bf7f39f6","src/x86_64.rs":"4f16bc9fad7757d48a6da3a078c715dd3a22154aadb4f1998d4c1b5d91396f9e"},"package":"18cd7635fea7bb481ea543b392789844c1ad581299da70184c7175ce3af76603"} \ No newline at end of file diff --git a/vendor/compiler_builtins/Cargo.lock b/vendor/compiler_builtins/Cargo.lock index e60762217..a498ea0ea 100644 --- a/vendor/compiler_builtins/Cargo.lock +++ b/vendor/compiler_builtins/Cargo.lock @@ -10,7 +10,7 @@ checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "compiler_builtins" -version = "0.1.79" +version = "0.1.82" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/vendor/compiler_builtins/Cargo.toml b/vendor/compiler_builtins/Cargo.toml index eedf9a7b2..13ec182df 100644 --- a/vendor/compiler_builtins/Cargo.toml +++ b/vendor/compiler_builtins/Cargo.toml @@ -11,7 +11,7 @@ [package] name = "compiler_builtins" -version = "0.1.79" +version = "0.1.82" authors = ["Jorge Aparicio "] links = "compiler-rt" include = [ @@ -33,7 +33,6 @@ documentation = "https://docs.rs/compiler_builtins" readme = "README.md" license = "MIT/Apache-2.0" repository = "https://github.com/rust-lang/compiler-builtins" -resolver = "1" [profile.dev] panic = "abort" diff --git a/vendor/compiler_builtins/LICENSE.txt b/vendor/compiler_builtins/LICENSE.txt new file mode 100644 index 000000000..92bbe113a --- /dev/null +++ b/vendor/compiler_builtins/LICENSE.txt @@ -0,0 +1,91 @@ +============================================================================== +compiler-builtins License +============================================================================== + +The compiler-builtins crate is dual licensed under both the University of +Illinois "BSD-Like" license and the MIT license. As a user of this code you may +choose to use it under either license. As a contributor, you agree to allow +your code to be used under both. + +Full text of the relevant licenses is included below. + +============================================================================== + +University of Illinois/NCSA +Open Source License + +Copyright (c) 2009-2016 by the contributors listed in CREDITS.TXT + +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +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: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +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 +CONTRIBUTORS 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 WITH THE +SOFTWARE. + +============================================================================== + +Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT + +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. + +============================================================================== +Copyrights and Licenses for Third Party Software Distributed with LLVM: +============================================================================== +The LLVM software contains code written by third parties. Such software will +have its own individual LICENSE.TXT file in the directory in which it appears. +This file will describe the copyrights, license, and restrictions which apply +to that code. + +The disclaimer of warranty in the University of Illinois Open Source License +applies to all code in the LLVM Distribution, and nothing in any of the +other licenses gives permission to use the names of the LLVM Team or the +University of Illinois to endorse or promote products derived from this +Software. + diff --git a/vendor/compiler_builtins/src/float/conv.rs b/vendor/compiler_builtins/src/float/conv.rs index 68ba63408..19fdc2fdc 100644 --- a/vendor/compiler_builtins/src/float/conv.rs +++ b/vendor/compiler_builtins/src/float/conv.rs @@ -13,7 +13,7 @@ mod int_to_float { let a = (i << n) >> 8; // Significant bits, with bit 24 still in tact. let b = (i << n) << 24; // Insignificant bits, only relevant for rounding. let m = a + ((b - (b >> 31 & !a)) >> 31); // Add one when we need to round up. Break ties to even. - let e = 157 - n as u32; // Exponent plus 127, minus one. + let e = 157 - n; // Exponent plus 127, minus one. (e << 23) + m // + not |, so the mantissa can overflow into the exponent. } @@ -42,8 +42,8 @@ mod int_to_float { return 0; } let n = i.leading_zeros(); - let a = ((i << n) >> 11) as u64; // Significant bits, with bit 53 still in tact. - let b = ((i << n) << 53) as u64; // Insignificant bits, only relevant for rounding. + let a = (i << n) >> 11; // Significant bits, with bit 53 still in tact. + let b = (i << n) << 53; // Insignificant bits, only relevant for rounding. let m = a + ((b - (b >> 63 & !a)) >> 63); // Add one when we need to round up. Break ties to even. let e = 1085 - n as u64; // Exponent plus 1023, minus one. (e << 52) + m // + not |, so the mantissa can overflow into the exponent. diff --git a/vendor/compiler_builtins/src/float/div.rs b/vendor/compiler_builtins/src/float/div.rs index 528a8368d..c2d6c07e7 100644 --- a/vendor/compiler_builtins/src/float/div.rs +++ b/vendor/compiler_builtins/src/float/div.rs @@ -135,11 +135,11 @@ where let mut correction: u32 = negate_u32(((reciprocal as u64).wrapping_mul(q31b as u64) >> 32) as u32); - reciprocal = ((reciprocal as u64).wrapping_mul(correction as u64) as u64 >> 31) as u32; + reciprocal = ((reciprocal as u64).wrapping_mul(correction as u64) >> 31) as u32; correction = negate_u32(((reciprocal as u64).wrapping_mul(q31b as u64) >> 32) as u32); - reciprocal = ((reciprocal as u64).wrapping_mul(correction as u64) as u64 >> 31) as u32; + reciprocal = ((reciprocal as u64).wrapping_mul(correction as u64) >> 31) as u32; correction = negate_u32(((reciprocal as u64).wrapping_mul(q31b as u64) >> 32) as u32); - reciprocal = ((reciprocal as u64).wrapping_mul(correction as u64) as u64 >> 31) as u32; + reciprocal = ((reciprocal as u64).wrapping_mul(correction as u64) >> 31) as u32; // Exhaustive testing shows that the error in reciprocal after three steps // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our diff --git a/vendor/compiler_builtins/src/int/specialized_div_rem/mod.rs b/vendor/compiler_builtins/src/int/specialized_div_rem/mod.rs index 6ec4675df..77034eb54 100644 --- a/vendor/compiler_builtins/src/int/specialized_div_rem/mod.rs +++ b/vendor/compiler_builtins/src/int/specialized_div_rem/mod.rs @@ -72,7 +72,10 @@ mod asymmetric; /// impossible to reach by Rust users, unless `compiler-builtins` public division functions or /// `core/std::unchecked_div/rem` are directly used without a zero check in front. fn zero_div_fn() -> ! { - unsafe { core::hint::unreachable_unchecked() } + // Calling the intrinsic directly, to avoid the `assert_unsafe_precondition` that cannot be used + // here because it involves non-`inline` functions + // (https://github.com/rust-lang/compiler-builtins/issues/491). + unsafe { core::intrinsics::unreachable() } } const USE_LZ: bool = { diff --git a/vendor/compiler_builtins/src/macros.rs b/vendor/compiler_builtins/src/macros.rs index 7d90b7aad..477c25684 100644 --- a/vendor/compiler_builtins/src/macros.rs +++ b/vendor/compiler_builtins/src/macros.rs @@ -266,6 +266,7 @@ macro_rules! intrinsics { #[cfg(target_arch = "arm")] pub mod $alias { #[cfg_attr(not(feature = "mangled-names"), no_mangle)] + #[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")] pub extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? { super::$name($($argname),*) } diff --git a/vendor/compiler_builtins/src/math.rs b/vendor/compiler_builtins/src/math.rs index fa9836186..3fc33b127 100644 --- a/vendor/compiler_builtins/src/math.rs +++ b/vendor/compiler_builtins/src/math.rs @@ -118,8 +118,11 @@ no_mangle! { fn truncf(x: f32) -> f32; } -// only for the thumb*-none-eabi* targets -#[cfg(all(target_arch = "arm", target_os = "none"))] +// only for the thumb*-none-eabi* targets and riscv32*-none-elf targets that lack the floating point instruction set +#[cfg(any( + all(target_arch = "arm", target_os = "none"), + all(target_arch = "riscv32", not(target_feature = "f"), target_os = "none") +))] no_mangle! { fn fmin(x: f64, y: f64) -> f64; fn fminf(x: f32, y: f32) -> f32; diff --git a/vendor/compiletest_rs/.cargo-checksum.json b/vendor/compiletest_rs/.cargo-checksum.json index 8533fd089..c7ba6752d 100644 --- a/vendor/compiletest_rs/.cargo-checksum.json +++ b/vendor/compiletest_rs/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"e66bd0207f0ea860188e04376705d67a4658e78295bcaf579b2a89dbd9088d54","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"e0655e85239c6e887c0f35e1b97fb2574127ea61c28e3deec93c20b560f47892","build.rs":"905784fbb4a75c17279a88fd476e7221104adf00b4dd745a4a66bd41cac8d77a","src/common.rs":"df14f9c75c6a341c5bbc90c4b386c20f66164196f3b4b2ffc19b454d6b658e2b","src/errors.rs":"88a36d1726d90b11bf9272b1439dd52cd4fdf2e70e6e0cb6cfb323f76d84e3ff","src/header.rs":"04e405d100c46dd82139705e8b833e03d19c597edf3a5f7fee92ad9cbd12c201","src/json.rs":"e278c4c3c32c60e840a250b0979926e2ac333dcbbbaae5ab6fcf01ca05bef625","src/lib.rs":"ac780a6ad8d9eb84bd0c6bd7c56fab64a98ef29b9133f1b4fb2a845b58c839bc","src/raise_fd_limit.rs":"b0840fe16df9edaae0571499e105db47768050fcd62729d1e56295f2db34318e","src/read2.rs":"fb9caa84bec8c9c3d2c1ee39a4a6698c461fdc77aec086c74fd7738a6acf4155","src/runtest.rs":"9dc12384637275790ca5a030f79e7ea72be991ff8d5365193e48895a30db6454","src/uidiff.rs":"2f612bd4ed76d68c0f6b3eb8dda5adf14a3e6ceef261c88c810ac6b6857e2d34","src/util.rs":"9cda9e803ffe5e1b5d4c74cf7da7bd51e28a8d1b09bda3d31e01c0f648c3262d","tests/bless.rs":"29031f02666102ab8cde316b9206bf1e770275f9fa6e0172754dcad859a52b5b","tests/test_support/mod.rs":"21ec96cca07cf95b6e3333917a5158a6c47356940063f77d52503b97fd3d8b79"},"package":"262134ef87408da1ddfe45e33daa0ca43b75286d6b1076446e602d264cf9847e"} \ No newline at end of file +{"files":{"Cargo.toml":"cc0342b513ff3ec9dd349398d0a851131ce10afa5b7748997fe7b66f4c75ad32","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"043fc0e7bbad6798c80b81640db2f45cea97b2cadadf8d21e08fe89119872e07","build.rs":"905784fbb4a75c17279a88fd476e7221104adf00b4dd745a4a66bd41cac8d77a","src/common.rs":"df14f9c75c6a341c5bbc90c4b386c20f66164196f3b4b2ffc19b454d6b658e2b","src/errors.rs":"88a36d1726d90b11bf9272b1439dd52cd4fdf2e70e6e0cb6cfb323f76d84e3ff","src/header.rs":"04e405d100c46dd82139705e8b833e03d19c597edf3a5f7fee92ad9cbd12c201","src/json.rs":"e278c4c3c32c60e840a250b0979926e2ac333dcbbbaae5ab6fcf01ca05bef625","src/lib.rs":"ac780a6ad8d9eb84bd0c6bd7c56fab64a98ef29b9133f1b4fb2a845b58c839bc","src/raise_fd_limit.rs":"b0840fe16df9edaae0571499e105db47768050fcd62729d1e56295f2db34318e","src/read2.rs":"fb9caa84bec8c9c3d2c1ee39a4a6698c461fdc77aec086c74fd7738a6acf4155","src/runtest.rs":"4d0d761d8f848ceda532ecc1363d5280951656c5a9ea7eff75d91475e7fcf269","src/uidiff.rs":"2f612bd4ed76d68c0f6b3eb8dda5adf14a3e6ceef261c88c810ac6b6857e2d34","src/util.rs":"9cda9e803ffe5e1b5d4c74cf7da7bd51e28a8d1b09bda3d31e01c0f648c3262d","tests/bless.rs":"29031f02666102ab8cde316b9206bf1e770275f9fa6e0172754dcad859a52b5b","tests/test_support/mod.rs":"21ec96cca07cf95b6e3333917a5158a6c47356940063f77d52503b97fd3d8b79"},"package":"70489bbb718aea4f92e5f48f2e3b5be670c2051de30e57cb6e5377b4aa08b372"} \ No newline at end of file diff --git a/vendor/compiletest_rs/Cargo.toml b/vendor/compiletest_rs/Cargo.toml index 9403548b8..f56e4d712 100644 --- a/vendor/compiletest_rs/Cargo.toml +++ b/vendor/compiletest_rs/Cargo.toml @@ -11,7 +11,7 @@ [package] name = "compiletest_rs" -version = "0.8.0" +version = "0.9.0" authors = [ "The Rust Project Developers", "Thomas Bracht Laumann Jespersen ", diff --git a/vendor/compiletest_rs/README.md b/vendor/compiletest_rs/README.md index bf7cac194..c01a40c9b 100644 --- a/vendor/compiletest_rs/README.md +++ b/vendor/compiletest_rs/README.md @@ -14,7 +14,7 @@ To use `compiletest-rs` in your application, add the following to `Cargo.toml` ```toml [dev-dependencies] -compiletest_rs = "0.7" +compiletest_rs = "0.9" ``` By default, `compiletest-rs` should be able to run on both stable, beta and @@ -28,7 +28,7 @@ crate. ```toml [dev-dependencies] -compiletest_rs = { version = "0.7", features = [ "rustc" ] } +compiletest_rs = { version = "0.9", features = [ "rustc" ] } ``` Create a `tests` folder in the root folder of your project. Create a test file diff --git a/vendor/compiletest_rs/src/runtest.rs b/vendor/compiletest_rs/src/runtest.rs index c52551488..47f9c4870 100644 --- a/vendor/compiletest_rs/src/runtest.rs +++ b/vendor/compiletest_rs/src/runtest.rs @@ -33,9 +33,28 @@ use std::io::{self, BufReader}; use std::path::{Path, PathBuf}; use std::process::{Command, Output, ExitStatus, Stdio, Child}; use std::str; +use std::sync::{Arc, Mutex, RwLock}; use extract_gdb_version; +fn get_or_create_coverage_file(path: &Path, create: impl FnOnce() -> File) -> Arc> { + lazy_static::lazy_static! { + static ref COVERAGE_FILE_LOCKS: RwLock>>> = RwLock::new(HashMap::new()); + } + + { + let locks = COVERAGE_FILE_LOCKS.read().unwrap(); + locks.get(path).map(Arc::clone) + } + .unwrap_or_else(|| { + let mut locks = COVERAGE_FILE_LOCKS.write().unwrap(); + locks + .entry(path.to_path_buf()) + .or_insert_with(|| Arc::new(Mutex::new(create()))) + .clone() + }) +} + /// The name of the environment variable that holds dynamic library locations. pub fn dylib_env_var() -> &'static str { if cfg!(windows) { @@ -2343,16 +2362,23 @@ actual:\n\ coverage_file_path.push("rustfix_missing_coverage.txt"); debug!("coverage_file_path: {}", coverage_file_path.display()); - let mut file = OpenOptions::new() - .create(true) - .append(true) - .open(coverage_file_path.as_path()) - .expect("could not create or open file"); - - if let Err(_) = writeln!(file, "{}", self.testpaths.file.display()) { + let file_ref = get_or_create_coverage_file(&coverage_file_path, || { + OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(coverage_file_path.as_path()) + .expect("could not create or open file") + }); + let mut file = file_ref.lock().unwrap(); + + if writeln!(file, "{}", self.testpaths.file.display()) + .and_then(|_| file.sync_data()) + .is_err() + { panic!("couldn't write to {}", coverage_file_path.display()); } - } + } } if self.props.run_rustfix { @@ -2408,10 +2434,13 @@ actual:\n\ // And finally, compile the fixed code and make sure it both // succeeds and has no diagnostics. let mut rustc = self.make_compile_args( - &self.testpaths.file.with_extension(UI_FIXED), + &expected_fixed_path, TargetLocation::ThisFile(self.make_exe_name()), AllowUnused::No, ); + // Set the crate name to avoid `file.revision.fixed` inferring the + // invalid name `file.revision` + rustc.arg("--crate-name=fixed"); rustc.arg("-L").arg(&self.aux_output_dir_name()); let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { diff --git a/vendor/crossbeam-epoch/.cargo-checksum.json b/vendor/crossbeam-epoch/.cargo-checksum.json index 21e5f8500..d069e3a4b 100644 --- a/vendor/crossbeam-epoch/.cargo-checksum.json +++ b/vendor/crossbeam-epoch/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"4a701ed7814fbde912aa7a1d15c95ed6b7ba3cd661c64f92c17b3b8bf67ecf5e","Cargo.lock":"018d954edeff6a45c6af01735239b639a83eed8258176481c6e9dae366085760","Cargo.toml":"4c1451a736e2ec0b31dfe6080140b69fdc614a0606db876308f1badf932dc1b9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"d67d0cf57751a019707dd95785345ee181a10ea80237789bc3c19bf28c0d45ca","benches/defer.rs":"c330b704d96b2ad1aed29f72c37a99da534adef8cb06a3976d5f93bf567abb20","benches/flush.rs":"0389ac6c473632f0e93c962f223404cc360257f6699b4ec90b9b3be16bb6d74f","benches/pin.rs":"2f649a5153745c7930efdb32a52f9dc522f7b8cf548a251c5e2c82ee25dc3fff","build.rs":"89e236e4e22dd748720129dcd02edfc08adccf708a7f0b03e41780e5bafb39cc","examples/sanitize.rs":"a39d1635fa61e643e59192d7a63becc97ff81f03c1f4e03d38cedefb1525026a","no_atomic.rs":"916ed15218bb7b75a4e0d432430e7134efd27ca43ca8a8766e0c90e89febb602","src/atomic.rs":"1bd4275c1411852024533e8a70959dfedf72029e3253544d1fbb0cc18b6fd519","src/collector.rs":"29e5911f61510247659b0090517bd1a38d11e1ed86e35811603cb599962d9a58","src/default.rs":"9c4d3951981d47efc748674d64b22eff27ecb2e3ef16369aa423592740ce6033","src/deferred.rs":"0c87df5797212778edd3c2d5fcf0cc04e8b9ed100261ecf9522f74a90804a3d5","src/epoch.rs":"d31e66d8fe62299928e25867336d96391b26a4fe890a1cae0885dfcf36d6835b","src/guard.rs":"f4439909152d38c03b6dfb6eeba6c9f07c39962187d461c92a492c27c258670b","src/internal.rs":"ac40ce276f0ed3dfd561926b78f775592eabb90790e177edde41fe50c13b8256","src/lib.rs":"1c0765413dd66d4655e6417a69829ac5c2f4d504f66f77a87fe9c230c05e039d","src/sync/list.rs":"10aa4c59845ab9ff1d8bcb6f594b70bbe23c320fa7a2b125fdf85df88b9d61e2","src/sync/mod.rs":"cbc6334460d73761c3dea7f99ed2ccbf267d5da3bc76c812e94f85c9f4565c6a","src/sync/queue.rs":"06173b2255677d0d39178ceb49876fda2878f491e907c595eb65643dbb43c9ba","tests/loom.rs":"db772f4478966de6ec98774ca4093171dc942da635822a0d2d3257d31188cb9b"},"package":"045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"} \ No newline at end of file +{"files":{"CHANGELOG.md":"930bdf6d05b1fae72bb844f6c26e0a35cc83b810a987baaf5d279044d3b3f74d","Cargo.lock":"ce25f4d162a39d180e7369954bc512ab2ab1ab3b04f6f071cb2212bd43b3bbc3","Cargo.toml":"f2a34cbd48fff1346070f503da83c9149db91c7a098a0b486007fd6a39ba6a1b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"d67d0cf57751a019707dd95785345ee181a10ea80237789bc3c19bf28c0d45ca","benches/defer.rs":"c330b704d96b2ad1aed29f72c37a99da534adef8cb06a3976d5f93bf567abb20","benches/flush.rs":"0389ac6c473632f0e93c962f223404cc360257f6699b4ec90b9b3be16bb6d74f","benches/pin.rs":"2f649a5153745c7930efdb32a52f9dc522f7b8cf548a251c5e2c82ee25dc3fff","build.rs":"89e236e4e22dd748720129dcd02edfc08adccf708a7f0b03e41780e5bafb39cc","examples/sanitize.rs":"a39d1635fa61e643e59192d7a63becc97ff81f03c1f4e03d38cedefb1525026a","no_atomic.rs":"f58085b9d0666ccf62e0ae17fb5dae937c0a86fcc55dc0ae04ad8659e696a49c","src/atomic.rs":"1bd4275c1411852024533e8a70959dfedf72029e3253544d1fbb0cc18b6fd519","src/collector.rs":"29e5911f61510247659b0090517bd1a38d11e1ed86e35811603cb599962d9a58","src/default.rs":"62edf5e1f934eb82d8d7f010d6f25366e6851145a6f0a162372202bb63da1f3a","src/deferred.rs":"0c87df5797212778edd3c2d5fcf0cc04e8b9ed100261ecf9522f74a90804a3d5","src/epoch.rs":"d31e66d8fe62299928e25867336d96391b26a4fe890a1cae0885dfcf36d6835b","src/guard.rs":"f4439909152d38c03b6dfb6eeba6c9f07c39962187d461c92a492c27c258670b","src/internal.rs":"ac40ce276f0ed3dfd561926b78f775592eabb90790e177edde41fe50c13b8256","src/lib.rs":"a036d73230d0574011e67be11d275fe46439a1b5fc3295cb242d9179e5e0a220","src/sync/list.rs":"10aa4c59845ab9ff1d8bcb6f594b70bbe23c320fa7a2b125fdf85df88b9d61e2","src/sync/mod.rs":"326e32489d467e974c441120640a8338aa55da55c24b20276075ce9053997326","src/sync/once_lock.rs":"c03dc9c05a817e087dccf8b682f7307501542805533551da3c2bab442bc40743","src/sync/queue.rs":"06173b2255677d0d39178ceb49876fda2878f491e907c595eb65643dbb43c9ba","tests/loom.rs":"db772f4478966de6ec98774ca4093171dc942da635822a0d2d3257d31188cb9b"},"package":"f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"} \ No newline at end of file diff --git a/vendor/crossbeam-epoch/CHANGELOG.md b/vendor/crossbeam-epoch/CHANGELOG.md index b05a52dfc..3aac87b7f 100644 --- a/vendor/crossbeam-epoch/CHANGELOG.md +++ b/vendor/crossbeam-epoch/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.9.11 + +- Removes the dependency on the `once_cell` crate to restore the MSRV. (#913) +- Work around [rust-lang#98302](https://github.com/rust-lang/rust/issues/98302), which causes compile error on windows-gnu when LTO is enabled. (#913) + # Version 0.9.10 - Bump the minimum supported Rust version to 1.38. (#877) diff --git a/vendor/crossbeam-epoch/Cargo.lock b/vendor/crossbeam-epoch/Cargo.lock index 726980a93..3ded5c77e 100644 --- a/vendor/crossbeam-epoch/Cargo.lock +++ b/vendor/crossbeam-epoch/Cargo.lock @@ -31,14 +31,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.11" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", "loom", "memoffset", - "once_cell", "rand", "rustversion", "scopeguard", @@ -46,13 +45,12 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if", "loom", - "once_cell", ] [[package]] @@ -87,9 +85,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "log" @@ -133,9 +131,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "pin-project-lite" @@ -151,18 +149,18 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -190,9 +188,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -223,9 +221,9 @@ checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "rustversion" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" [[package]] name = "scoped-tls" @@ -256,9 +254,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "syn" -version = "1.0.98" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" dependencies = [ "proc-macro2", "quote", @@ -276,9 +274,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if", "pin-project-lite", @@ -299,9 +297,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ "once_cell", "valuable", @@ -338,9 +336,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" [[package]] name = "valuable" diff --git a/vendor/crossbeam-epoch/Cargo.toml b/vendor/crossbeam-epoch/Cargo.toml index 1551c3c2c..0f8e23864 100644 --- a/vendor/crossbeam-epoch/Cargo.toml +++ b/vendor/crossbeam-epoch/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.38" name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.11" description = "Epoch-based garbage collection" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch" readme = "README.md" @@ -41,10 +41,6 @@ default-features = false [dependencies.memoffset] version = "0.6" -[dependencies.once_cell] -version = "1" -optional = true - [dependencies.scopeguard] version = "1.1" default-features = false @@ -69,7 +65,6 @@ nightly = ["crossbeam-utils/nightly"] std = [ "alloc", "crossbeam-utils/std", - "once_cell", ] [target."cfg(crossbeam_loom)".dependencies.loom-crate] diff --git a/vendor/crossbeam-epoch/no_atomic.rs b/vendor/crossbeam-epoch/no_atomic.rs index f740aaee1..675d9a27e 100644 --- a/vendor/crossbeam-epoch/no_atomic.rs +++ b/vendor/crossbeam-epoch/no_atomic.rs @@ -2,6 +2,8 @@ // It is not intended for manual editing. const NO_ATOMIC_CAS: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", "avr-unknown-gnu-atmega328", "bpfeb-unknown-none", "bpfel-unknown-none", @@ -10,6 +12,7 @@ const NO_ATOMIC_CAS: &[&str] = &[ "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", ]; @@ -18,7 +21,9 @@ const NO_ATOMIC_64: &[&str] = &[ "arm-linux-androideabi", "armebv7r-none-eabi", "armebv7r-none-eabihf", + "armv4t-none-eabi", "armv4t-unknown-linux-gnueabi", + "armv5te-none-eabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv5te-unknown-linux-uclibceabi", @@ -55,6 +60,7 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32imac-unknown-xous-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", diff --git a/vendor/crossbeam-epoch/src/default.rs b/vendor/crossbeam-epoch/src/default.rs index c2b4852a4..b42c1c7a7 100644 --- a/vendor/crossbeam-epoch/src/default.rs +++ b/vendor/crossbeam-epoch/src/default.rs @@ -8,22 +8,30 @@ use crate::collector::{Collector, LocalHandle}; use crate::guard::Guard; use crate::primitive::thread_local; #[cfg(not(crossbeam_loom))] -use once_cell::sync::Lazy; +use crate::sync::once_lock::OnceLock; -/// The global data for the default garbage collector. -#[cfg(not(crossbeam_loom))] -static COLLECTOR: Lazy = Lazy::new(Collector::new); -// FIXME: loom does not currently provide the equivalent of Lazy: -// https://github.com/tokio-rs/loom/issues/263 -#[cfg(crossbeam_loom)] -loom::lazy_static! { - /// The global data for the default garbage collector. - static ref COLLECTOR: Collector = Collector::new(); +fn collector() -> &'static Collector { + #[cfg(not(crossbeam_loom))] + { + /// The global data for the default garbage collector. + static COLLECTOR: OnceLock = OnceLock::new(); + COLLECTOR.get_or_init(Collector::new) + } + // FIXME: loom does not currently provide the equivalent of Lazy: + // https://github.com/tokio-rs/loom/issues/263 + #[cfg(crossbeam_loom)] + { + loom::lazy_static! { + /// The global data for the default garbage collector. + static ref COLLECTOR: Collector = Collector::new(); + } + &COLLECTOR + } } thread_local! { /// The per-thread participant for the default garbage collector. - static HANDLE: LocalHandle = COLLECTOR.register(); + static HANDLE: LocalHandle = collector().register(); } /// Pins the current thread. @@ -40,7 +48,7 @@ pub fn is_pinned() -> bool { /// Returns the default global collector. pub fn default_collector() -> &'static Collector { - &COLLECTOR + collector() } #[inline] @@ -50,7 +58,7 @@ where { HANDLE .try_with(|h| f(h)) - .unwrap_or_else(|_| f(&COLLECTOR.register())) + .unwrap_or_else(|_| f(&collector().register())) } #[cfg(all(test, not(crossbeam_loom)))] diff --git a/vendor/crossbeam-epoch/src/lib.rs b/vendor/crossbeam-epoch/src/lib.rs index 4cf982b6b..b432c1f40 100644 --- a/vendor/crossbeam-epoch/src/lib.rs +++ b/vendor/crossbeam-epoch/src/lib.rs @@ -107,7 +107,7 @@ mod primitive { // https://github.com/tokio-rs/loom#handling-loom-api-differences impl UnsafeCell { #[inline] - pub(crate) fn new(data: T) -> UnsafeCell { + pub(crate) const fn new(data: T) -> UnsafeCell { UnsafeCell(::core::cell::UnsafeCell::new(data)) } diff --git a/vendor/crossbeam-epoch/src/sync/mod.rs b/vendor/crossbeam-epoch/src/sync/mod.rs index 5c06e7643..08981be25 100644 --- a/vendor/crossbeam-epoch/src/sync/mod.rs +++ b/vendor/crossbeam-epoch/src/sync/mod.rs @@ -1,4 +1,7 @@ //! Synchronization primitives. pub(crate) mod list; +#[cfg(feature = "std")] +#[cfg(not(crossbeam_loom))] +pub(crate) mod once_lock; pub(crate) mod queue; diff --git a/vendor/crossbeam-epoch/src/sync/once_lock.rs b/vendor/crossbeam-epoch/src/sync/once_lock.rs new file mode 100644 index 000000000..c1fefc96c --- /dev/null +++ b/vendor/crossbeam-epoch/src/sync/once_lock.rs @@ -0,0 +1,103 @@ +// Based on unstable std::sync::OnceLock. +// +// Source: https://github.com/rust-lang/rust/blob/8e9c93df464b7ada3fc7a1c8ccddd9dcb24ee0a0/library/std/src/sync/once_lock.rs + +use core::cell::UnsafeCell; +use core::mem::MaybeUninit; +use core::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Once; + +pub(crate) struct OnceLock { + once: Once, + // Once::is_completed requires Rust 1.43, so use this to track of whether they have been initialized. + is_initialized: AtomicBool, + value: UnsafeCell>, + // Unlike std::sync::OnceLock, we don't need PhantomData here because + // we don't use #[may_dangle]. +} + +unsafe impl Sync for OnceLock {} +unsafe impl Send for OnceLock {} + +impl OnceLock { + /// Creates a new empty cell. + #[must_use] + pub(crate) const fn new() -> Self { + Self { + once: Once::new(), + is_initialized: AtomicBool::new(false), + value: UnsafeCell::new(MaybeUninit::uninit()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell + /// was empty. + /// + /// Many threads may call `get_or_init` concurrently with different + /// initializing functions, but it is guaranteed that only one function + /// will be executed. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. The + /// exact outcome is unspecified. Current implementation deadlocks, but + /// this may be changed to a panic in the future. + pub(crate) fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + // Fast path check + if self.is_initialized() { + // SAFETY: The inner value has been initialized + return unsafe { self.get_unchecked() }; + } + self.initialize(f); + + debug_assert!(self.is_initialized()); + + // SAFETY: The inner value has been initialized + unsafe { self.get_unchecked() } + } + + #[inline] + fn is_initialized(&self) -> bool { + self.is_initialized.load(Ordering::Acquire) + } + + #[cold] + fn initialize(&self, f: F) + where + F: FnOnce() -> T, + { + let slot = self.value.get().cast::(); + let is_initialized = &self.is_initialized; + + self.once.call_once(|| { + let value = f(); + unsafe { + slot.write(value); + } + is_initialized.store(true, Ordering::Release); + }); + } + + /// # Safety + /// + /// The value must be initialized + unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + &*self.value.get().cast::() + } +} + +impl Drop for OnceLock { + fn drop(&mut self) { + if self.is_initialized() { + // SAFETY: The inner value has been initialized + unsafe { self.value.get().cast::().drop_in_place() }; + } + } +} diff --git a/vendor/crossbeam-utils/.cargo-checksum.json b/vendor/crossbeam-utils/.cargo-checksum.json index eac87698d..9c73bbda3 100644 --- a/vendor/crossbeam-utils/.cargo-checksum.json +++ b/vendor/crossbeam-utils/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"eb2f46ecf2eee5f591c4d4e789f18735bb1ed771782a5e0f16eab3a77001e7c2","Cargo.toml":"9ce8b596c9789e65bef4c952bdcac84fc88e50ba9ecb01a818036eff4e6ecfec","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"2a19af38a52dd965c2d66bb39f90a85b430b51ee9ccb29e9e1978ee7091e5087","benches/atomic_cell.rs":"c927eb3cd1e5ecc4b91adbc3bde98af15ffab4086190792ba64d5cde0e24df3d","build.rs":"4859f9c926c230023e861bf01c4b225b460035faf8cf6240108530efedbb747f","no_atomic.rs":"916ed15218bb7b75a4e0d432430e7134efd27ca43ca8a8766e0c90e89febb602","src/atomic/atomic_cell.rs":"0fc99463e633144c5d59d39c35b5477da1f1b90f5448cadc37454b7f4b97707e","src/atomic/consume.rs":"7a7736fcd64f6473dfea7653559ffc5e1a2a234df43835f8aa8734862145ac15","src/atomic/mod.rs":"94193895fa03cece415e8d7be700b73a9a8a7015774ca821253438607f9b0736","src/atomic/seq_lock.rs":"27182e6b87a9db73c5f6831759f8625f9fcdec3c2828204c444aef04f427735a","src/atomic/seq_lock_wide.rs":"9888dd03116bb89ca36d4ab8d5a0b5032107a2983a7eb8024454263b09080088","src/backoff.rs":"8fd5e3dcccc05860680e49c8498de8096bee9140bcfee8723d97117106a020d0","src/cache_padded.rs":"6a512698115ad0d5a5b163dbd7a83247e1f1c146c4a30f3fc74b952e3b767b59","src/lib.rs":"6f1bcf157abe06ad8458a53e865bf8efab9fad4a9424790147cee8fefb3795d8","src/sync/mod.rs":"59986f559a8f170a4b3247ab2eea2460b09809d87c8110ed88e4e7103d3519dc","src/sync/parker.rs":"91f3a7d4ee8d9e06b6558d180e8a0df08ff5c6cef612b4ce4790f9f75cb34f84","src/sync/sharded_lock.rs":"78433f55ee3defeea348d65abc78e03d63d6a304e09c568b27b403e9ad205771","src/sync/wait_group.rs":"32e946a7581c55f8aa9904527b92b177c538fa0cf7cbcfa1d1f25990582cb6ea","src/thread.rs":"21cf9b3e965529e5c0a6ff8fc1ec846bfe0006c41deb238a149be8d07384e955","tests/atomic_cell.rs":"bf8bc869c922a1cbf929c3b741bae0cae98f2157f572b5a4eb2873d20a407c22","tests/cache_padded.rs":"1bfaff8354c8184e1ee1f902881ca9400b60effb273b0d3f752801a483d2b66d","tests/parker.rs":"6def4721287d9d70b1cfd63ebb34e1c83fbb3376edbad2bc8aac6ef69dd99d20","tests/sharded_lock.rs":"314adeb8a651a28935f7a49c9a261b8fa1fd82bf6a16c865a5aced6216d7e40b","tests/thread.rs":"9a7d7d3028c552fd834c68598b04a1cc252a816bc20ab62cec060d6cd09cab10","tests/wait_group.rs":"02661c2a820a5abe8b0c8fe15a6650aead707b57cdda0610d1b09a2680ed6969"},"package":"51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"} \ No newline at end of file +{"files":{"CHANGELOG.md":"65d3e11edf9498bdbc930c8c3878b7d3a90c1a0b1698597dc4a396a547fa0948","Cargo.toml":"1e4259a5a47271e8ae040b91e17652b5a4e0e7e45c3f22de5008db276f3a50bf","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"2a19af38a52dd965c2d66bb39f90a85b430b51ee9ccb29e9e1978ee7091e5087","benches/atomic_cell.rs":"c927eb3cd1e5ecc4b91adbc3bde98af15ffab4086190792ba64d5cde0e24df3d","build.rs":"4859f9c926c230023e861bf01c4b225b460035faf8cf6240108530efedbb747f","no_atomic.rs":"f58085b9d0666ccf62e0ae17fb5dae937c0a86fcc55dc0ae04ad8659e696a49c","src/atomic/atomic_cell.rs":"0fc99463e633144c5d59d39c35b5477da1f1b90f5448cadc37454b7f4b97707e","src/atomic/consume.rs":"7a7736fcd64f6473dfea7653559ffc5e1a2a234df43835f8aa8734862145ac15","src/atomic/mod.rs":"94193895fa03cece415e8d7be700b73a9a8a7015774ca821253438607f9b0736","src/atomic/seq_lock.rs":"27182e6b87a9db73c5f6831759f8625f9fcdec3c2828204c444aef04f427735a","src/atomic/seq_lock_wide.rs":"9888dd03116bb89ca36d4ab8d5a0b5032107a2983a7eb8024454263b09080088","src/backoff.rs":"8fd5e3dcccc05860680e49c8498de8096bee9140bcfee8723d97117106a020d0","src/cache_padded.rs":"8bb8925e2df44224ffa29f31a2f9c08d88d8bd3df6c1ce47003598225055fdb5","src/lib.rs":"6f1bcf157abe06ad8458a53e865bf8efab9fad4a9424790147cee8fefb3795d8","src/sync/mod.rs":"eca73c04f821859b8434d2b93db87d160dc6a3f65498ca201cd40d732ca4c134","src/sync/once_lock.rs":"c03dc9c05a817e087dccf8b682f7307501542805533551da3c2bab442bc40743","src/sync/parker.rs":"91f3a7d4ee8d9e06b6558d180e8a0df08ff5c6cef612b4ce4790f9f75cb34f84","src/sync/sharded_lock.rs":"6391b3b99b194b8e0888446c2dec340e4fb095753bcf0c1a80bc654f9c8be0e3","src/sync/wait_group.rs":"3e339aab014f50e214fea535c841755113ea058153378ed54e50a4acb403c937","src/thread.rs":"21cf9b3e965529e5c0a6ff8fc1ec846bfe0006c41deb238a149be8d07384e955","tests/atomic_cell.rs":"bf8bc869c922a1cbf929c3b741bae0cae98f2157f572b5a4eb2873d20a407c22","tests/cache_padded.rs":"1bfaff8354c8184e1ee1f902881ca9400b60effb273b0d3f752801a483d2b66d","tests/parker.rs":"6def4721287d9d70b1cfd63ebb34e1c83fbb3376edbad2bc8aac6ef69dd99d20","tests/sharded_lock.rs":"314adeb8a651a28935f7a49c9a261b8fa1fd82bf6a16c865a5aced6216d7e40b","tests/thread.rs":"9a7d7d3028c552fd834c68598b04a1cc252a816bc20ab62cec060d6cd09cab10","tests/wait_group.rs":"02661c2a820a5abe8b0c8fe15a6650aead707b57cdda0610d1b09a2680ed6969"},"package":"edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"} \ No newline at end of file diff --git a/vendor/crossbeam-utils/CHANGELOG.md b/vendor/crossbeam-utils/CHANGELOG.md index 28812e1d6..3a93e4659 100644 --- a/vendor/crossbeam-utils/CHANGELOG.md +++ b/vendor/crossbeam-utils/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.8.12 + +- Removes the dependency on the `once_cell` crate to restore the MSRV. (#913) +- Work around [rust-lang#98302](https://github.com/rust-lang/rust/issues/98302), which causes compile error on windows-gnu when LTO is enabled. (#913) + # Version 0.8.11 - Bump the minimum supported Rust version to 1.38. (#877) diff --git a/vendor/crossbeam-utils/Cargo.toml b/vendor/crossbeam-utils/Cargo.toml index 9e1b58628..5cb2b0a84 100644 --- a/vendor/crossbeam-utils/Cargo.toml +++ b/vendor/crossbeam-utils/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.38" name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.12" description = "Utilities for concurrent programming" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" readme = "README.md" @@ -35,10 +35,6 @@ repository = "https://github.com/crossbeam-rs/crossbeam" [dependencies.cfg-if] version = "1" -[dependencies.once_cell] -version = "1" -optional = true - [dev-dependencies.rand] version = "0.8" @@ -48,7 +44,7 @@ version = "1" [features] default = ["std"] nightly = [] -std = ["once_cell"] +std = [] [target."cfg(crossbeam_loom)".dependencies.loom] version = "0.5" diff --git a/vendor/crossbeam-utils/no_atomic.rs b/vendor/crossbeam-utils/no_atomic.rs index f740aaee1..675d9a27e 100644 --- a/vendor/crossbeam-utils/no_atomic.rs +++ b/vendor/crossbeam-utils/no_atomic.rs @@ -2,6 +2,8 @@ // It is not intended for manual editing. const NO_ATOMIC_CAS: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", "avr-unknown-gnu-atmega328", "bpfeb-unknown-none", "bpfel-unknown-none", @@ -10,6 +12,7 @@ const NO_ATOMIC_CAS: &[&str] = &[ "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", ]; @@ -18,7 +21,9 @@ const NO_ATOMIC_64: &[&str] = &[ "arm-linux-androideabi", "armebv7r-none-eabi", "armebv7r-none-eabihf", + "armv4t-none-eabi", "armv4t-unknown-linux-gnueabi", + "armv5te-none-eabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv5te-unknown-linux-uclibceabi", @@ -55,6 +60,7 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32imac-unknown-xous-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", diff --git a/vendor/crossbeam-utils/src/cache_padded.rs b/vendor/crossbeam-utils/src/cache_padded.rs index 822e831d1..b5d5d33c9 100644 --- a/vendor/crossbeam-utils/src/cache_padded.rs +++ b/vendor/crossbeam-utils/src/cache_padded.rs @@ -39,9 +39,9 @@ use core::ops::{Deref, DerefMut}; /// let addr1 = &*array[0] as *const i8 as usize; /// let addr2 = &*array[1] as *const i8 as usize; /// -/// assert!(addr2 - addr1 >= 64); -/// assert_eq!(addr1 % 64, 0); -/// assert_eq!(addr2 % 64, 0); +/// assert!(addr2 - addr1 >= 32); +/// assert_eq!(addr1 % 32, 0); +/// assert_eq!(addr2 % 32, 0); /// ``` /// /// When building a concurrent queue with a head and a tail index, it is wise to place them in diff --git a/vendor/crossbeam-utils/src/sync/mod.rs b/vendor/crossbeam-utils/src/sync/mod.rs index eeb740c2c..f9eec71fb 100644 --- a/vendor/crossbeam-utils/src/sync/mod.rs +++ b/vendor/crossbeam-utils/src/sync/mod.rs @@ -4,6 +4,8 @@ //! * [`ShardedLock`], a sharded reader-writer lock with fast concurrent reads. //! * [`WaitGroup`], for synchronizing the beginning or end of some computation. +#[cfg(not(crossbeam_loom))] +mod once_lock; mod parker; #[cfg(not(crossbeam_loom))] mod sharded_lock; diff --git a/vendor/crossbeam-utils/src/sync/once_lock.rs b/vendor/crossbeam-utils/src/sync/once_lock.rs new file mode 100644 index 000000000..c1fefc96c --- /dev/null +++ b/vendor/crossbeam-utils/src/sync/once_lock.rs @@ -0,0 +1,103 @@ +// Based on unstable std::sync::OnceLock. +// +// Source: https://github.com/rust-lang/rust/blob/8e9c93df464b7ada3fc7a1c8ccddd9dcb24ee0a0/library/std/src/sync/once_lock.rs + +use core::cell::UnsafeCell; +use core::mem::MaybeUninit; +use core::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Once; + +pub(crate) struct OnceLock { + once: Once, + // Once::is_completed requires Rust 1.43, so use this to track of whether they have been initialized. + is_initialized: AtomicBool, + value: UnsafeCell>, + // Unlike std::sync::OnceLock, we don't need PhantomData here because + // we don't use #[may_dangle]. +} + +unsafe impl Sync for OnceLock {} +unsafe impl Send for OnceLock {} + +impl OnceLock { + /// Creates a new empty cell. + #[must_use] + pub(crate) const fn new() -> Self { + Self { + once: Once::new(), + is_initialized: AtomicBool::new(false), + value: UnsafeCell::new(MaybeUninit::uninit()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell + /// was empty. + /// + /// Many threads may call `get_or_init` concurrently with different + /// initializing functions, but it is guaranteed that only one function + /// will be executed. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. The + /// exact outcome is unspecified. Current implementation deadlocks, but + /// this may be changed to a panic in the future. + pub(crate) fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + // Fast path check + if self.is_initialized() { + // SAFETY: The inner value has been initialized + return unsafe { self.get_unchecked() }; + } + self.initialize(f); + + debug_assert!(self.is_initialized()); + + // SAFETY: The inner value has been initialized + unsafe { self.get_unchecked() } + } + + #[inline] + fn is_initialized(&self) -> bool { + self.is_initialized.load(Ordering::Acquire) + } + + #[cold] + fn initialize(&self, f: F) + where + F: FnOnce() -> T, + { + let slot = self.value.get().cast::(); + let is_initialized = &self.is_initialized; + + self.once.call_once(|| { + let value = f(); + unsafe { + slot.write(value); + } + is_initialized.store(true, Ordering::Release); + }); + } + + /// # Safety + /// + /// The value must be initialized + unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + &*self.value.get().cast::() + } +} + +impl Drop for OnceLock { + fn drop(&mut self) { + if self.is_initialized() { + // SAFETY: The inner value has been initialized + unsafe { self.value.get().cast::().drop_in_place() }; + } + } +} diff --git a/vendor/crossbeam-utils/src/sync/sharded_lock.rs b/vendor/crossbeam-utils/src/sync/sharded_lock.rs index 692653447..b43c55ea4 100644 --- a/vendor/crossbeam-utils/src/sync/sharded_lock.rs +++ b/vendor/crossbeam-utils/src/sync/sharded_lock.rs @@ -9,8 +9,8 @@ use std::sync::{LockResult, PoisonError, TryLockError, TryLockResult}; use std::sync::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::thread::{self, ThreadId}; +use crate::sync::once_lock::OnceLock; use crate::CachePadded; -use once_cell::sync::Lazy; /// The number of shards per sharded lock. Must be a power of two. const NUM_SHARDS: usize = 8; @@ -583,13 +583,17 @@ struct ThreadIndices { next_index: usize, } -static THREAD_INDICES: Lazy> = Lazy::new(|| { - Mutex::new(ThreadIndices { - mapping: HashMap::new(), - free_list: Vec::new(), - next_index: 0, - }) -}); +fn thread_indices() -> &'static Mutex { + static THREAD_INDICES: OnceLock> = OnceLock::new(); + fn init() -> Mutex { + Mutex::new(ThreadIndices { + mapping: HashMap::new(), + free_list: Vec::new(), + next_index: 0, + }) + } + THREAD_INDICES.get_or_init(init) +} /// A registration of a thread with an index. /// @@ -601,7 +605,7 @@ struct Registration { impl Drop for Registration { fn drop(&mut self) { - let mut indices = THREAD_INDICES.lock().unwrap(); + let mut indices = thread_indices().lock().unwrap(); indices.mapping.remove(&self.thread_id); indices.free_list.push(self.index); } @@ -610,7 +614,7 @@ impl Drop for Registration { thread_local! { static REGISTRATION: Registration = { let thread_id = thread::current().id(); - let mut indices = THREAD_INDICES.lock().unwrap(); + let mut indices = thread_indices().lock().unwrap(); let index = match indices.free_list.pop() { Some(i) => i, diff --git a/vendor/crossbeam-utils/src/sync/wait_group.rs b/vendor/crossbeam-utils/src/sync/wait_group.rs index 4206ee42b..19d607415 100644 --- a/vendor/crossbeam-utils/src/sync/wait_group.rs +++ b/vendor/crossbeam-utils/src/sync/wait_group.rs @@ -1,6 +1,3 @@ -// Necessary for using `Mutex` for conditional variables -#![allow(clippy::mutex_atomic)] - use crate::primitive::sync::{Arc, Condvar, Mutex}; use std::fmt; @@ -42,6 +39,7 @@ use std::fmt; /// /// // Block until all threads have finished their work. /// wg.wait(); +/// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 /// ``` /// /// [`Barrier`]: std::sync::Barrier @@ -100,6 +98,7 @@ impl WaitGroup { /// /// // Block until both threads have reached `wait()`. /// wg.wait(); + /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 /// ``` pub fn wait(self) { if *self.inner.count.lock().unwrap() == 1 { diff --git a/vendor/dashmap/.cargo-checksum.json b/vendor/dashmap/.cargo-checksum.json index 7d0daa971..4197ac76b 100644 --- a/vendor/dashmap/.cargo-checksum.json +++ b/vendor/dashmap/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"8f8a0060b2a6f95a4ba3f009e49a4f0a4c26ea5ba7fb02388ca5466d97c6ccfe","LICENSE":"16692e8cee4aa06e3913787497eba2d47c42002014136f5da67be6ee640e28a3","README.md":"e1114aed5dfbd2892f2d81881c46f8e17b9b4774344ad3feb55bd2c1a41384fd","rust-toolchain":"06dc4c395690e7d6ff8b92d8d265a8cf1c02cbca414e15352072e378fcb4171a","src/iter.rs":"dec9cc68374a0a176b5840e37da4e83d0493d7dca6f776dc926bf511c84e70db","src/iter_set.rs":"5327da951dc93d30b293aeb7a805666ee4b8e6364881348ab5d86b23c29a0e13","src/lib.rs":"ad0b2651810d4d286f11ce4effb800920eb4100ae6676f6141126e5488358007","src/lock.rs":"22b1013ee3cbd1598c26403552faf8e5b44fe98a8ff4c8812da15d57bdeee4b3","src/mapref/entry.rs":"ddcf788856330a4384ce987bb84ff36b494675b3b1f2460ae48376ac664491df","src/mapref/mod.rs":"15bd45cfc642a9e3e77bbfbf2d9fad9c5fac0ff6904214a3c501e262242ec8b0","src/mapref/multiple.rs":"17a87879229d78f75d71817d100aa0a210d764d6b66e4a05b17a3e092d17e306","src/mapref/one.rs":"ea46339e08c5033cf419c195e922e1ba6f606fc71c15ee31d1b3c38cfedfedcf","src/rayon/map.rs":"07315c9dd35437fd5e504a07fcbcd77f9ea19c892c32c1d60f27db5a6a26345b","src/rayon/set.rs":"21fe2ca8c58c8ff1bc753f5e2eb6131afd598211eea375f2ac7190cd0f9abcba","src/read_only.rs":"c846f8117800dbbb122bc0552021c5ac4ccfbf464bebe37f4b65e40b19baf260","src/serde.rs":"57bbf2b255de966cc9c54011429495cc5308a1f76906846b29e015f860b79559","src/set.rs":"80271aa0d8a32845afdef5a35f18e5cac6f0f5ab8d2a6b11b02cd123152c91d4","src/setref/mod.rs":"cc39e406a333dc6c04398f4b1336fb400e3a8360c387466d8a91f5d7f4ed40a7","src/setref/multiple.rs":"2270749e83f80dbb4761448f0629ecd02b0b4268f76834236d1167844e6d5e37","src/setref/one.rs":"69738583f2a160f3907e540277ccd88e0036406b3ead66b3d4015ddd938d6937","src/t.rs":"9b40ebfba22369813bf159ed60fa70e742ae72bfaec6aee91a716cba91cb8f0d","src/table.rs":"536a3b5775cbdbe436357c231e54e4e2ee4a5e1849872aa92335271b148845b4","src/try_result.rs":"81d1dd396f70b0aa2a6e1969851b706cbfdfb09c802ac9d33dcace882aa28dd1","src/util.rs":"7a8096a713cf04e60d6c9e38cd366314ed74472abab4bb8a3a9ed081a0e0301b"},"package":"3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f"} \ No newline at end of file +{"files":{"Cargo.toml":"8181631e0224f428c3c213850ce536d9d27c82b46e3eadcd0137f78470086fc2","LICENSE":"16692e8cee4aa06e3913787497eba2d47c42002014136f5da67be6ee640e28a3","README.md":"e1114aed5dfbd2892f2d81881c46f8e17b9b4774344ad3feb55bd2c1a41384fd","rust-toolchain":"06dc4c395690e7d6ff8b92d8d265a8cf1c02cbca414e15352072e378fcb4171a","src/iter.rs":"dec9cc68374a0a176b5840e37da4e83d0493d7dca6f776dc926bf511c84e70db","src/iter_set.rs":"5327da951dc93d30b293aeb7a805666ee4b8e6364881348ab5d86b23c29a0e13","src/lib.rs":"24935d49696b2d05a83287c6a5f08d59bc206a535bfa0f8893bfeff3cfd14ea8","src/lock.rs":"22b1013ee3cbd1598c26403552faf8e5b44fe98a8ff4c8812da15d57bdeee4b3","src/mapref/entry.rs":"ddcf788856330a4384ce987bb84ff36b494675b3b1f2460ae48376ac664491df","src/mapref/mod.rs":"15bd45cfc642a9e3e77bbfbf2d9fad9c5fac0ff6904214a3c501e262242ec8b0","src/mapref/multiple.rs":"17a87879229d78f75d71817d100aa0a210d764d6b66e4a05b17a3e092d17e306","src/mapref/one.rs":"ea46339e08c5033cf419c195e922e1ba6f606fc71c15ee31d1b3c38cfedfedcf","src/rayon/map.rs":"2df5ac8241d92e1811852abd65c5b3124a14d886ae4e3a8a5cbdfdb3d7dde929","src/rayon/read_only.rs":"99dc0083f6840f59b2090bc9c5f9767a44088832e63935cb8f6bc7eca8b86102","src/rayon/set.rs":"21fe2ca8c58c8ff1bc753f5e2eb6131afd598211eea375f2ac7190cd0f9abcba","src/read_only.rs":"d872ec78201ddc272aeeabdbeaccb26e069704b85aa2f6a4d56bd0c5defe7a2b","src/serde.rs":"57bbf2b255de966cc9c54011429495cc5308a1f76906846b29e015f860b79559","src/set.rs":"80271aa0d8a32845afdef5a35f18e5cac6f0f5ab8d2a6b11b02cd123152c91d4","src/setref/mod.rs":"cc39e406a333dc6c04398f4b1336fb400e3a8360c387466d8a91f5d7f4ed40a7","src/setref/multiple.rs":"2270749e83f80dbb4761448f0629ecd02b0b4268f76834236d1167844e6d5e37","src/setref/one.rs":"69738583f2a160f3907e540277ccd88e0036406b3ead66b3d4015ddd938d6937","src/t.rs":"9b40ebfba22369813bf159ed60fa70e742ae72bfaec6aee91a716cba91cb8f0d","src/try_result.rs":"81d1dd396f70b0aa2a6e1969851b706cbfdfb09c802ac9d33dcace882aa28dd1","src/util.rs":"7a8096a713cf04e60d6c9e38cd366314ed74472abab4bb8a3a9ed081a0e0301b"},"package":"907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"} \ No newline at end of file diff --git a/vendor/dashmap/Cargo.toml b/vendor/dashmap/Cargo.toml index a03feb0ce..ce76bd9a7 100644 --- a/vendor/dashmap/Cargo.toml +++ b/vendor/dashmap/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.59" name = "dashmap" -version = "5.3.4" +version = "5.4.0" authors = ["Acrimon "] description = "Blazing fast concurrent HashMap for Rust." homepage = "https://github.com/xacrimon/dashmap" @@ -29,21 +29,24 @@ features = ["rayon", "raw-api", "serde"] version = "1.0.0" [dependencies.hashbrown] -version = "0.12.0" +version = "0.12.3" default-features = false [dependencies.lock_api] -version = "0.4.7" +version = "0.4.8" + +[dependencies.once_cell] +version = "1.13.1" [dependencies.parking_lot_core] version = "0.9.3" [dependencies.rayon] -version = "1.5.2" +version = "1.5.3" optional = true [dependencies.serde] -version = "1.0.136" +version = "1.0.144" features = ["derive"] optional = true diff --git a/vendor/dashmap/src/lib.rs b/vendor/dashmap/src/lib.rs index 627b51381..bf112d570 100644 --- a/vendor/dashmap/src/lib.rs +++ b/vendor/dashmap/src/lib.rs @@ -16,6 +16,7 @@ mod util; #[cfg(feature = "rayon")] pub mod rayon { pub mod map; + pub mod read_only; pub mod set; } @@ -35,6 +36,7 @@ use iter::{Iter, IterMut, OwningIter}; use mapref::entry::{Entry, OccupiedEntry, VacantEntry}; use mapref::multiple::RefMulti; use mapref::one::{Ref, RefMut}; +use once_cell::sync::OnceCell; pub use read_only::ReadOnlyView; pub use set::DashSet; use std::collections::hash_map::RandomState; @@ -51,8 +53,19 @@ cfg_if! { pub(crate) type HashMap = hashbrown::HashMap, S>; +// Temporary reimplementation of [`std::collections::TryReserveError`] +// util [`std::collections::TryReserveError`] stabilises. +// We cannot easily create `std::collections` error type from `hashbrown` error type +// without access to `TryReserveError::kind` method. +#[non_exhaustive] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct TryReserveError {} + fn default_shard_amount() -> usize { - (std::thread::available_parallelism().map_or(1, usize::from) * 4).next_power_of_two() + static DEFAULT_SHARD_AMOUNT: OnceCell = OnceCell::new(); + *DEFAULT_SHARD_AMOUNT.get_or_init(|| { + (std::thread::available_parallelism().map_or(1, usize::from) * 4).next_power_of_two() + }) } fn ncb(shard_amount: usize) -> usize { @@ -65,7 +78,7 @@ fn ncb(shard_amount: usize) -> usize { /// with some slight changes to handle concurrency. /// /// DashMap tries to be very simple to use and to be a direct replacement for `RwLock>`. -/// To accomplish these all methods take `&self` instead modifying methods taking `&mut self`. +/// To accomplish this, all methods take `&self` instead of modifying methods taking `&mut self`. /// This allows you to put a DashMap in an `Arc` and share it between threads while being able to modify it. /// /// Documentation mentioning locking behaviour acts in the reference frame of the calling thread. @@ -216,7 +229,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// Creates a new DashMap with a specified hasher and shard amount /// - /// shard_amount should greater than 0 and be a power of two. + /// shard_amount should be greater than 0 and a power of two. /// If a shard_amount which is not a power of two is provided, the function will panic. /// /// # Examples @@ -797,6 +810,24 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { pub fn try_entry(&'a self, key: K) -> Option> { self._try_entry(key) } + + /// Advanced entry API that tries to mimic `std::collections::HashMap::try_reserve`. + /// Tries to reserve capacity for at least `shard * additional` + /// and may reserve more space to avoid frequent reallocations. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error is returned. + // TODO: return std::collections::TryReserveError once std::collections::TryReserveErrorKind stabilises. + pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { + for shard in self.shards.iter() { + shard + .write() + .try_reserve(additional) + .map_err(|_| TryReserveError {})?; + } + Ok(()) + } } impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> @@ -1367,4 +1398,26 @@ mod tests { assert!(result2.is_locked()); } } + + #[test] + fn test_try_reserve() { + let mut map: DashMap = DashMap::new(); + // DashMap is empty and doesn't allocate memory + assert_eq!(map.capacity(), 0); + + map.try_reserve(10).unwrap(); + + // And now map can hold at least 10 elements + assert!(map.capacity() >= 10); + } + + #[test] + fn test_try_reserve_errors() { + let mut map: DashMap = DashMap::new(); + + match map.try_reserve(usize::MAX) { + Err(_) => {} + _ => panic!("should have raised CapacityOverflow error"), + } + } } diff --git a/vendor/dashmap/src/rayon/map.rs b/vendor/dashmap/src/rayon/map.rs index c0947cf6b..4fc0c43aa 100644 --- a/vendor/dashmap/src/rayon/map.rs +++ b/vendor/dashmap/src/rayon/map.rs @@ -80,7 +80,7 @@ where } pub struct OwningIter { - shards: Box<[RwLock>]>, + pub(super) shards: Box<[RwLock>]>, } impl ParallelIterator for OwningIter @@ -125,7 +125,7 @@ where } pub struct Iter<'a, K, V, S = RandomState> { - shards: &'a [RwLock>], + pub(super) shards: &'a [RwLock>], } impl<'a, K, V, S> ParallelIterator for Iter<'a, K, V, S> diff --git a/vendor/dashmap/src/rayon/read_only.rs b/vendor/dashmap/src/rayon/read_only.rs new file mode 100644 index 000000000..a11448cee --- /dev/null +++ b/vendor/dashmap/src/rayon/read_only.rs @@ -0,0 +1,96 @@ +use crate::mapref::multiple::RefMulti; +use crate::rayon::map::Iter; +use crate::ReadOnlyView; +use core::hash::{BuildHasher, Hash}; +use rayon::iter::IntoParallelIterator; + +impl IntoParallelIterator for ReadOnlyView +where + K: Send + Eq + Hash, + V: Send, + S: Send + Clone + BuildHasher, +{ + type Iter = super::map::OwningIter; + type Item = (K, V); + + fn into_par_iter(self) -> Self::Iter { + super::map::OwningIter { + shards: self.map.shards, + } + } +} + +// This impl also enables `IntoParallelRefIterator::par_iter` +impl<'a, K, V, S> IntoParallelIterator for &'a ReadOnlyView +where + K: Send + Sync + Eq + Hash, + V: Send + Sync, + S: Send + Sync + Clone + BuildHasher, +{ + type Iter = Iter<'a, K, V, S>; + type Item = RefMulti<'a, K, V, S>; + + fn into_par_iter(self) -> Self::Iter { + Iter { + shards: &self.map.shards, + } + } +} + +#[cfg(test)] +mod tests { + use crate::DashMap; + use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator}; + + fn construct_sample_map() -> DashMap { + let map = DashMap::new(); + + map.insert(1, "one".to_string()); + + map.insert(10, "ten".to_string()); + + map.insert(27, "twenty seven".to_string()); + + map.insert(45, "forty five".to_string()); + + map + } + + #[test] + fn test_par_iter() { + let map = construct_sample_map(); + + let view = map.clone().into_read_only(); + + view.par_iter().for_each(|entry| { + let key = *entry.key(); + + assert!(view.contains_key(&key)); + + let map_entry = map.get(&key).unwrap(); + + assert_eq!(view.get(&key).unwrap(), map_entry.value()); + + let key_value: (&i32, &String) = view.get_key_value(&key).unwrap(); + + assert_eq!(key_value.0, map_entry.key()); + + assert_eq!(key_value.1, map_entry.value()); + }); + } + + #[test] + fn test_into_par_iter() { + let map = construct_sample_map(); + + let view = map.clone().into_read_only(); + + view.into_par_iter().for_each(|(key, value)| { + let map_entry = map.get(&key).unwrap(); + + assert_eq!(&key, map_entry.key()); + + assert_eq!(&value, map_entry.value()); + }); + } +} diff --git a/vendor/dashmap/src/read_only.rs b/vendor/dashmap/src/read_only.rs index c43947b2e..14582245b 100644 --- a/vendor/dashmap/src/read_only.rs +++ b/vendor/dashmap/src/read_only.rs @@ -7,7 +7,7 @@ use std::collections::hash_map::RandomState; /// A read-only view into a `DashMap`. Allows to obtain raw references to the stored values. pub struct ReadOnlyView { - map: DashMap, + pub(crate) map: DashMap, } impl Clone for ReadOnlyView { diff --git a/vendor/dashmap/src/table.rs b/vendor/dashmap/src/table.rs deleted file mode 100644 index 03acd76e2..000000000 --- a/vendor/dashmap/src/table.rs +++ /dev/null @@ -1,81 +0,0 @@ -use super::u128::AtomicU128; -use std::borrow::Borrow; -use std::cell::UnsafeCell; -use std::hash::{BuildHasher, Hash, Hasher}; -use std::mem::MaybeUninit; -use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::{Arc, Mutex}; - -const TOMBSTONE_BIT: u64 = 1 << 63; -const ALLOCATED_BIT: u64 = 1 << 62; -const POINTER_MASK: u64 = 0x3FFFFFFFFFFFFFFF; - -fn hash(hasher: &S, key: &K) -> u64 -where - S: BuildHasher, - K: Hash, -{ - let mut hasher = hasher.build_hasher(); - key.hash(&mut hasher); - hasher.finish() -} - -struct Slot { - data: AtomicU64, - pair: UnsafeCell>, -} - -pub struct Table { - hash: Arc, - slots: Box<[Slot]>, - mask: usize, -} - -impl Table -where - K: Eq + Hash, - S: BuildHasher, -{ - pub fn new(hasher: Arc, capacity: usize) -> Self { - debug_assert!(capacity.is_power_of_two()); - let slots = (0..capacity) - .map(|_| Slot { - data: AtomicU64::new(0), - pair: UnsafeCell::new(MaybeUninit::uninit()), - }) - .collect::>(); - - Table { - hash: hasher, - slots: slots.into_boxed_slice(), - mask: capacity - 1, - } - } - - pub fn get(&self, key: &Q) -> Option<*mut (K, V)> - where - K: Borrow, - Q: Eq + Hash, - { - let hash = hash(&*self.hash, key); - let mut idx = hash as usize & self.mask; - let mut i = 0; - - loop { - let slot = &self.slots[idx]; - let data = slot.data.load(Ordering::Relaxed); - let ptr = (data & POINTER_MASK) as *mut (K, V); - if !ptr.is_null() { - let stored = unsafe { (*ptr).0.borrow() }; - if stored == key { - return Some(ptr); - } - } else if data & TOMBSTONE_BIT != TOMBSTONE_BIT || i > self.mask { - return None; - } - - idx = (idx + 1) & self.mask; - i += 1; - } - } -} diff --git a/vendor/form_urlencoded/.cargo-checksum.json b/vendor/form_urlencoded/.cargo-checksum.json index 33e19d140..29befa62b 100644 --- a/vendor/form_urlencoded/.cargo-checksum.json +++ b/vendor/form_urlencoded/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"aadc4e4ba33e86861d8d1d8b848ac11a27b6f87340d082b47f762387464c61ed","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","src/lib.rs":"5d30edec687843447c97e4ea87583983eb9fc06135ae718c8ecc0fa8cebef2df"},"package":"5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"} \ No newline at end of file +{"files":{"Cargo.toml":"1771c35bc67b544a7ebc6f31168d7bc08d29ae76323e7ee10352d43b5a38afac","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","src/lib.rs":"c1a0db36086e4fd0e8bb1489f9c2bb55945dd233614bf5dc3a0c41cb49292dd3"},"package":"a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"} \ No newline at end of file diff --git a/vendor/form_urlencoded/Cargo.toml b/vendor/form_urlencoded/Cargo.toml index 4c9fae259..037361d31 100644 --- a/vendor/form_urlencoded/Cargo.toml +++ b/vendor/form_urlencoded/Cargo.toml @@ -3,26 +3,24 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" +rust-version = "1.51" name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" authors = ["The rust-url developers"] description = "Parser and serializer for the application/x-www-form-urlencoded syntax, as used by HTML forms." -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/servo/rust-url" [lib] test = false -[dependencies.matches] -version = "0.1" [dependencies.percent-encoding] -version = "2.1.0" +version = "2.2.0" diff --git a/vendor/form_urlencoded/src/lib.rs b/vendor/form_urlencoded/src/lib.rs index 765ee168a..477594bf7 100644 --- a/vendor/form_urlencoded/src/lib.rs +++ b/vendor/form_urlencoded/src/lib.rs @@ -13,9 +13,6 @@ //! Converts between a string (such as an URL’s query string) //! and a sequence of (name, value) pairs. -#[macro_use] -extern crate matches; - use percent_encoding::{percent_decode, percent_encode_byte}; use std::borrow::{Borrow, Cow}; use std::str; @@ -402,8 +399,7 @@ pub(crate) fn decode_utf8_lossy(input: Cow<'_, [u8]>) -> Cow<'_, str> { // replace invalid bytes with a placeholder. // First we do a debug_assert to confirm our description above. - let raw_utf8: *const [u8]; - raw_utf8 = utf8.as_bytes(); + let raw_utf8: *const [u8] = utf8.as_bytes(); debug_assert!(raw_utf8 == &*bytes as *const [u8]); // Given we know the original input bytes are valid UTF-8, diff --git a/vendor/home/.cargo-checksum.json b/vendor/home/.cargo-checksum.json index 637f4c5ce..ad8175dc3 100644 --- a/vendor/home/.cargo-checksum.json +++ b/vendor/home/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f6ea8042d794bed2af227905011daada5eaa1eb15ba63589d2aa9c8bd5ea06e7","LICENSE-APACHE":"aefbb3792184d86e625cd877b226a00e2cf13cb546ae79e78ddb9e3f097a7156","LICENSE-MIT":"ea7c5138df175c35e89b7adc1b1b35e07786a40330cae4beb2172781bd3daad9","README.md":"13b381ff7553b3467c85b877ee0aae43ebf444deca1c85131d5f0fb3b27d5003","src/lib.rs":"bbadf2a9750a1dd204057dee19e4282d48a878bd9b1810bedf59dc4b55a992eb","src/windows.rs":"061ce6208d2a366cdbf9d094c60fa73b7e856eb1f510fa2aaf5d109bded35442"},"package":"2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"} \ No newline at end of file +{"files":{"Cargo.toml":"12996f8286ac1164cb7026f8e170316337a0acb2d180fbf41192ddcf534a4843","LICENSE-APACHE":"aefbb3792184d86e625cd877b226a00e2cf13cb546ae79e78ddb9e3f097a7156","LICENSE-MIT":"ea7c5138df175c35e89b7adc1b1b35e07786a40330cae4beb2172781bd3daad9","README.md":"13b381ff7553b3467c85b877ee0aae43ebf444deca1c85131d5f0fb3b27d5003","src/env.rs":"4e8bd91330f6ae948f5b825e9884720631f4fe9282fb4548915218e1c43b54a5","src/lib.rs":"cc2675a4c0d5b2e3041228554718f63f754811e9b45a3c9b423bd2f43adf38e3","src/windows.rs":"061ce6208d2a366cdbf9d094c60fa73b7e856eb1f510fa2aaf5d109bded35442"},"package":"747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"} \ No newline at end of file diff --git a/vendor/home/Cargo.toml b/vendor/home/Cargo.toml index 245d5e1d8..765a5f903 100644 --- a/vendor/home/Cargo.toml +++ b/vendor/home/Cargo.toml @@ -3,24 +3,34 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" name = "home" -version = "0.5.3" +version = "0.5.4" authors = ["Brian Anderson "] -include = ["/src", "/Cargo.toml", "/CHANGELOG", "/LICENSE-*", "/README.md"] +include = [ + "/src", + "/Cargo.toml", + "/CHANGELOG", + "/LICENSE-*", + "/README.md", +] description = "Shared definitions of home directories" documentation = "https://docs.rs/home" readme = "README.md" license = "MIT OR Apache-2.0" repository = "https://github.com/brson/home" + [target."cfg(windows)".dependencies.winapi] version = "0.3" -features = ["shlobj", "std", "winerror"] +features = [ + "shlobj", + "std", + "winerror", +] diff --git a/vendor/home/src/env.rs b/vendor/home/src/env.rs new file mode 100644 index 000000000..e47273bc8 --- /dev/null +++ b/vendor/home/src/env.rs @@ -0,0 +1,106 @@ +//! Lower-level utilities for mocking the process environment. + +use std::{ + ffi::OsString, + io, + path::{Path, PathBuf}, +}; + +/// Permits parameterizing the home functions via the _from variants - used for +/// in-process unit testing by rustup. +pub trait Env { + /// Return the path to the the users home dir, or None if any error occurs: + /// see home_inner. + fn home_dir(&self) -> Option; + /// Return the current working directory. + fn current_dir(&self) -> io::Result; + /// Get an environment variable, as per std::env::var_os. + fn var_os(&self, key: &str) -> Option; +} + +/// Implements Env for the OS context, both Unix style and Windows. +/// +/// This is trait permits in-process testing by providing a control point to +/// allow in-process divergence on what is normally process wide state. +/// +/// Implementations should be provided by whatever testing framework the caller +/// is using. Code that is not performing in-process threaded testing requiring +/// isolated rustup/cargo directories does not need this trait or the _from +/// functions. +pub struct OsEnv; +impl Env for OsEnv { + fn home_dir(&self) -> Option { + crate::home_dir_inner() + } + fn current_dir(&self) -> io::Result { + std::env::current_dir() + } + fn var_os(&self, key: &str) -> Option { + std::env::var_os(key) + } +} + +pub const OS_ENV: OsEnv = OsEnv {}; + +/// Returns the path of the current user's home directory from [`Env::home_dir`]. +pub fn home_dir_with_env(env: &dyn Env) -> Option { + env.home_dir() +} + +/// Variant of cargo_home where the environment source is parameterized. This is +/// specifically to support in-process testing scenarios as environment +/// variables and user home metadata are normally process global state. See the +/// [`Env`] trait. +pub fn cargo_home_with_env(env: &dyn Env) -> io::Result { + let cwd = env.current_dir()?; + cargo_home_with_cwd_env(env, &cwd) +} + +/// Variant of cargo_home_with_cwd where the environment source is +/// parameterized. This is specifically to support in-process testing scenarios +/// as environment variables and user home metadata are normally process global +/// state. See the OsEnv trait. +pub fn cargo_home_with_cwd_env(env: &dyn Env, cwd: &Path) -> io::Result { + match env.var_os("CARGO_HOME").filter(|h| !h.is_empty()) { + Some(home) => { + let home = PathBuf::from(home); + if home.is_absolute() { + Ok(home) + } else { + Ok(cwd.join(&home)) + } + } + _ => home_dir_with_env(env) + .map(|p| p.join(".cargo")) + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find cargo home dir")), + } +} + +/// Variant of cargo_home_with_cwd where the environment source is +/// parameterized. This is specifically to support in-process testing scenarios +/// as environment variables and user home metadata are normally process global +/// state. See the OsEnv trait. +pub fn rustup_home_with_env(env: &dyn Env) -> io::Result { + let cwd = env.current_dir()?; + rustup_home_with_cwd_env(env, &cwd) +} + +/// Variant of cargo_home_with_cwd where the environment source is +/// parameterized. This is specifically to support in-process testing scenarios +/// as environment variables and user home metadata are normally process global +/// state. See the OsEnv trait. +pub fn rustup_home_with_cwd_env(env: &dyn Env, cwd: &Path) -> io::Result { + match env.var_os("RUSTUP_HOME").filter(|h| !h.is_empty()) { + Some(home) => { + let home = PathBuf::from(home); + if home.is_absolute() { + Ok(home) + } else { + Ok(cwd.join(&home)) + } + } + _ => home_dir_with_env(env) + .map(|d| d.join(".rustup")) + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find rustup home dir")), + } +} diff --git a/vendor/home/src/lib.rs b/vendor/home/src/lib.rs index ad31d3d2e..ad254ca3b 100644 --- a/vendor/home/src/lib.rs +++ b/vendor/home/src/lib.rs @@ -25,13 +25,14 @@ //! //! [discussion]: https://github.com/rust-lang/rust/pull/46799#issuecomment-361156935 -#![doc(html_root_url = "https://docs.rs/home/0.5.3")] +#![doc(html_root_url = "https://docs.rs/home/0.5.4")] #![deny(rust_2018_idioms)] +pub mod env; + #[cfg(windows)] mod windows; -use std::env; use std::io; use std::path::{Path, PathBuf}; @@ -48,10 +49,9 @@ use std::path::{Path, PathBuf}; /// /// Returns the value of the `USERPROFILE` environment variable if it /// is set and not equal to the empty string. If both do not exist, -/// [`GetUserProfileDirectory`][msdn] is used to return the -/// appropriate path. +/// [`SHGetFolderPathW`][msdn] is used to return the appropriate path. /// -/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectoryw +/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderpathw /// /// # Examples /// @@ -62,7 +62,7 @@ use std::path::{Path, PathBuf}; /// } /// ``` pub fn home_dir() -> Option { - home_dir_inner() + env::home_dir_with_env(&env::OS_ENV) } #[cfg(windows)] @@ -71,7 +71,7 @@ use windows::home_dir_inner; #[cfg(any(unix, target_os = "redox"))] fn home_dir_inner() -> Option { #[allow(deprecated)] - env::home_dir() + std::env::home_dir() } /// Returns the storage directory used by Cargo, often knowns as @@ -102,26 +102,13 @@ fn home_dir_inner() -> Option { /// } /// ``` pub fn cargo_home() -> io::Result { - let cwd = env::current_dir()?; - cargo_home_with_cwd(&cwd) + env::cargo_home_with_env(&env::OS_ENV) } /// Returns the storage directory used by Cargo within `cwd`. /// For more details, see [`cargo_home`](fn.cargo_home.html). pub fn cargo_home_with_cwd(cwd: &Path) -> io::Result { - match env::var_os("CARGO_HOME").filter(|h| !h.is_empty()) { - Some(home) => { - let home = PathBuf::from(home); - if home.is_absolute() { - Ok(home) - } else { - Ok(cwd.join(&home)) - } - } - _ => home_dir() - .map(|p| p.join(".cargo")) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find cargo home dir")), - } + env::cargo_home_with_cwd_env(&env::OS_ENV, cwd) } /// Returns the storage directory used by rustup, often knowns as @@ -152,24 +139,11 @@ pub fn cargo_home_with_cwd(cwd: &Path) -> io::Result { /// } /// ``` pub fn rustup_home() -> io::Result { - let cwd = env::current_dir()?; - rustup_home_with_cwd(&cwd) + env::rustup_home_with_env(&env::OS_ENV) } /// Returns the storage directory used by rustup within `cwd`. /// For more details, see [`rustup_home`](fn.rustup_home.html). pub fn rustup_home_with_cwd(cwd: &Path) -> io::Result { - match env::var_os("RUSTUP_HOME").filter(|h| !h.is_empty()) { - Some(home) => { - let home = PathBuf::from(home); - if home.is_absolute() { - Ok(home) - } else { - Ok(cwd.join(&home)) - } - } - _ => home_dir() - .map(|d| d.join(".rustup")) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find rustup home dir")), - } + env::rustup_home_with_cwd_env(&env::OS_ENV, cwd) } diff --git a/vendor/idna/.cargo-checksum.json b/vendor/idna/.cargo-checksum.json index 01c1655f1..edf5c94ba 100644 --- a/vendor/idna/.cargo-checksum.json +++ b/vendor/idna/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"fa141dcb135262e5fda9f680671699045326d96779bb1acf38d48c70c712bcdf","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","benches/all.rs":"e734b9c9092ed66986725f86cfe90f3756cfddb058af308b796ba494f9beefc2","src/IdnaMappingTable.txt":"87d6553a4b86bc49dcade38bf26b745cd81800eb8af295dc3fb99b4729eaea38","src/lib.rs":"d61b2bfcf4265b9a41eedd1de33ab49ea615e3c06df944321b30c57950a85342","src/make_uts46_mapping_table.py":"917055fa841f813de2bcf79cc79b595da3d5551559ee768db8660ab77cb26c34","src/punycode.rs":"07edf5293bc384a164eebb01bc18fe3d4b2d009b4565a36b74a3030978ea6e04","src/uts46.rs":"40521a01e5b8c38667252d5b1e0141c5a71f63aeae2f451b986792984e633b09","src/uts46_mapping_table.rs":"942fff78147c61da942f5f3a7ff4e90f9d7a00a29285733ac3fc3357eb2ed06f","tests/IdnaTestV2.txt":"c6f3778b0545fd150c8063286c7f5adc901e16557eddccc3751213646d07593d","tests/punycode.rs":"e6fb978f48445d1525a6b97351c41c5393a1612a35f85b9a7f45b8794fce9aba","tests/punycode_tests.json":"3d4ac0cf25984c37b9ce197f5df680a0136f728fb8ec82bc76624e42139eb3a8","tests/tests.rs":"de7425a3e4e6e871255721107803704d1431246601fa9c87105224d88dfe60d6","tests/unit.rs":"be025a7d9bab3bd1ce134c87f9d848269e157b31ca5ba0ea03426c1ac736b69e","tests/uts46.rs":"ca91d48811d366fb9e32d7aa79cfda1261b93c271b6ed7fb5535de9a2500205b"},"package":"418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"} \ No newline at end of file +{"files":{"Cargo.toml":"e8c4cbd1a352ce9085b80ac9fcaa8468a2da84b615adf01e719a3020a0279e4c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"76e972ac0f4ddb116e86e10100132a783931a596e7b9872eaa31be15cd4d751d","benches/all.rs":"e734b9c9092ed66986725f86cfe90f3756cfddb058af308b796ba494f9beefc2","src/IdnaMappingTable.txt":"87d6553a4b86bc49dcade38bf26b745cd81800eb8af295dc3fb99b4729eaea38","src/lib.rs":"498f127759fa79bda0d264f373ab7230cc2c73ef3a7b532d619c2a513abb53ff","src/make_uts46_mapping_table.py":"917055fa841f813de2bcf79cc79b595da3d5551559ee768db8660ab77cb26c34","src/punycode.rs":"07edf5293bc384a164eebb01bc18fe3d4b2d009b4565a36b74a3030978ea6e04","src/uts46.rs":"1a5604c32cf57b50e846b58aaaba94e685ff10975e9d6d82ae953f8cefe9c028","src/uts46_mapping_table.rs":"942fff78147c61da942f5f3a7ff4e90f9d7a00a29285733ac3fc3357eb2ed06f","tests/IdnaTestV2.txt":"c6f3778b0545fd150c8063286c7f5adc901e16557eddccc3751213646d07593d","tests/punycode.rs":"7eb6215fa4c84e6710682d48dffe19e490aea223b554b97c180a7d504b9e492a","tests/punycode_tests.json":"3d4ac0cf25984c37b9ce197f5df680a0136f728fb8ec82bc76624e42139eb3a8","tests/tests.rs":"d205a2bfb29dfee73e014faebd3207a55ef0d40121e6dbd52f5d611b37ac111e","tests/unit.rs":"be025a7d9bab3bd1ce134c87f9d848269e157b31ca5ba0ea03426c1ac736b69e","tests/uts46.rs":"06c97bf7dc20f5372b542fa46922d6dd63fe15e0aa34d799d08df9e3a241aa21"},"package":"e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"} \ No newline at end of file diff --git a/vendor/idna/Cargo.toml b/vendor/idna/Cargo.toml index 138a27162..fa2ed42bc 100644 --- a/vendor/idna/Cargo.toml +++ b/vendor/idna/Cargo.toml @@ -3,21 +3,21 @@ # 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 +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# 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 = "2018" +rust-version = "1.51" name = "idna" -version = "0.2.3" +version = "0.3.0" authors = ["The rust-url developers"] autotests = false description = "IDNA (Internationalizing Domain Names in Applications) and Punycode." -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/servo/rust-url/" [lib] @@ -33,22 +33,21 @@ name = "unit" [[bench]] name = "all" harness = false -[dependencies.matches] -version = "0.1" [dependencies.unicode-bidi] version = "0.3" [dependencies.unicode-normalization] version = "0.1.17" + [dev-dependencies.assert_matches] version = "1.3" [dev-dependencies.bencher] version = "0.1" -[dev-dependencies.rustc-test] -version = "0.3" - [dev-dependencies.serde_json] version = "1.0" + +[dev-dependencies.tester] +version = "0.9" diff --git a/vendor/idna/LICENSE-MIT b/vendor/idna/LICENSE-MIT index 24de6b418..51d5dc7eb 100644 --- a/vendor/idna/LICENSE-MIT +++ b/vendor/idna/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2013-2016 The rust-url developers +Copyright (c) 2013-2022 The rust-url developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/vendor/idna/src/lib.rs b/vendor/idna/src/lib.rs index b87d4a15e..37d638741 100644 --- a/vendor/idna/src/lib.rs +++ b/vendor/idna/src/lib.rs @@ -32,8 +32,9 @@ //! > that minimizes the impact of this transition for client software, //! > allowing client software to access domains that are valid under either system. +#[cfg(test)] #[macro_use] -extern crate matches; +extern crate assert_matches; pub mod punycode; mod uts46; diff --git a/vendor/idna/src/uts46.rs b/vendor/idna/src/uts46.rs index ad798055f..ec2fd0b10 100644 --- a/vendor/idna/src/uts46.rs +++ b/vendor/idna/src/uts46.rs @@ -156,7 +156,7 @@ fn passes_bidi(label: &str, is_bidi_domain: bool) -> bool { // LTR label BidiClass::L => { // Rule 5 - while let Some(c) = chars.next() { + for c in chars.by_ref() { if !matches!( bidi_class(c), BidiClass::L @@ -318,51 +318,48 @@ fn check_validity(label: &str, config: Config, errors: &mut Errors) { // V8: Bidi rules are checked inside `processing()` } -/// http://www.unicode.org/reports/tr46/#Processing -#[allow(clippy::manual_strip)] // introduced in 1.45, MSRV is 1.36 -fn processing( - domain: &str, - config: Config, - normalized: &mut String, - output: &mut String, -) -> Errors { - // Weed out the simple cases: only allow all lowercase ASCII characters and digits where none - // of the labels start with PUNYCODE_PREFIX and labels don't start or end with hyphen. - let (mut prev, mut simple, mut puny_prefix) = ('?', !domain.is_empty(), 0); +// Detect simple cases: all lowercase ASCII characters and digits where none +// of the labels start with PUNYCODE_PREFIX and labels don't start or end with hyphen. +fn is_simple(domain: &str) -> bool { + if domain.is_empty() { + return false; + } + let (mut prev, mut puny_prefix) = ('?', 0); for c in domain.chars() { if c == '.' { if prev == '-' { - simple = false; - break; + return false; } puny_prefix = 0; continue; } else if puny_prefix == 0 && c == '-' { - simple = false; - break; + return false; } else if puny_prefix < 5 { if c == ['x', 'n', '-', '-'][puny_prefix] { puny_prefix += 1; if puny_prefix == 4 { - simple = false; - break; + return false; } } else { puny_prefix = 5; } } if !c.is_ascii_lowercase() && !c.is_ascii_digit() { - simple = false; - break; + return false; } prev = c; } - if simple { - output.push_str(domain); - return Errors::default(); - } + true +} +/// http://www.unicode.org/reports/tr46/#Processing +fn processing( + domain: &str, + config: Config, + normalized: &mut String, + output: &mut String, +) -> Errors { normalized.clear(); let mut errors = Errors::default(); let offset = output.len(); @@ -384,8 +381,8 @@ fn processing( output.push('.'); } first = false; - if label.starts_with(PUNYCODE_PREFIX) { - match decoder.decode(&label[PUNYCODE_PREFIX.len()..]) { + if let Some(remainder) = label.strip_prefix(PUNYCODE_PREFIX) { + match decoder.decode(remainder) { Ok(decode) => { let start = output.len(); output.extend(decode); @@ -396,7 +393,7 @@ fn processing( } if !errors.is_err() { - if !is_nfc(&decoded_label) { + if !is_nfc(decoded_label) { errors.nfc = true; } else { check_validity(decoded_label, non_transitional, &mut errors); @@ -448,11 +445,13 @@ impl Idna { } } - /// http://www.unicode.org/reports/tr46/#ToASCII - #[allow(clippy::wrong_self_convention)] - pub fn to_ascii<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> { - let mut errors = processing(domain, self.config, &mut self.normalized, &mut self.output); - + pub fn to_ascii_inner(&mut self, domain: &str, out: &mut String) -> Errors { + if is_simple(domain) { + out.push_str(domain); + return Errors::default(); + } + let mut errors = processing(domain, self.config, &mut self.normalized, out); + self.output = std::mem::replace(out, String::with_capacity(out.len())); let mut first = true; for label in self.output.split('.') { if !first { @@ -471,6 +470,13 @@ impl Idna { } } } + errors + } + + /// http://www.unicode.org/reports/tr46/#ToASCII + #[allow(clippy::wrong_self_convention)] + pub fn to_ascii<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> { + let mut errors = self.to_ascii_inner(domain, out); if self.config.verify_dns_length { let domain = if out.ends_with('.') { @@ -492,6 +498,10 @@ impl Idna { /// http://www.unicode.org/reports/tr46/#ToUnicode #[allow(clippy::wrong_self_convention)] pub fn to_unicode<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> { + if is_simple(domain) { + out.push_str(domain); + return Errors::default().into(); + } processing(domain, self.config, &mut self.normalized, out).into() } } @@ -555,7 +565,7 @@ impl Config { /// http://www.unicode.org/reports/tr46/#ToASCII pub fn to_ascii(self, domain: &str) -> Result { - let mut result = String::new(); + let mut result = String::with_capacity(domain.len()); let mut codec = Idna::new(self); codec.to_ascii(domain, &mut result).map(|()| result) } diff --git a/vendor/idna/tests/punycode.rs b/vendor/idna/tests/punycode.rs index c0123c639..1a51cbc92 100644 --- a/vendor/idna/tests/punycode.rs +++ b/vendor/idna/tests/punycode.rs @@ -63,9 +63,9 @@ pub fn collect_tests(add_test: &mut F) { }; add_test( test_name, - TestFn::dyn_test_fn(move || { + TestFn::DynTestFn(Box::new(move || { one_test(get_string(&o, "decoded"), get_string(&o, "encoded")) - }), + })), ) } _ => panic!(), diff --git a/vendor/idna/tests/tests.rs b/vendor/idna/tests/tests.rs index 5f0f8cde3..0704c81c1 100644 --- a/vendor/idna/tests/tests.rs +++ b/vendor/idna/tests/tests.rs @@ -1,4 +1,4 @@ -use rustc_test as test; +use tester as test; mod punycode; mod uts46; @@ -8,12 +8,18 @@ fn main() { { let mut add_test = |name, run| { tests.push(test::TestDescAndFn { - desc: test::TestDesc::new(test::DynTestName(name)), + desc: test::TestDesc { + name: test::DynTestName(name), + ignore: false, + should_panic: test::ShouldPanic::No, + allow_fail: false, + test_type: test::TestType::Unknown, + }, testfn: run, }) }; punycode::collect_tests(&mut add_test); uts46::collect_tests(&mut add_test); } - test::test_main(&std::env::args().collect::>(), tests) + test::test_main(&std::env::args().collect::>(), tests, None) } diff --git a/vendor/idna/tests/uts46.rs b/vendor/idna/tests/uts46.rs index 72b5bcec7..bd402ce97 100644 --- a/vendor/idna/tests/uts46.rs +++ b/vendor/idna/tests/uts46.rs @@ -8,6 +8,7 @@ use crate::test::TestFn; use std::char; +use std::fmt::Write; use idna::Errors; @@ -25,10 +26,10 @@ pub fn collect_tests(add_test: &mut F) { }; let mut pieces = line.split(';').map(|x| x.trim()).collect::>(); - let source = unescape(&pieces.remove(0)); + let source = unescape(pieces.remove(0)); // ToUnicode - let mut to_unicode = unescape(&pieces.remove(0)); + let mut to_unicode = unescape(pieces.remove(0)); if to_unicode.is_empty() { to_unicode = source.clone(); } @@ -65,7 +66,7 @@ pub fn collect_tests(add_test: &mut F) { let test_name = format!("UTS #46 line {}", i + 1); add_test( test_name, - TestFn::dyn_test_fn(move || { + TestFn::DynTestFn(Box::new(move || { let config = idna::Config::default() .use_std3_ascii_rules(true) .verify_dns_length(true) @@ -109,7 +110,7 @@ pub fn collect_tests(add_test: &mut F) { to_ascii_t_result, |e| e.starts_with('C') || e == "V2", ); - }), + })), ) } } @@ -160,8 +161,8 @@ fn unescape(input: &str) -> String { match char::from_u32(((c1 * 16 + c2) * 16 + c3) * 16 + c4) { Some(c) => output.push(c), None => { - output - .push_str(&format!("\\u{:X}{:X}{:X}{:X}", c1, c2, c3, c4)); + write!(&mut output, "\\u{:X}{:X}{:X}{:X}", c1, c2, c3, c4) + .expect("Could not write to output"); } }; } diff --git a/vendor/itertools/.cargo-checksum.json b/vendor/itertools/.cargo-checksum.json index cbed44086..a4f2873c5 100644 --- a/vendor/itertools/.cargo-checksum.json +++ b/vendor/itertools/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"7f54a6e7b78dae273c5352ca3472c8e7d4996d42879ffbb8430df37c020c8a6a","Cargo.lock":"74a768ea98da273b20c181728d646b0e59ece19d5738f983ee8804f35a5e6af4","Cargo.toml":"3934329298921fda64203f05a3b194b3a4f009e85fdcb78b46c8a743176e1059","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"6ba6696202f5a848c40f0cdef0ae9282a8edd45b44e5d901160930534427e62d","benches/bench1.rs":"bb06f39db0544b1380cd4929139ccf521a9eecab7ca3f910b9499f965ec0a047","benches/combinations.rs":"51523ee1ca438a56f14711f0b04ee943895062d35859fbe23a2714d2fca3289d","benches/combinations_with_replacement.rs":"11f29160652a2d90ce7ca4b1c339c4457888ab6867e2456ce1c62e3adf9be737","benches/extra/mod.rs":"6ca290d72302a1945078621610b5788060b0de29639decebbdc557a80044aa97","benches/extra/zipslices.rs":"3db9764c21536c541cdf3f93ba2e34f6ab63dd12a9149aa5bd8a4524778176f1","benches/fold_specialization.rs":"5a517bbe29d366a15f6f751660e17ab1aa3e7b21552a1983048c662e34f0d69e","benches/powerset.rs":"6fd9d69a3483b37dc2411f99fb4efa6131577696f2dbdc8d1de9e4d7642fe3a3","benches/tree_fold1.rs":"539232e74f9aaea295a42069ac5af707811e90dc1c71c6e0a9064ffc731999de","benches/tuple_combinations.rs":"16366158743307a0289fc1df423a3cec45009807d410a9fe9922d5b6f8b7d002","benches/tuples.rs":"5a620783ae203e9ff9623d10d2c7fe9911d8b6c811cbad7613afa30e390c759d","examples/iris.data":"596ffd580471ca4d4880f8e439c7281f3b50d8249a5960353cb200b1490f63a0","examples/iris.rs":"1b465ed6a417180913104bc95a545fd9d1a3d67d121871ab737ad87e31b8be37","src/adaptors/coalesce.rs":"11d88d64fc1e3e80fc847cfbff7627e7164a1621e2e989afdd0730f2f3172dca","src/adaptors/map.rs":"241971e856e468d71323071fb4a09867fbcedb83877320be132dc03516fe60e8","src/adaptors/mod.rs":"be7eab70869f4fcf5e0e441ba7646759a39ec86952d54a3df22b60b919572ec3","src/adaptors/multi_product.rs":"742a8a42f2cc2b3840b0397639cb57d87deac8483127012c1f9a0be9c02ff1f1","src/combinations.rs":"fb25babb459389093f886721016c72bf9f00e51d02735f638d871bb3a447ffd0","src/combinations_with_replacement.rs":"3cb719c61a39af0c7e73139e0d1a94e716b69cbe6b046e3ca39150c9995ec7ff","src/concat_impl.rs":"7e14b7c1ad592a40373aec1140ed4cecc04462a9724a8ee663f3e757f457c587","src/cons_tuples_impl.rs":"c253d03b861831c01d62cacc57b49715ee62f6171e69f6886bb5a6ca0863bc3a","src/diff.rs":"a7800e9ce7a87b53ebe2338481335751fb43d44fa6a1ca719aceaaab40e5c8fe","src/duplicates_impl.rs":"663bd10f0a8f49ce0a58ba1c488a70684b61f9636232310fe8ffa2f356961e94","src/either_or_both.rs":"4f17729e9a28508cf60734355d748399c9b05d4df970b75a23e41fe462171464","src/exactly_one_err.rs":"3a72023c689a27fa9ed5e11ff2e32638d548bd327b00c642d5ee1c79e9300f75","src/flatten_ok.rs":"294f313d6e4e34c4e4d03facfd8a15ba92742ba94e609386d76e75d725d4eb14","src/format.rs":"a8192d85c0f9de8e633c202456e3cde0f3bc50f19b6bd8a4b2cfa3ef5123de1a","src/free.rs":"75189fd779017ee2c083e3e75982f1b7d4b51fae99b105a2b2d0e3d2d16dda4f","src/group_map.rs":"f7b02c964f63505d3e36280cfdc1755e05287714201efe983dacf702eee61434","src/groupbylazy.rs":"69829a5990c666cf9dfc7330a1765e0ecb6901a4572f8cda86e81f391af62283","src/grouping_map.rs":"a9f48ed6ba6bf13b16a037f8aaf608c67c6b68dc8949702a07bfeea41471e38e","src/impl_macros.rs":"f3f0865c825dfb8396e0897b9f087c6220099fade36a67e113f5af9102e1347e","src/intersperse.rs":"12c486feaec66931b62007ffd551c72d711963a15019de882d7a4aff71f1c0ae","src/k_smallest.rs":"603eb34314c01769ff7f6def2a24cf7a7b38507e6f3658b7aafc23a3b2e9b322","src/kmerge_impl.rs":"ff34c08b641276df3fcb20874925e6fe0dbf82f6db36f1de17b07b5991b373d7","src/lazy_buffer.rs":"2426f171a839eef12501086ba8da270db46b51749e68562aecc7623d56995c3f","src/lib.rs":"83d043c8af42f7b4b66c6fc5012b8399acd44de44c8d522f7cc4ae806d4462ca","src/merge_join.rs":"8a12376800eb31b124123b0590b302d08aaca71c64bcef89c1aef5d29837038a","src/minmax.rs":"96d3897c28c8c63284d4729becc9ada6855e0953cac6e1bd35cf6f38c50b0ec0","src/multipeek_impl.rs":"8e1ebb6359bd43387c7b6f65e6612845e5673418a39c7bcbdb2c52b50a2d75f5","src/pad_tail.rs":"404e611a3e3e698f7d4eef97a21c3aacd677cadb1f92a48b43bd1f83f183ab10","src/peek_nth.rs":"6a0a51f2f373ce14d3d58595c46464878a14976bf00841a7396c03f9f9ab07ac","src/peeking_take_while.rs":"34985239af5a7bef38fecb1e00f5830f1921b04e6f6e5d25456e701cc3b59e35","src/permutations.rs":"b655e43e78e98a22c3f2be2420d8aa378fc6633ee7cf8b7c6a9630ac882d68a9","src/powerset.rs":"e0ee6b1316b4dd314c1e81502b90ae8113e1cda12168322520c5a65410e584b2","src/process_results_impl.rs":"9ed7fa46c8316238272ef47577387a386c1a109b50377dd3caf4291b6587cb73","src/put_back_n_impl.rs":"821e047fecd6ca0036290029f4febe7638a3abf1faa05e1e747a3bf9d80ff464","src/rciter_impl.rs":"ed4cc5da423e001ed142ed3925a32110189d6e9f5c77606c3fa52762f111f2f6","src/repeatn.rs":"bfc8f9145c9d8a3ea651f012b7d5a8d2fbbcbefdee76eafd098d02e7c54cda90","src/size_hint.rs":"d51d0db24a30c432cb13a2b62d9afb67c3e109e75ab32232f7777803391bcc11","src/sources.rs":"61637f32c2cea2290ecfc1980c0b2d0f68463839ac09bd81006f8258ab8ecaae","src/tee.rs":"665832aa547389a420c3441470ff2494249f0ed2841be0c6a578367fe9dbd381","src/tuple_impl.rs":"039433eddafb0c5f2e4d125035304f5e5f04dd7b537e497af291e40bdb63054e","src/unique_impl.rs":"b5c30a9ca2790e7818f53680aeacee5997c09426fb4a28d2497a8f8414b19e67","src/unziptuple.rs":"ded1fd651d16c6629a49aa68386627addb4ade1ee32bc95929a16bab4f2332d5","src/with_position.rs":"c8a9b3476b3b90986b004a8877c19ff54b4c6800c5ac7ca1458d914036dacfe9","src/zip_eq_impl.rs":"4a41dc6dfe99359585d50ce648bdc85f15276c602048872b1d152e90841d8cad","src/zip_longest.rs":"f7cf5fffc3ca053ee80b410a05b27de1a475021f6de3181aea981010d7e8453f","src/ziptuple.rs":"b3606e1231ac706836cfca67b5b19a88c111a82f2b8649bec72d08b3aa81d783","tests/adaptors_no_collect.rs":"dc69691bed895e6fd3922942ccc7d424a5247b0f79dea74cf8e2f8a8af0bd491","tests/flatten_ok.rs":"b7894874132918b8229c7150b2637511d8e3e14197d8eeb9382d46b2a514efa2","tests/macros_hygiene.rs":"522afa0106e3f11a5149e9218f89c2329e405546d2ef0ea756d6a27e8a0e9ca3","tests/merge_join.rs":"b08c4ee6529d234c68d411a413b8781455d18a1eab17872d1828bb75a4fcf79b","tests/peeking_take_while.rs":"4b1c394e44a9ef9bc0de707ae080b45803db722f79834c20f15b826d7c3f1f2e","tests/quick.rs":"c975132c0a27b07494af03fa978f748c15178f9c9a8d2c647af9b47202f6dac4","tests/specializations.rs":"7a6428a0dbf826bc6adf701803e97283ca6efda9a39595642fb1070c085d52c0","tests/test_core.rs":"cc31f6623ae2e4db1efca649da554c47a60cc13ead5a7a44cfd2265a34344553","tests/test_std.rs":"53bcf0b11e853df71ad44286bff687e7d6f2040bcf800d64ff4d13448dae02c9","tests/tuples.rs":"014e4da776174bfe923270e2a359cd9c95b372fce4b952b8138909d6e2c52762","tests/zip.rs":"4f840d5cdd9021511d8e639d87152bd08b5d12f6192e88072688b0b9100ac912"},"package":"a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"} \ No newline at end of file +{"files":{"CHANGELOG.md":"ed6c781d541c40d4a19eaecd794cadebb94b3f4d51e32367803542c88f0457ee","Cargo.toml":"6dcbab25126c0cdf64f5089156de0d4346914c6d47c557d370b8e20e039ca7d3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"3acfeb07424200ae70bf571ef63a96bae954c298bddf447c9bea0ea9394825cc","benches/bench1.rs":"bb06f39db0544b1380cd4929139ccf521a9eecab7ca3f910b9499f965ec0a047","benches/combinations.rs":"51523ee1ca438a56f14711f0b04ee943895062d35859fbe23a2714d2fca3289d","benches/combinations_with_replacement.rs":"11f29160652a2d90ce7ca4b1c339c4457888ab6867e2456ce1c62e3adf9be737","benches/extra/mod.rs":"6ca290d72302a1945078621610b5788060b0de29639decebbdc557a80044aa97","benches/extra/zipslices.rs":"40e9f68a7c00f8429193fca463caef18851fa49b33355cc136bad3ccc840d655","benches/fold_specialization.rs":"5a517bbe29d366a15f6f751660e17ab1aa3e7b21552a1983048c662e34f0d69e","benches/powerset.rs":"6fd9d69a3483b37dc2411f99fb4efa6131577696f2dbdc8d1de9e4d7642fe3a3","benches/tree_fold1.rs":"539232e74f9aaea295a42069ac5af707811e90dc1c71c6e0a9064ffc731999de","benches/tuple_combinations.rs":"16366158743307a0289fc1df423a3cec45009807d410a9fe9922d5b6f8b7d002","benches/tuples.rs":"5a620783ae203e9ff9623d10d2c7fe9911d8b6c811cbad7613afa30e390c759d","clippy.toml":"33ffb83bbddb772575b3aa565b7136a8158ee386c216ffc2588fed9e83fa3826","examples/iris.data":"596ffd580471ca4d4880f8e439c7281f3b50d8249a5960353cb200b1490f63a0","examples/iris.rs":"1b465ed6a417180913104bc95a545fd9d1a3d67d121871ab737ad87e31b8be37","src/adaptors/coalesce.rs":"a0073325d40f297d29101538d18a267aef81889a999338dc09cb43a31cb4ec8b","src/adaptors/map.rs":"241971e856e468d71323071fb4a09867fbcedb83877320be132dc03516fe60e8","src/adaptors/mod.rs":"7f3bd7d011a348ce5e4bea486ef2e6346b64c7fe27540334d56d3f147f981d59","src/adaptors/multi_product.rs":"bb43e6dce68c815c21006d5b01c56e038d54b0c3bb8ee6bb8a4de11e2952c7ad","src/combinations.rs":"fb25babb459389093f886721016c72bf9f00e51d02735f638d871bb3a447ffd0","src/combinations_with_replacement.rs":"463011a574facbdd84278386b533a90e4dd517f0417e05adb82d182049db1f50","src/concat_impl.rs":"03b1ed61cbed242c286c3c4c5c848dbd57e02ab83fcef264f3a592b58107f324","src/cons_tuples_impl.rs":"c253d03b861831c01d62cacc57b49715ee62f6171e69f6886bb5a6ca0863bc3a","src/diff.rs":"a7800e9ce7a87b53ebe2338481335751fb43d44fa6a1ca719aceaaab40e5c8fe","src/duplicates_impl.rs":"f62fe4b642f501f785721ce5a505cf622a771e457210726dd0fb8b30be7ebbbc","src/either_or_both.rs":"76b13fbfac6bc959b4c1d8b7c99ce51726e95f994ca5429477e523a3d3950e4a","src/exactly_one_err.rs":"aa50081f6a31b5109b30e3ed305e3ec2413c6908dedc8990ec5378a99cee2b39","src/extrema_set.rs":"2a25b0b86eed2fd5d05622d591a3085cab823973d450816c2c3b8cb76e9c187e","src/flatten_ok.rs":"fe209fd886ecd9cb98d99625aa0c7274af7e644eff4a10de15b4dec8bbbc934a","src/format.rs":"a8192d85c0f9de8e633c202456e3cde0f3bc50f19b6bd8a4b2cfa3ef5123de1a","src/free.rs":"dfc57b7f56a08d4986a96b679018b41346576a7a34b668e008cc01109e728750","src/group_map.rs":"f7b02c964f63505d3e36280cfdc1755e05287714201efe983dacf702eee61434","src/groupbylazy.rs":"4f2181c022a45ff8444597708861fc6863eceb6f7555ea81cf3eeba19b492971","src/grouping_map.rs":"cbc45ac563345c96f3ac50c78f73c83d870523436a7ab88c1c9a685d204461d3","src/impl_macros.rs":"4f829b458873bed556f1aff2ae4e88dbd576766e2b5bcc07ff3ac8756758e6f4","src/intersperse.rs":"b9717242495846a4a979c95d93d5681caccb7c07a0d889eab763ad3d49a46125","src/k_smallest.rs":"603eb34314c01769ff7f6def2a24cf7a7b38507e6f3658b7aafc23a3b2e9b322","src/kmerge_impl.rs":"a347b0f6fa7715afd8a54d85ce139ed5b14c9e58a16c2b3648f5b288fdb5375f","src/lazy_buffer.rs":"834f6ef7fdf9f00c8a6329beb38eaefb706847ceeec309c221dce705c2c1e05b","src/lib.rs":"fadb0045279aafe8e8cccb45fadc383c7b358197b83c9c38fba87ada4cb2f84a","src/merge_join.rs":"1016113f6c983a9498bae5dc0570190437e1357b3333f6e19ea95c88599a1225","src/minmax.rs":"96d3897c28c8c63284d4729becc9ada6855e0953cac6e1bd35cf6f38c50b0ec0","src/multipeek_impl.rs":"35162bca4456bfa20a08e8d40e4d1cc6783dc662778789fdcded60371e975122","src/pad_tail.rs":"04be2ca73abb85815b06b5524c99d6feb2919180c486a4646f9cc6c87462f67b","src/peek_nth.rs":"6a0a51f2f373ce14d3d58595c46464878a14976bf00841a7396c03f9f9ab07ac","src/peeking_take_while.rs":"2b1b77c8882be32cfd76e973d303aa62f73370efd470c60764add0cdcca524d5","src/permutations.rs":"97831e7e26904c3cae68c97e74f7c6981ceb2fb2f2217282a0e5e54083a565fc","src/powerset.rs":"e0ee6b1316b4dd314c1e81502b90ae8113e1cda12168322520c5a65410e584b2","src/process_results_impl.rs":"9ed7fa46c8316238272ef47577387a386c1a109b50377dd3caf4291b6587cb73","src/put_back_n_impl.rs":"821e047fecd6ca0036290029f4febe7638a3abf1faa05e1e747a3bf9d80ff464","src/rciter_impl.rs":"5b156082ef2d25a94a4ad01d94cba2813c4b3e72e212515a8ad0fc8588f8045d","src/repeatn.rs":"bfc8f9145c9d8a3ea651f012b7d5a8d2fbbcbefdee76eafd098d02e7c54cda90","src/size_hint.rs":"021e57aad7df8f1e70ef588e9e9b8a1695aab183b1098f1848561f96c5dc9bcb","src/sources.rs":"61637f32c2cea2290ecfc1980c0b2d0f68463839ac09bd81006f8258ab8ecaae","src/tee.rs":"665832aa547389a420c3441470ff2494249f0ed2841be0c6a578367fe9dbd381","src/tuple_impl.rs":"00a9b61942425fb477b9691c3348646c0f9f534ff94f6321027f38c61ce2478c","src/unique_impl.rs":"3b89cdd668b74cc0a0eabb1522489e2305a0d2d8da25d6a1884e8626bbdb5959","src/unziptuple.rs":"84b50e5d29b9ddbf21a46a1cc2fd7877729c7f7da9bdc8ae1966dbaf2d2f6f60","src/with_position.rs":"c8a9b3476b3b90986b004a8877c19ff54b4c6800c5ac7ca1458d914036dacfe9","src/zip_eq_impl.rs":"4a41dc6dfe99359585d50ce648bdc85f15276c602048872b1d152e90841d8cad","src/zip_longest.rs":"f7cf5fffc3ca053ee80b410a05b27de1a475021f6de3181aea981010d7e8453f","src/ziptuple.rs":"7f9df12bf6556f382bbd4ad8cf17eb8b60c1c47fadbce016141133ba0f3384a1","tests/adaptors_no_collect.rs":"f459f36d54f5d475b2b2e83f5a1c98109c15062756ae822fa379486f3eeed666","tests/flatten_ok.rs":"b7894874132918b8229c7150b2637511d8e3e14197d8eeb9382d46b2a514efa2","tests/macros_hygiene.rs":"522afa0106e3f11a5149e9218f89c2329e405546d2ef0ea756d6a27e8a0e9ca3","tests/merge_join.rs":"b08c4ee6529d234c68d411a413b8781455d18a1eab17872d1828bb75a4fcf79b","tests/peeking_take_while.rs":"4b1c394e44a9ef9bc0de707ae080b45803db722f79834c20f15b826d7c3f1f2e","tests/quick.rs":"6fcc0649b9270f024b169b1f499dd4cc7fecb0c9aec0dfc155b264916cc626e7","tests/specializations.rs":"fdd16dc663330033fedcc478609b393d4aa369dc07dc8cda31a75219fb793087","tests/test_core.rs":"32576ba90aa8e5db985b6e6ffe30e3046bc6a11d392db8f6b4bdd2ba48d9b24d","tests/test_std.rs":"f28a78a1912c950e7c37be1e82867e70dc585d60afecdebc7a97965194eee8e6","tests/tuples.rs":"014e4da776174bfe923270e2a359cd9c95b372fce4b952b8138909d6e2c52762","tests/zip.rs":"99af365fe6054ef1c6089d3e604e34da8fea66e55861ae4be9e7336ec8de4b56"},"package":"b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"} \ No newline at end of file diff --git a/vendor/itertools/CHANGELOG.md b/vendor/itertools/CHANGELOG.md index 5e2032c4c..d2b40b5db 100644 --- a/vendor/itertools/CHANGELOG.md +++ b/vendor/itertools/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.10.4 + - Add `EitherOrBoth::or` and `EitherOrBoth::or_else` (#593) + - Add `min_set`, `max_set` et al. (#613, #323) + - Use `either/use_std` (#628) + - Documentation fixes (#612, #625, #632, #633, #634, #638) + - Code maintenance (#623, #624, #627, #630) + ## 0.10.2 - Add `Itertools::multiunzip` (#362, #565) - Add `intersperse` and `intersperse_with` free functions (#555) diff --git a/vendor/itertools/Cargo.lock b/vendor/itertools/Cargo.lock deleted file mode 100644 index fecfb2070..000000000 --- a/vendor/itertools/Cargo.lock +++ /dev/null @@ -1,726 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "bstr" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - -[[package]] -name = "cast" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374" -dependencies = [ - "rustc_version", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - -[[package]] -name = "criterion" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools 0.10.0", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" -dependencies = [ - "cast", - "itertools 0.9.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "half" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" - -[[package]] -name = "hermit-abi" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -dependencies = [ - "libc", -] - -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.3" -dependencies = [ - "criterion", - "either", - "paste", - "permutohedron", - "quickcheck", - "rand", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "js-sys" -version = "0.3.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.96" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5600b4e6efc5421841a2138a6b082e07fe12f9aaa12783d50e5d13325b26b4fc" - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memchr" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "paste" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" - -[[package]] -name = "permutohedron" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "plotters" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" - -[[package]] -name = "plotters-svg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "proc-macro2" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quickcheck" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" -dependencies = [ - "rand", - "rand_core", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" - -[[package]] -name = "serde_cbor" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" -dependencies = [ - "half", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasm-bindgen" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" - -[[package]] -name = "web-sys" -version = "0.3.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/vendor/itertools/Cargo.toml b/vendor/itertools/Cargo.toml index 525cae5f3..40be7e48f 100644 --- a/vendor/itertools/Cargo.toml +++ b/vendor/itertools/Cargo.toml @@ -13,7 +13,7 @@ [package] edition = "2018" name = "itertools" -version = "0.10.3" +version = "0.10.5" authors = ["bluss"] exclude = ["/bors.toml"] description = "Extra iterator adaptors, iterator methods, free functions, and macros." @@ -85,4 +85,4 @@ version = "0.7" [features] default = ["use_std"] use_alloc = [] -use_std = ["use_alloc"] +use_std = ["use_alloc", "either/use_std"] diff --git a/vendor/itertools/README.md b/vendor/itertools/README.md index 4cc3f8fd3..a911127f4 100644 --- a/vendor/itertools/README.md +++ b/vendor/itertools/README.md @@ -11,7 +11,7 @@ How to use with Cargo: ```toml [dependencies] -itertools = "0.10.2" +itertools = "0.10.5" ``` How to use in your crate: diff --git a/vendor/itertools/benches/extra/zipslices.rs b/vendor/itertools/benches/extra/zipslices.rs index 8bf3967f5..633be5906 100644 --- a/vendor/itertools/benches/extra/zipslices.rs +++ b/vendor/itertools/benches/extra/zipslices.rs @@ -3,7 +3,7 @@ use std::cmp; // Note: There are different ways to implement ZipSlices. // This version performed the best in benchmarks. // -// I also implemented a version with three pointes (tptr, tend, uptr), +// I also implemented a version with three pointers (tptr, tend, uptr), // that mimiced slice::Iter and only checked bounds by using tptr == tend, // but that was inferior to this solution. diff --git a/vendor/itertools/clippy.toml b/vendor/itertools/clippy.toml new file mode 100644 index 000000000..0a5485386 --- /dev/null +++ b/vendor/itertools/clippy.toml @@ -0,0 +1 @@ +msrv = "1.36.0" diff --git a/vendor/itertools/src/adaptors/coalesce.rs b/vendor/itertools/src/adaptors/coalesce.rs index b1aff6e27..3df7cc582 100644 --- a/vendor/itertools/src/adaptors/coalesce.rs +++ b/vendor/itertools/src/adaptors/coalesce.rs @@ -3,6 +3,7 @@ use std::iter::FusedIterator; use crate::size_hint; +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct CoalesceBy where I: Iterator, @@ -86,7 +87,6 @@ impl, T> FusedIterator for Coalesc /// An iterator adaptor that may join together adjacent elements. /// /// See [`.coalesce()`](crate::Itertools::coalesce) for more information. -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub type Coalesce = CoalesceBy::Item>; impl CoalescePredicate for F @@ -113,7 +113,6 @@ where /// An iterator adaptor that removes repeated duplicates, determining equality using a comparison function. /// /// See [`.dedup_by()`](crate::Itertools::dedup_by) or [`.dedup()`](crate::Itertools::dedup) for more information. -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub type DedupBy = CoalesceBy, ::Item>; #[derive(Clone)] @@ -186,7 +185,6 @@ where /// /// See [`.dedup_by_with_count()`](crate::Itertools::dedup_by_with_count) or /// [`.dedup_with_count()`](crate::Itertools::dedup_with_count) for more information. -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub type DedupByWithCount = CoalesceBy, (usize, ::Item)>; diff --git a/vendor/itertools/src/adaptors/mod.rs b/vendor/itertools/src/adaptors/mod.rs index 2010f535b..1695bbd65 100644 --- a/vendor/itertools/src/adaptors/mod.rs +++ b/vendor/itertools/src/adaptors/mod.rs @@ -35,9 +35,7 @@ pub struct Interleave { /// Create an iterator that interleaves elements in `i` and `j`. /// -/// [`IntoIterator`] enabled version of `i.interleave(j)`. -/// -/// See [`.interleave()`](crate::Itertools::interleave) for more information. +/// [`IntoIterator`] enabled version of `[Itertools::interleave]`. pub fn interleave(i: I, j: J) -> Interleave<::IntoIter, ::IntoIter> where I: IntoIterator, J: IntoIterator @@ -210,7 +208,7 @@ impl PutBack /// If a value is already in the put back slot, it is overwritten. #[inline] pub fn put_back(&mut self, x: I::Item) { - self.top = Some(x) + self.top = Some(x); } } @@ -329,12 +327,7 @@ impl Iterator for Product } Some(x) => x }; - match self.a_cur { - None => None, - Some(ref a) => { - Some((a.clone(), elt_b)) - } - } + self.a_cur.as_ref().map(|a| (a.clone(), elt_b)) } fn size_hint(&self) -> (usize, Option) { @@ -492,7 +485,6 @@ impl MergePredicate for MergeLte { /// Iterator element type is `I::Item`. /// /// See [`.merge()`](crate::Itertools::merge_by) for more information. -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub type Merge = MergeBy; /// Create an iterator that merges elements in `i` and `j`. diff --git a/vendor/itertools/src/adaptors/multi_product.rs b/vendor/itertools/src/adaptors/multi_product.rs index 30650eda6..0b3840698 100644 --- a/vendor/itertools/src/adaptors/multi_product.rs +++ b/vendor/itertools/src/adaptors/multi_product.rs @@ -40,7 +40,7 @@ pub fn multi_cartesian_product(iters: H) -> MultiProduct< where I: Iterator + Clone, I::Item: Clone @@ -50,7 +50,7 @@ struct MultiProductIter iter_orig: I, } -/// Holds the current state during an iteration of a MultiProduct. +/// Holds the current state during an iteration of a `MultiProduct`. #[derive(Debug)] enum MultiProductIterState { StartOfIter, diff --git a/vendor/itertools/src/combinations_with_replacement.rs b/vendor/itertools/src/combinations_with_replacement.rs index 81b13f130..0fec9671a 100644 --- a/vendor/itertools/src/combinations_with_replacement.rs +++ b/vendor/itertools/src/combinations_with_replacement.rs @@ -64,7 +64,7 @@ where // If this is the first iteration, return early if self.first { // In empty edge cases, stop iterating immediately - return if self.indices.len() != 0 && !self.pool.get_next() { + return if !(self.indices.is_empty() || self.pool.get_next()) { None // Otherwise, yield the initial state } else { @@ -92,7 +92,7 @@ where // We need to update the rightmost non-max value // and all those to the right for indices_index in increment_from..self.indices.len() { - self.indices[indices_index] = increment_value + self.indices[indices_index] = increment_value; } Some(self.current()) } diff --git a/vendor/itertools/src/concat_impl.rs b/vendor/itertools/src/concat_impl.rs index 450f7fce1..f022ec90a 100644 --- a/vendor/itertools/src/concat_impl.rs +++ b/vendor/itertools/src/concat_impl.rs @@ -18,5 +18,6 @@ pub fn concat(iterable: I) -> I::Item where I: IntoIterator, I::Item: Extend<<::Item as IntoIterator>::Item> + IntoIterator + Default { - iterable.into_iter().fold1(|mut a, b| { a.extend(b); a }).unwrap_or_else(<_>::default) + #[allow(deprecated)] //TODO: once msrv hits 1.51. replace `fold1` with `reduce` + iterable.into_iter().fold1(|mut a, b| { a.extend(b); a }).unwrap_or_default() } diff --git a/vendor/itertools/src/duplicates_impl.rs b/vendor/itertools/src/duplicates_impl.rs index 640d4818c..28eda44a9 100644 --- a/vendor/itertools/src/duplicates_impl.rs +++ b/vendor/itertools/src/duplicates_impl.rs @@ -188,7 +188,6 @@ mod private { /// An iterator adapter to filter for duplicate elements. /// /// See [`.duplicates_by()`](crate::Itertools::duplicates_by) for more information. -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub type DuplicatesBy = private::DuplicatesBy>; /// Create a new `DuplicatesBy` iterator. diff --git a/vendor/itertools/src/either_or_both.rs b/vendor/itertools/src/either_or_both.rs index 28d1df757..ef3985f75 100644 --- a/vendor/itertools/src/either_or_both.rs +++ b/vendor/itertools/src/either_or_both.rs @@ -164,6 +164,33 @@ impl EitherOrBoth { } } + /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present. + /// Otherwise, returns the wrapped value for the present element, and the supplied + /// value for the other. The first (`l`) argument is used for a missing `Left` + /// value. The second (`r`) argument is used for a missing `Right` value. + /// + /// Arguments passed to `or` are eagerly evaluated; if you are passing + /// the result of a function call, it is recommended to use [`or_else`], + /// which is lazily evaluated. + /// + /// [`or_else`]: EitherOrBoth::or_else + /// + /// # Examples + /// + /// ``` + /// # use itertools::EitherOrBoth; + /// assert_eq!(EitherOrBoth::Both("tree", 1).or("stone", 5), ("tree", 1)); + /// assert_eq!(EitherOrBoth::Left("tree").or("stone", 5), ("tree", 5)); + /// assert_eq!(EitherOrBoth::Right(1).or("stone", 5), ("stone", 1)); + /// ``` + pub fn or(self, l: A, r: B) -> (A, B) { + match self { + Left(inner_l) => (inner_l, r), + Right(inner_r) => (l, inner_r), + Both(inner_l, inner_r) => (inner_l, inner_r), + } + } + /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present. /// Otherwise, returns the wrapped value for the present element, and the [`default`](Default::default) /// for the other. @@ -178,6 +205,28 @@ impl EitherOrBoth { EitherOrBoth::Both(l, r) => (l, r), } } + + /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present. + /// Otherwise, returns the wrapped value for the present element, and computes the + /// missing value with the supplied closure. The first argument (`l`) is used for a + /// missing `Left` value. The second argument (`r`) is used for a missing `Right` value. + /// + /// # Examples + /// + /// ``` + /// # use itertools::EitherOrBoth; + /// let k = 10; + /// assert_eq!(EitherOrBoth::Both("tree", 1).or_else(|| "stone", || 2 * k), ("tree", 1)); + /// assert_eq!(EitherOrBoth::Left("tree").or_else(|| "stone", || 2 * k), ("tree", 20)); + /// assert_eq!(EitherOrBoth::Right(1).or_else(|| "stone", || 2 * k), ("stone", 1)); + /// ``` + pub fn or_else A, R: FnOnce() -> B>(self, l: L, r: R) -> (A, B) { + match self { + Left(inner_l) => (inner_l, r()), + Right(inner_r) => (l(), inner_r), + Both(inner_l, inner_r) => (inner_l, inner_r), + } + } } impl EitherOrBoth { diff --git a/vendor/itertools/src/exactly_one_err.rs b/vendor/itertools/src/exactly_one_err.rs index 63485c993..c54ae77ca 100644 --- a/vendor/itertools/src/exactly_one_err.rs +++ b/vendor/itertools/src/exactly_one_err.rs @@ -11,10 +11,10 @@ use crate::size_hint; /// Iterator returned for the error case of `IterTools::exactly_one()` /// This iterator yields exactly the same elements as the input iterator. /// -/// During the execution of exactly_one the iterator must be mutated. This wrapper +/// During the execution of `exactly_one` the iterator must be mutated. This wrapper /// effectively "restores" the state of the input iterator when it's handed back. /// -/// This is very similar to PutBackN except this iterator only supports 0-2 elements and does not +/// This is very similar to `PutBackN` except this iterator only supports 0-2 elements and does not /// use a `Vec`. #[derive(Clone)] pub struct ExactlyOneError diff --git a/vendor/itertools/src/extrema_set.rs b/vendor/itertools/src/extrema_set.rs new file mode 100644 index 000000000..ae128364c --- /dev/null +++ b/vendor/itertools/src/extrema_set.rs @@ -0,0 +1,48 @@ +use std::cmp::Ordering; + +/// Implementation guts for `min_set`, `min_set_by`, and `min_set_by_key`. +pub fn min_set_impl( + mut it: I, + mut key_for: F, + mut compare: Compare, +) -> Vec +where + I: Iterator, + F: FnMut(&I::Item) -> K, + Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering, +{ + match it.next() { + None => Vec::new(), + Some(element) => { + let mut current_key = key_for(&element); + let mut result = vec![element]; + it.for_each(|element| { + let key = key_for(&element); + match compare(&element, &result[0], &key, ¤t_key) { + Ordering::Less => { + result.clear(); + result.push(element); + current_key = key; + } + Ordering::Equal => { + result.push(element); + } + Ordering::Greater => {} + } + }); + result + } + } +} + +/// Implementation guts for `ax_set`, `max_set_by`, and `max_set_by_key`. +pub fn max_set_impl(it: I, key_for: F, mut compare: Compare) -> Vec +where + I: Iterator, + F: FnMut(&I::Item) -> K, + Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering, +{ + min_set_impl(it, key_for, |it1, it2, key1, key2| { + compare(it2, it1, key2, key1) + }) +} diff --git a/vendor/itertools/src/flatten_ok.rs b/vendor/itertools/src/flatten_ok.rs index d46bbde4e..21ae1f722 100644 --- a/vendor/itertools/src/flatten_ok.rs +++ b/vendor/itertools/src/flatten_ok.rs @@ -44,11 +44,11 @@ where if let Some(inner) = &mut self.inner_front { if let Some(item) = inner.next() { return Some(Ok(item)); - } else { - // This is necessary for the iterator to implement `FusedIterator` - // with only the orginal iterator being fused. - self.inner_front = None; } + + // This is necessary for the iterator to implement `FusedIterator` + // with only the original iterator being fused. + self.inner_front = None; } match self.iter.next() { @@ -59,11 +59,11 @@ where if let Some(inner) = &mut self.inner_back { if let Some(item) = inner.next() { return Some(Ok(item)); - } else { - // This is necessary for the iterator to implement `FusedIterator` - // with only the orginal iterator being fused. - self.inner_back = None; } + + // This is necessary for the iterator to implement `FusedIterator` + // with only the original iterator being fused. + self.inner_back = None; } else { return None; } @@ -103,11 +103,11 @@ where if let Some(inner) = &mut self.inner_back { if let Some(item) = inner.next_back() { return Some(Ok(item)); - } else { - // This is necessary for the iterator to implement `FusedIterator` - // with only the orginal iterator being fused. - self.inner_back = None; } + + // This is necessary for the iterator to implement `FusedIterator` + // with only the original iterator being fused. + self.inner_back = None; } match self.iter.next_back() { @@ -118,11 +118,11 @@ where if let Some(inner) = &mut self.inner_front { if let Some(item) = inner.next_back() { return Some(Ok(item)); - } else { - // This is necessary for the iterator to implement `FusedIterator` - // with only the orginal iterator being fused. - self.inner_front = None; } + + // This is necessary for the iterator to implement `FusedIterator` + // with only the original iterator being fused. + self.inner_front = None; } else { return None; } @@ -138,7 +138,6 @@ where T: IntoIterator, T::IntoIter: Clone, { - #[inline] clone_fields!(iter, inner_front, inner_back); } diff --git a/vendor/itertools/src/free.rs b/vendor/itertools/src/free.rs index 667403040..19e3e2869 100644 --- a/vendor/itertools/src/free.rs +++ b/vendor/itertools/src/free.rs @@ -105,18 +105,23 @@ pub fn rev(iterable: I) -> iter::Rev iterable.into_iter().rev() } -/// Iterate `i` and `j` in lock step. +/// Converts the arguments to iterators and zips them. /// /// [`IntoIterator`] enabled version of [`Iterator::zip`]. +/// +/// ## Example /// /// ``` /// use itertools::zip; /// -/// let data = [1, 2, 3, 4, 5]; -/// for (a, b) in zip(&data, &data[1..]) { -/// /* loop body */ +/// let mut result: Vec<(i32, char)> = Vec::new(); +/// +/// for (a, b) in zip(&[1, 2, 3, 4, 5], &['a', 'b', 'c']) { +/// result.push((*a, *b)); /// } +/// assert_eq!(result, vec![(1, 'a'),(2, 'b'),(3, 'c')]); /// ``` +#[deprecated(note="Use [std::iter::zip](https://doc.rust-lang.org/std/iter/fn.zip.html) instead", since="0.10.4")] pub fn zip(i: I, j: J) -> Zip where I: IntoIterator, J: IntoIterator @@ -124,16 +129,21 @@ pub fn zip(i: I, j: J) -> Zip i.into_iter().zip(j) } -/// Create an iterator that first iterates `i` and then `j`. + +/// Takes two iterables and creates a new iterator over both in sequence. /// /// [`IntoIterator`] enabled version of [`Iterator::chain`]. /// +/// ## Example /// ``` /// use itertools::chain; +/// +/// let mut result:Vec = Vec::new(); /// -/// for elt in chain(&[1, 2, 3], &[4]) { -/// /* loop body */ +/// for element in chain(&[1, 2, 3], &[4]) { +/// result.push(*element); /// } +/// assert_eq!(result, vec![1, 2, 3, 4]); /// ``` pub fn chain(i: I, j: J) -> iter::Chain<::IntoIter, ::IntoIter> where I: IntoIterator, @@ -239,7 +249,7 @@ pub fn min(iterable: I) -> Option } -/// Combine all iterator elements into one String, seperated by `sep`. +/// Combine all iterator elements into one String, separated by `sep`. /// /// [`IntoIterator`] enabled version of [`Itertools::join`]. /// diff --git a/vendor/itertools/src/groupbylazy.rs b/vendor/itertools/src/groupbylazy.rs index 91c52ea59..a5a321df4 100644 --- a/vendor/itertools/src/groupbylazy.rs +++ b/vendor/itertools/src/groupbylazy.rs @@ -1,13 +1,13 @@ use std::cell::{Cell, RefCell}; use alloc::vec::{self, Vec}; -/// A trait to unify FnMut for GroupBy with the chunk key in IntoChunks +/// A trait to unify `FnMut` for `GroupBy` with the chunk key in `IntoChunks` trait KeyFunction { type Key; fn call_mut(&mut self, arg: A) -> Self::Key; } -impl<'a, A, K, F: ?Sized> KeyFunction for F +impl KeyFunction for F where F: FnMut(A) -> K { type Key = K; @@ -18,7 +18,7 @@ impl<'a, A, K, F: ?Sized> KeyFunction for F } -/// ChunkIndex acts like the grouping key function for IntoChunks +/// `ChunkIndex` acts like the grouping key function for `IntoChunks` #[derive(Debug)] struct ChunkIndex { size: usize, @@ -37,7 +37,7 @@ impl ChunkIndex { } } -impl<'a, A> KeyFunction for ChunkIndex { +impl KeyFunction for ChunkIndex { type Key = usize; #[inline(always)] fn call_mut(&mut self, _arg: A) -> Self::Key { @@ -330,7 +330,7 @@ impl GroupBy /// `client`: Index of group fn drop_group(&self, client: usize) { - self.inner.borrow_mut().drop_group(client) + self.inner.borrow_mut().drop_group(client); } } @@ -482,7 +482,7 @@ impl IntoChunks /// `client`: Index of chunk fn drop_group(&self, client: usize) { - self.inner.borrow_mut().drop_group(client) + self.inner.borrow_mut().drop_group(client); } } diff --git a/vendor/itertools/src/grouping_map.rs b/vendor/itertools/src/grouping_map.rs index be22ec849..bb5b582c9 100644 --- a/vendor/itertools/src/grouping_map.rs +++ b/vendor/itertools/src/grouping_map.rs @@ -39,7 +39,6 @@ pub fn new(iter: I) -> GroupingMap /// `GroupingMapBy` is an intermediate struct for efficient group-and-fold operations. /// /// See [`GroupingMap`] for more informations. -#[must_use = "GroupingMapBy is lazy and do nothing unless consumed"] pub type GroupingMapBy = GroupingMap>; /// `GroupingMap` is an intermediate struct for efficient group-and-fold operations. @@ -290,7 +289,7 @@ impl GroupingMap where F: FnMut(&K, &V) -> CK, CK: Ord, { - self.max_by(|key, v1, v2| f(key, &v1).cmp(&f(key, &v2))) + self.max_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2))) } /// Groups elements from the `GroupingMap` source by key and finds the minimum of each group. @@ -368,7 +367,7 @@ impl GroupingMap where F: FnMut(&K, &V) -> CK, CK: Ord, { - self.min_by(|key, v1, v2| f(key, &v1).cmp(&f(key, &v2))) + self.min_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2))) } /// Groups elements from the `GroupingMap` source by key and find the maximum and minimum of @@ -481,7 +480,7 @@ impl GroupingMap where F: FnMut(&K, &V) -> CK, CK: Ord, { - self.minmax_by(|key, v1, v2| f(key, &v1).cmp(&f(key, &v2))) + self.minmax_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2))) } /// Groups elements from the `GroupingMap` source by key and sums them. diff --git a/vendor/itertools/src/impl_macros.rs b/vendor/itertools/src/impl_macros.rs index 5772baeb6..a029843b0 100644 --- a/vendor/itertools/src/impl_macros.rs +++ b/vendor/itertools/src/impl_macros.rs @@ -15,6 +15,7 @@ macro_rules! debug_fmt_fields { macro_rules! clone_fields { ($($field:ident),*) => { + #[inline] // TODO is this sensible? fn clone(&self) -> Self { Self { $($field: self.$field.clone(),)* diff --git a/vendor/itertools/src/intersperse.rs b/vendor/itertools/src/intersperse.rs index 2c660d492..10a3a5389 100644 --- a/vendor/itertools/src/intersperse.rs +++ b/vendor/itertools/src/intersperse.rs @@ -55,7 +55,7 @@ pub struct IntersperseWith peek: Option, } -/// Create a new IntersperseWith iterator +/// Create a new `IntersperseWith` iterator pub fn intersperse_with(iter: I, elt: ElemF) -> IntersperseWith where I: Iterator, { @@ -107,8 +107,7 @@ impl Iterator for IntersperseWith self.iter.fold(accum, |accum, x| { let accum = f(accum, element.generate()); - let accum = f(accum, x); - accum + f(accum, x) }) } } diff --git a/vendor/itertools/src/kmerge_impl.rs b/vendor/itertools/src/kmerge_impl.rs index bd56b0317..509d5fc6a 100644 --- a/vendor/itertools/src/kmerge_impl.rs +++ b/vendor/itertools/src/kmerge_impl.rs @@ -80,7 +80,7 @@ fn sift_down(heap: &mut [T], index: usize, mut less_than: S) // that wouldn't be predicted if present while child + 1 < heap.len() { // pick the smaller of the two children - // use aritmethic to avoid an unpredictable branch + // use arithmetic to avoid an unpredictable branch child += less_than(&heap[child+1], &heap[child]) as usize; // sift down is done if we are already in order @@ -104,7 +104,6 @@ fn sift_down(heap: &mut [T], index: usize, mut less_than: S) /// Iterator element type is `I::Item`. /// /// See [`.kmerge()`](crate::Itertools::kmerge) for more information. -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub type KMerge = KMergeBy; pub trait KMergePredicate { @@ -129,7 +128,7 @@ implbool> KMergePredicate for F { /// Create an iterator that merges elements of the contained iterators using /// the ordering function. /// -/// Equivalent to `iterable.into_iter().kmerge()`. +/// [`IntoIterator`] enabled version of [`Itertools::kmerge`]. /// /// ``` /// use itertools::kmerge; @@ -170,7 +169,7 @@ impl fmt::Debug for KMergeBy /// Create an iterator that merges elements of the contained iterators. /// -/// Equivalent to `iterable.into_iter().kmerge_by(less_than)`. +/// [`IntoIterator`] enabled version of [`Itertools::kmerge_by`]. pub fn kmerge_by(iterable: I, mut less_than: F) -> KMergeBy<::IntoIter, F> where I: IntoIterator, @@ -214,6 +213,7 @@ impl Iterator for KMergeBy } fn size_hint(&self) -> (usize, Option) { + #[allow(deprecated)] //TODO: once msrv hits 1.51. replace `fold1` with `reduce` self.heap.iter() .map(|i| i.size_hint()) .fold1(size_hint::add) diff --git a/vendor/itertools/src/lazy_buffer.rs b/vendor/itertools/src/lazy_buffer.rs index fa514ec2d..ca24062aa 100644 --- a/vendor/itertools/src/lazy_buffer.rs +++ b/vendor/itertools/src/lazy_buffer.rs @@ -28,16 +28,12 @@ where if self.done { return false; } - let next_item = self.it.next(); - match next_item { - Some(x) => { - self.buffer.push(x); - true - } - None => { - self.done = true; - false - } + if let Some(x) = self.it.next() { + self.buffer.push(x); + true + } else { + self.done = true; + false } } @@ -61,7 +57,7 @@ where { type Output = as Index>::Output; - fn index(&self, _index: J) -> &Self::Output { - self.buffer.index(_index) + fn index(&self, index: J) -> &Self::Output { + self.buffer.index(index) } } diff --git a/vendor/itertools/src/lib.rs b/vendor/itertools/src/lib.rs index df95e19ba..f91968870 100644 --- a/vendor/itertools/src/lib.rs +++ b/vendor/itertools/src/lib.rs @@ -197,6 +197,8 @@ mod combinations_with_replacement; mod exactly_one_err; mod diff; mod flatten_ok; +#[cfg(feature = "use_std")] +mod extrema_set; mod format; #[cfg(feature = "use_std")] mod grouping_map; @@ -387,7 +389,7 @@ macro_rules! izip { /// let with_macro: Chain, Take>>, slice::Iter<_>> = /// chain![once(&0), repeat(&1).take(2), &[2, 3, 5],]; /// -/// // ...is equivalant to this: +/// // ...is equivalent to this: /// let with_method: Chain, Take>>, slice::Iter<_>> = /// once(&0) /// .chain(repeat(&1).take(2)) @@ -778,7 +780,7 @@ pub trait Itertools : Iterator { /// the original iterator. /// /// **Note:** If the iterator is clonable, prefer using that instead - /// of using this method. It is likely to be more efficient. + /// of using this method. Cloning is likely to be more efficient. /// /// Iterator element type is `Self::Item`. /// @@ -904,7 +906,7 @@ pub trait Itertools : Iterator { /// a series of `Result::Ok` values. `Result::Err` values are unchanged. /// /// This is useful when you have some common error type for your crate and - /// need to propogate it upwards, but the `Result::Ok` case needs to be flattened. + /// need to propagate it upwards, but the `Result::Ok` case needs to be flattened. /// /// ``` /// use itertools::Itertools; @@ -913,7 +915,7 @@ pub trait Itertools : Iterator { /// let it = input.iter().cloned().flatten_ok(); /// itertools::assert_equal(it.clone(), vec![Ok(0), Ok(1), Err(false), Ok(2), Ok(3)]); /// - /// // This can also be used to propogate errors when collecting. + /// // This can also be used to propagate errors when collecting. /// let output_result: Result, bool> = it.collect(); /// assert_eq!(output_result, Err(false)); /// ``` @@ -1109,7 +1111,7 @@ pub trait Itertools : Iterator { /// ``` #[cfg(feature = "use_alloc")] fn multi_cartesian_product(self) -> MultiProduct<::IntoIter> - where Self: Iterator + Sized, + where Self: Sized, Self::Item: IntoIterator, ::IntoIter: Clone, ::Item: Clone @@ -1746,12 +1748,10 @@ pub trait Itertools : Iterator { fn find_position

{} + + pub trait _ValueParserViaValueEnumSealed {} + impl _ValueParserViaValueEnumSealed for &_AutoValueParser {} + + pub trait _ValueParserViaFromStrSealed {} + impl _ValueParserViaFromStrSealed for _AutoValueParser + where + FromStr: std::str::FromStr + std::any::Any + Send + Sync + 'static, + ::Err: + Into>, + { + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn ensure_typed_applies_to_parse() { + fn parse(_: &str) -> Result { + Ok(10) + } + let cmd = crate::Command::new("cmd"); + let arg = None; + assert_eq!( + TypedValueParser::parse_ref(&parse, &cmd, arg, std::ffi::OsStr::new("foo")).unwrap(), + 10 + ); + } +} diff --git a/vendor/clap-3.2.20/src/derive.rs b/vendor/clap-3.2.20/src/derive.rs new file mode 100644 index 000000000..b6ac04df6 --- /dev/null +++ b/vendor/clap-3.2.20/src/derive.rs @@ -0,0 +1,577 @@ +//! This module contains traits that are usable with the `#[derive(...)].` +//! macros in [`clap_derive`]. + +use crate::{ArgMatches, Command, Error, PossibleValue}; + +use std::ffi::OsString; + +/// Parse command-line arguments into `Self`. +/// +/// The primary one-stop-shop trait used to create an instance of a `clap` +/// [`Command`], conduct the parsing, and turn the resulting [`ArgMatches`] back +/// into concrete instance of the user struct. +/// +/// This trait is primarily a convenience on top of [`FromArgMatches`] + +/// [`CommandFactory`] which uses those two underlying traits to build the two +/// fundamental functions `parse` which uses the `std::env::args_os` iterator, +/// and `parse_from` which allows the consumer to supply the iterator (along +/// with fallible options for each). +/// +/// See also [`Subcommand`] and [`Args`]. +/// +/// See the [derive reference](crate::_derive) for attributes and best practices. +/// +/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] +/// +/// # Examples +/// +/// The following example creates a `Context` struct that would be used +/// throughout the application representing the normalized values coming from +/// the CLI. +/// +#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] +#[cfg_attr(feature = "derive", doc = " ```")] +/// /// My super CLI +/// #[derive(clap::Parser)] +/// #[clap(name = "demo")] +/// struct Context { +/// /// More verbose output +/// #[clap(long)] +/// verbose: bool, +/// /// An optional name +/// #[clap(short, long)] +/// name: Option, +/// } +/// ``` +/// +/// The equivalent [`Command`] struct + `From` implementation: +/// +/// ```rust +/// # use clap::{Command, Arg, ArgMatches, ArgAction}; +/// Command::new("demo") +/// .about("My super CLI") +/// .arg(Arg::new("verbose") +/// .long("verbose") +/// .action(ArgAction::SetTrue) +/// .help("More verbose output")) +/// .arg(Arg::new("name") +/// .long("name") +/// .short('n') +/// .help("An optional name") +/// .takes_value(true)); +/// +/// struct Context { +/// verbose: bool, +/// name: Option, +/// } +/// +/// impl From for Context { +/// fn from(m: ArgMatches) -> Self { +/// Context { +/// verbose: *m.get_one::("verbose").expect("defaulted_by_clap"), +/// name: m.get_one::("name").cloned(), +/// } +/// } +/// } +/// ``` +/// +pub trait Parser: FromArgMatches + CommandFactory + Sized { + /// Parse from `std::env::args_os()`, exit on error + fn parse() -> Self { + let mut matches = ::command().get_matches(); + let res = ::from_arg_matches_mut(&mut matches) + .map_err(format_error::); + match res { + Ok(s) => s, + Err(e) => { + // Since this is more of a development-time error, we aren't doing as fancy of a quit + // as `get_matches` + e.exit() + } + } + } + + /// Parse from `std::env::args_os()`, return Err on error. + fn try_parse() -> Result { + let mut matches = ::command().try_get_matches()?; + ::from_arg_matches_mut(&mut matches).map_err(format_error::) + } + + /// Parse from iterator, exit on error + fn parse_from(itr: I) -> Self + where + I: IntoIterator, + T: Into + Clone, + { + let mut matches = ::command().get_matches_from(itr); + let res = ::from_arg_matches_mut(&mut matches) + .map_err(format_error::); + match res { + Ok(s) => s, + Err(e) => { + // Since this is more of a development-time error, we aren't doing as fancy of a quit + // as `get_matches_from` + e.exit() + } + } + } + + /// Parse from iterator, return Err on error. + fn try_parse_from(itr: I) -> Result + where + I: IntoIterator, + T: Into + Clone, + { + let mut matches = ::command().try_get_matches_from(itr)?; + ::from_arg_matches_mut(&mut matches).map_err(format_error::) + } + + /// Update from iterator, exit on error + fn update_from(&mut self, itr: I) + where + I: IntoIterator, + T: Into + Clone, + { + let mut matches = ::command_for_update().get_matches_from(itr); + let res = ::update_from_arg_matches_mut(self, &mut matches) + .map_err(format_error::); + if let Err(e) = res { + // Since this is more of a development-time error, we aren't doing as fancy of a quit + // as `get_matches_from` + e.exit() + } + } + + /// Update from iterator, return Err on error. + fn try_update_from(&mut self, itr: I) -> Result<(), Error> + where + I: IntoIterator, + T: Into + Clone, + { + let mut matches = + ::command_for_update().try_get_matches_from(itr)?; + ::update_from_arg_matches_mut(self, &mut matches) + .map_err(format_error::) + } + + /// Deprecated, `StructOpt::clap` replaced with [`CommandFactory::command`] (derive as part of + /// [`Parser`]) + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "`StructOpt::clap` is replaced with `CommandFactory::command` (derived as part of `Parser`)" + ) + )] + #[doc(hidden)] + fn clap<'help>() -> Command<'help> { + ::command() + } + + /// Deprecated, `StructOpt::from_clap` replaced with [`FromArgMatches::from_arg_matches_mut`] (derive as part of + /// [`Parser`]) + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "`StructOpt::from_clap` is replaced with `FromArgMatches::from_arg_matches_mut` (derived as part of `Parser`)" + ) + )] + #[doc(hidden)] + fn from_clap(matches: &ArgMatches) -> Self { + ::from_arg_matches(matches).unwrap() + } + + /// Deprecated, `StructOpt::from_args` replaced with `Parser::parse` (note the change in derives) + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "`StructOpt::from_args` is replaced with `Parser::parse` (note the change in derives)" + ) + )] + #[doc(hidden)] + fn from_args() -> Self { + Self::parse() + } + + /// Deprecated, `StructOpt::from_args_safe` replaced with `Parser::try_parse` (note the change in derives) + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "`StructOpt::from_args_safe` is replaced with `Parser::try_parse` (note the change in derives)" + ) + )] + #[doc(hidden)] + fn from_args_safe() -> Result { + Self::try_parse() + } + + /// Deprecated, `StructOpt::from_iter` replaced with `Parser::parse_from` (note the change in derives) + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "`StructOpt::from_iter` is replaced with `Parser::parse_from` (note the change in derives)" + ) + )] + #[doc(hidden)] + fn from_iter(itr: I) -> Self + where + I: IntoIterator, + T: Into + Clone, + { + Self::parse_from(itr) + } + + /// Deprecated, `StructOpt::from_iter_safe` replaced with `Parser::try_parse_from` (note the + /// change in derives) + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "`StructOpt::from_iter_safe` is replaced with `Parser::try_parse_from` (note the change in derives)" + ) + )] + #[doc(hidden)] + fn from_iter_safe(itr: I) -> Result + where + I: IntoIterator, + T: Into + Clone, + { + Self::try_parse_from(itr) + } +} + +/// Create a [`Command`] relevant for a user-defined container. +/// +/// Derived as part of [`Parser`]. +pub trait CommandFactory: Sized { + /// Build a [`Command`] that can instantiate `Self`. + /// + /// See [`FromArgMatches::from_arg_matches_mut`] for instantiating `Self`. + fn command<'help>() -> Command<'help> { + #[allow(deprecated)] + Self::into_app() + } + /// Deprecated, replaced with `CommandFactory::command` + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `CommandFactory::command") + )] + fn into_app<'help>() -> Command<'help>; + /// Build a [`Command`] that can update `self`. + /// + /// See [`FromArgMatches::update_from_arg_matches_mut`] for updating `self`. + fn command_for_update<'help>() -> Command<'help> { + #[allow(deprecated)] + Self::into_app_for_update() + } + /// Deprecated, replaced with `CommandFactory::command_for_update` + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.1.0", + note = "Replaced with `CommandFactory::command_for_update" + ) + )] + fn into_app_for_update<'help>() -> Command<'help>; +} + +/// Converts an instance of [`ArgMatches`] to a user-defined container. +/// +/// Derived as part of [`Parser`], [`Args`], and [`Subcommand`]. +pub trait FromArgMatches: Sized { + /// Instantiate `Self` from [`ArgMatches`], parsing the arguments as needed. + /// + /// Motivation: If our application had two CLI options, `--name + /// ` and the flag `--debug`, we may create a struct as follows: + /// + #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] + #[cfg_attr(feature = "derive", doc = " ```no_run")] + /// struct Context { + /// name: String, + /// debug: bool + /// } + /// ``` + /// + /// We then need to convert the `ArgMatches` that `clap` generated into our struct. + /// `from_arg_matches` serves as the equivalent of: + /// + #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] + #[cfg_attr(feature = "derive", doc = " ```no_run")] + /// # use clap::ArgMatches; + /// # struct Context { + /// # name: String, + /// # debug: bool + /// # } + /// impl From for Context { + /// fn from(m: ArgMatches) -> Self { + /// Context { + /// name: m.get_one::("name").unwrap().clone(), + /// debug: *m.get_one::("debug").expect("defaulted by clap"), + /// } + /// } + /// } + /// ``` + fn from_arg_matches(matches: &ArgMatches) -> Result; + + /// Instantiate `Self` from [`ArgMatches`], parsing the arguments as needed. + /// + /// Motivation: If our application had two CLI options, `--name + /// ` and the flag `--debug`, we may create a struct as follows: + /// + #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] + #[cfg_attr(feature = "derive", doc = " ```no_run")] + /// struct Context { + /// name: String, + /// debug: bool + /// } + /// ``` + /// + /// We then need to convert the `ArgMatches` that `clap` generated into our struct. + /// `from_arg_matches_mut` serves as the equivalent of: + /// + #[cfg_attr(not(feature = "derive"), doc = " ```ignore")] + #[cfg_attr(feature = "derive", doc = " ```no_run")] + /// # use clap::ArgMatches; + /// # struct Context { + /// # name: String, + /// # debug: bool + /// # } + /// impl From for Context { + /// fn from(m: ArgMatches) -> Self { + /// Context { + /// name: m.get_one::("name").unwrap().to_string(), + /// debug: *m.get_one::("debug").expect("defaulted by clap"), + /// } + /// } + /// } + /// ``` + fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { + Self::from_arg_matches(matches) + } + + /// Assign values from `ArgMatches` to `self`. + fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error>; + + /// Assign values from `ArgMatches` to `self`. + fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { + self.update_from_arg_matches(matches) + } +} + +/// Parse a set of arguments into a user-defined container. +/// +/// Implementing this trait lets a parent container delegate argument parsing behavior to `Self`. +/// with: +/// - `#[clap(flatten)] args: ChildArgs`: Attribute can only be used with struct fields that impl +/// `Args`. +/// - `Variant(ChildArgs)`: No attribute is used with enum variants that impl `Args`. +/// +/// See the [derive reference](crate::_derive) for attributes and best practices. +/// +/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] +/// +/// # Example +/// +#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] +#[cfg_attr(feature = "derive", doc = " ```")] +/// #[derive(clap::Parser)] +/// struct Args { +/// #[clap(flatten)] +/// logging: LogArgs, +/// } +/// +/// #[derive(clap::Args)] +/// struct LogArgs { +/// #[clap(long, short = 'v', parse(from_occurrences))] +/// verbose: i8, +/// } +/// ``` +pub trait Args: FromArgMatches + Sized { + /// Append to [`Command`] so it can instantiate `Self`. + /// + /// See also [`CommandFactory`]. + fn augment_args(cmd: Command<'_>) -> Command<'_>; + /// Append to [`Command`] so it can update `self`. + /// + /// This is used to implement `#[clap(flatten)]` + /// + /// See also [`CommandFactory`]. + fn augment_args_for_update(cmd: Command<'_>) -> Command<'_>; +} + +/// Parse a sub-command into a user-defined enum. +/// +/// Implementing this trait lets a parent container delegate subcommand behavior to `Self`. +/// with: +/// - `#[clap(subcommand)] field: SubCmd`: Attribute can be used with either struct fields or enum +/// variants that impl `Subcommand`. +/// - `#[clap(flatten)] Variant(SubCmd)`: Attribute can only be used with enum variants that impl +/// `Subcommand`. +/// +/// See the [derive reference](crate::_derive) for attributes and best practices. +/// +/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] +/// +/// # Example +/// +#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] +#[cfg_attr(feature = "derive", doc = " ```")] +/// #[derive(clap::Parser)] +/// struct Args { +/// #[clap(subcommand)] +/// action: Action, +/// } +/// +/// #[derive(clap::Subcommand)] +/// enum Action { +/// Add, +/// Remove, +/// } +/// ``` +pub trait Subcommand: FromArgMatches + Sized { + /// Append to [`Command`] so it can instantiate `Self`. + /// + /// See also [`CommandFactory`]. + fn augment_subcommands(cmd: Command<'_>) -> Command<'_>; + /// Append to [`Command`] so it can update `self`. + /// + /// This is used to implement `#[clap(flatten)]` + /// + /// See also [`CommandFactory`]. + fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_>; + /// Test whether `Self` can parse a specific subcommand + fn has_subcommand(name: &str) -> bool; +} + +/// Parse arguments into enums. +/// +/// When deriving [`Parser`], a field whose type implements `ValueEnum` can have the attribute +/// `#[clap(value_enum)]` which will +/// - Call [`Arg::possible_values`][crate::Arg::possible_values] +/// - Allowing using the `#[clap(default_value_t)]` attribute without implementing `Display`. +/// +/// See the [derive reference](crate::_derive) for attributes and best practices. +/// +/// **NOTE:** Deriving requires the [`derive` feature flag][crate::_features] +/// +/// # Example +/// +#[cfg_attr(not(feature = "derive"), doc = " ```ignore")] +#[cfg_attr(feature = "derive", doc = " ```")] +/// #[derive(clap::Parser)] +/// struct Args { +/// #[clap(value_enum)] +/// level: Level, +/// } +/// +/// #[derive(clap::ValueEnum, Clone)] +/// enum Level { +/// Debug, +/// Info, +/// Warning, +/// Error, +/// } +/// ``` +pub trait ValueEnum: Sized + Clone { + /// All possible argument values, in display order. + fn value_variants<'a>() -> &'a [Self]; + + /// Parse an argument into `Self`. + fn from_str(input: &str, ignore_case: bool) -> Result { + Self::value_variants() + .iter() + .find(|v| { + v.to_possible_value() + .expect("ValueEnum::value_variants contains only values with a corresponding ValueEnum::to_possible_value") + .matches(input, ignore_case) + }) + .cloned() + .ok_or_else(|| format!("Invalid variant: {}", input)) + } + + /// The canonical argument value. + /// + /// The value is `None` for skipped variants. + fn to_possible_value<'a>(&self) -> Option>; +} + +impl Parser for Box { + fn parse() -> Self { + Box::new(::parse()) + } + + fn try_parse() -> Result { + ::try_parse().map(Box::new) + } + + fn parse_from(itr: I) -> Self + where + I: IntoIterator, + It: Into + Clone, + { + Box::new(::parse_from(itr)) + } + + fn try_parse_from(itr: I) -> Result + where + I: IntoIterator, + It: Into + Clone, + { + ::try_parse_from(itr).map(Box::new) + } +} + +#[allow(deprecated)] +impl CommandFactory for Box { + fn into_app<'help>() -> Command<'help> { + ::into_app() + } + fn into_app_for_update<'help>() -> Command<'help> { + ::into_app_for_update() + } +} + +impl FromArgMatches for Box { + fn from_arg_matches(matches: &ArgMatches) -> Result { + ::from_arg_matches(matches).map(Box::new) + } + fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { + ::from_arg_matches_mut(matches).map(Box::new) + } + fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { + ::update_from_arg_matches(self, matches) + } + fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { + ::update_from_arg_matches_mut(self, matches) + } +} + +impl Args for Box { + fn augment_args(cmd: Command<'_>) -> Command<'_> { + ::augment_args(cmd) + } + fn augment_args_for_update(cmd: Command<'_>) -> Command<'_> { + ::augment_args_for_update(cmd) + } +} + +impl Subcommand for Box { + fn augment_subcommands(cmd: Command<'_>) -> Command<'_> { + ::augment_subcommands(cmd) + } + fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_> { + ::augment_subcommands_for_update(cmd) + } + fn has_subcommand(name: &str) -> bool { + ::has_subcommand(name) + } +} + +fn format_error(err: crate::Error) -> crate::Error { + let mut cmd = I::command(); + err.format(&mut cmd) +} diff --git a/vendor/clap-3.2.20/src/error/context.rs b/vendor/clap-3.2.20/src/error/context.rs new file mode 100644 index 000000000..985cd4d70 --- /dev/null +++ b/vendor/clap-3.2.20/src/error/context.rs @@ -0,0 +1,55 @@ +/// Semantics for a piece of error information +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum ContextKind { + /// The cause of the error + InvalidSubcommand, + /// The cause of the error + InvalidArg, + /// Existing arguments + PriorArg, + /// Accepted values + ValidValue, + /// Rejected values + InvalidValue, + /// Number of values present + ActualNumValues, + /// Number of allowed values + ExpectedNumValues, + /// Minimum number of allowed values + MinValues, + /// Number of occurrences present + ActualNumOccurrences, + /// Maximum number of allowed occurrences + MaxOccurrences, + /// Potential fix for the user + SuggestedCommand, + /// Potential fix for the user + SuggestedSubcommand, + /// Potential fix for the user + SuggestedArg, + /// Potential fix for the user + SuggestedValue, + /// Trailing argument + TrailingArg, + /// A usage string + Usage, + /// An opaque message to the user + Custom, +} + +/// A piece of error information +#[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum ContextValue { + /// [`ContextKind`] is self-sufficient, no additional information needed + None, + /// A single value + Bool(bool), + /// A single value + String(String), + /// Many values + Strings(Vec), + /// A single value + Number(isize), +} diff --git a/vendor/clap-3.2.20/src/error/kind.rs b/vendor/clap-3.2.20/src/error/kind.rs new file mode 100644 index 000000000..4c3dc48b0 --- /dev/null +++ b/vendor/clap-3.2.20/src/error/kind.rs @@ -0,0 +1,440 @@ +/// Command line argument parser kind of error +#[derive(Debug, Copy, Clone, PartialEq)] +#[non_exhaustive] +pub enum ErrorKind { + /// Occurs when an [`Arg`][crate::Arg] has a set of possible values, + /// and the user provides a value which isn't in that set. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("speed") + /// .value_parser(["fast", "slow"])) + /// .try_get_matches_from(vec!["prog", "other"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue); + /// ``` + InvalidValue, + + /// Occurs when a user provides a flag, option, argument or subcommand which isn't defined. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(arg!(--flag "some flag")) + /// .try_get_matches_from(vec!["prog", "--other"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnknownArgument); + /// ``` + UnknownArgument, + + /// Occurs when the user provides an unrecognized [`Subcommand`] which meets the threshold for + /// being similar enough to an existing subcommand. + /// If it doesn't meet the threshold, or the 'suggestions' feature is disabled, + /// the more general [`UnknownArgument`] error is returned. + /// + /// # Examples + /// + #[cfg_attr(not(feature = "suggestions"), doc = " ```no_run")] + #[cfg_attr(feature = "suggestions", doc = " ```")] + /// # use clap::{Command, Arg, ErrorKind, }; + /// let result = Command::new("prog") + /// .subcommand(Command::new("config") + /// .about("Used for configuration") + /// .arg(Arg::new("config_file") + /// .help("The configuration file to use"))) + /// .try_get_matches_from(vec!["prog", "confi"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidSubcommand); + /// ``` + /// + /// [`Subcommand`]: crate::Subcommand + /// [`UnknownArgument`]: ErrorKind::UnknownArgument + InvalidSubcommand, + + /// Occurs when the user provides an unrecognized [`Subcommand`] which either + /// doesn't meet the threshold for being similar enough to an existing subcommand, + /// or the 'suggestions' feature is disabled. + /// Otherwise the more detailed [`InvalidSubcommand`] error is returned. + /// + /// This error typically happens when passing additional subcommand names to the `help` + /// subcommand. Otherwise, the more general [`UnknownArgument`] error is used. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind, }; + /// let result = Command::new("prog") + /// .subcommand(Command::new("config") + /// .about("Used for configuration") + /// .arg(Arg::new("config_file") + /// .help("The configuration file to use"))) + /// .try_get_matches_from(vec!["prog", "help", "nothing"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand); + /// ``` + /// + /// [`Subcommand`]: crate::Subcommand + /// [`InvalidSubcommand`]: ErrorKind::InvalidSubcommand + /// [`UnknownArgument`]: ErrorKind::UnknownArgument + UnrecognizedSubcommand, + + /// Occurs when the user provides an empty value for an option that does not allow empty + /// values. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("color") + /// .takes_value(true) + /// .forbid_empty_values(true) + /// .long("color")) + /// .try_get_matches_from(vec!["prog", "--color="]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::EmptyValue); + /// ``` + EmptyValue, + + /// Occurs when the user doesn't use equals for an option that requires equal + /// sign to provide values. + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let res = Command::new("prog") + /// .arg(Arg::new("color") + /// .takes_value(true) + /// .require_equals(true) + /// .long("color")) + /// .try_get_matches_from(vec!["prog", "--color", "red"]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals); + /// ``` + NoEquals, + + /// Occurs when the user provides a value for an argument with a custom validation and the + /// value fails that validation. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// fn is_numeric(val: &str) -> Result<(), String> { + /// match val.parse::() { + /// Ok(..) => Ok(()), + /// Err(..) => Err(String::from("Value wasn't a number!")), + /// } + /// } + /// + /// let result = Command::new("prog") + /// .arg(Arg::new("num") + /// .validator(is_numeric)) + /// .try_get_matches_from(vec!["prog", "NotANumber"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation); + /// ``` + ValueValidation, + + /// Occurs when a user provides more values for an argument than were defined by setting + /// [`Arg::max_values`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("arg") + /// .max_values(2)) + /// .try_get_matches_from(vec!["prog", "too", "many", "values"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyValues); + /// ``` + /// [`Arg::max_values`]: crate::Arg::max_values() + TooManyValues, + + /// Occurs when the user provides fewer values for an argument than were defined by setting + /// [`Arg::min_values`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("some_opt") + /// .long("opt") + /// .min_values(3)) + /// .try_get_matches_from(vec!["prog", "--opt", "too", "few"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooFewValues); + /// ``` + /// [`Arg::min_values`]: crate::Arg::min_values() + TooFewValues, + + /// Occurs when a user provides more occurrences for an argument than were defined by setting + /// [`Arg::max_occurrences`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("verbosity") + /// .short('v') + /// .max_occurrences(2)) + /// .try_get_matches_from(vec!["prog", "-vvv"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyOccurrences); + /// ``` + /// [`Arg::max_occurrences`]: crate::Arg::max_occurrences() + TooManyOccurrences, + + /// Occurs when the user provides a different number of values for an argument than what's + /// been defined by setting [`Arg::number_of_values`] or than was implicitly set by + /// [`Arg::value_names`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("some_opt") + /// .long("opt") + /// .takes_value(true) + /// .number_of_values(2)) + /// .try_get_matches_from(vec!["prog", "--opt", "wrong"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::WrongNumberOfValues); + /// ``` + /// + /// [`Arg::number_of_values`]: crate::Arg::number_of_values() + /// [`Arg::value_names`]: crate::Arg::value_names() + WrongNumberOfValues, + + /// Occurs when the user provides two values which conflict with each other and can't be used + /// together. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("debug") + /// .long("debug") + /// .conflicts_with("color")) + /// .arg(Arg::new("color") + /// .long("color")) + /// .try_get_matches_from(vec!["prog", "--debug", "--color"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::ArgumentConflict); + /// ``` + ArgumentConflict, + + /// Occurs when the user does not provide one or more required arguments. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("debug") + /// .required(true)) + /// .try_get_matches_from(vec!["prog"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::MissingRequiredArgument); + /// ``` + MissingRequiredArgument, + + /// Occurs when a subcommand is required (as defined by [`Command::subcommand_required`]), + /// but the user does not provide one. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, ErrorKind}; + /// let err = Command::new("prog") + /// .subcommand_required(true) + /// .subcommand(Command::new("test")) + /// .try_get_matches_from(vec![ + /// "myprog", + /// ]); + /// assert!(err.is_err()); + /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand); + /// # ; + /// ``` + /// + /// [`Command::subcommand_required`]: crate::Command::subcommand_required + MissingSubcommand, + + /// Occurs when the user provides multiple values to an argument which doesn't allow that. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .arg(Arg::new("debug") + /// .long("debug") + /// .multiple_occurrences(false)) + /// .try_get_matches_from(vec!["prog", "--debug", "--debug"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage); + /// ``` + UnexpectedMultipleUsage, + + /// Occurs when the user provides a value containing invalid UTF-8. + /// + /// To allow arbitrary data + /// - Set [`Arg::allow_invalid_utf8`] for argument values + /// - Set [`Command::allow_invalid_utf8_for_external_subcommands`] for external-subcommand + /// values + /// + /// # Platform Specific + /// + /// Non-Windows platforms only (such as Linux, Unix, OSX, etc.) + /// + /// # Examples + /// + #[cfg_attr(not(unix), doc = " ```ignore")] + #[cfg_attr(unix, doc = " ```")] + /// # use clap::{Command, Arg, ErrorKind}; + /// # use std::os::unix::ffi::OsStringExt; + /// # use std::ffi::OsString; + /// let result = Command::new("prog") + /// .arg(Arg::new("utf8") + /// .short('u') + /// .takes_value(true)) + /// .try_get_matches_from(vec![OsString::from("myprog"), + /// OsString::from("-u"), + /// OsString::from_vec(vec![0xE9])]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidUtf8); + /// ``` + /// + /// [`Arg::allow_invalid_utf8`]: crate::Arg::allow_invalid_utf8 + /// [`Command::allow_invalid_utf8_for_external_subcommands`]: crate::Command::allow_invalid_utf8_for_external_subcommands + InvalidUtf8, + + /// Not a true "error" as it means `--help` or similar was used. + /// The help message will be sent to `stdout`. + /// + /// **Note**: If the help is displayed due to an error (such as missing subcommands) it will + /// be sent to `stderr` instead of `stdout`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .try_get_matches_from(vec!["prog", "--help"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelp); + /// ``` + DisplayHelp, + + /// Occurs when either an argument or a [`Subcommand`] is required, as defined by + /// [`Command::arg_required_else_help`] , but the user did not provide + /// one. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind, }; + /// let result = Command::new("prog") + /// .arg_required_else_help(true) + /// .subcommand(Command::new("config") + /// .about("Used for configuration") + /// .arg(Arg::new("config_file") + /// .help("The configuration file to use"))) + /// .try_get_matches_from(vec!["prog"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand); + /// ``` + /// + /// [`Subcommand`]: crate::Subcommand + /// [`Command::arg_required_else_help`]: crate::Command::arg_required_else_help + DisplayHelpOnMissingArgumentOrSubcommand, + + /// Not a true "error" as it means `--version` or similar was used. + /// The message will be sent to `stdout`. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ErrorKind}; + /// let result = Command::new("prog") + /// .version("3.0") + /// .try_get_matches_from(vec!["prog", "--version"]); + /// assert!(result.is_err()); + /// assert_eq!(result.unwrap_err().kind(), ErrorKind::DisplayVersion); + /// ``` + DisplayVersion, + + /// Occurs when using the [`ArgMatches::value_of_t`] and friends to convert an argument value + /// into type `T`, but the argument you requested wasn't used. I.e. you asked for an argument + /// with name `config` to be converted, but `config` wasn't used by the user. + /// + /// [`ArgMatches::value_of_t`]: crate::ArgMatches::value_of_t() + ArgumentNotFound, + + /// Represents an [I/O error]. + /// Can occur when writing to `stderr` or `stdout` or reading a configuration file. + /// + /// [I/O error]: std::io::Error + Io, + + /// Represents a [Format error] (which is a part of [`Display`]). + /// Typically caused by writing to `stderr` or `stdout`. + /// + /// [`Display`]: std::fmt::Display + /// [Format error]: std::fmt::Error + Format, +} + +impl ErrorKind { + /// End-user description of the error case, where relevant + pub fn as_str(self) -> Option<&'static str> { + match self { + Self::InvalidValue => Some("One of the values isn't valid for an argument"), + Self::UnknownArgument => { + Some("Found an argument which wasn't expected or isn't valid in this context") + } + Self::InvalidSubcommand => Some("A subcommand wasn't recognized"), + Self::UnrecognizedSubcommand => Some("A subcommand wasn't recognized"), + Self::EmptyValue => Some("An argument requires a value but none was supplied"), + Self::NoEquals => Some("Equal is needed when assigning values to one of the arguments"), + Self::ValueValidation => Some("Invalid value for one of the arguments"), + Self::TooManyValues => Some("An argument received an unexpected value"), + Self::TooFewValues => Some("An argument requires more values"), + Self::TooManyOccurrences => Some("An argument occurred too many times"), + Self::WrongNumberOfValues => Some("An argument received too many or too few values"), + Self::ArgumentConflict => { + Some("An argument cannot be used with one or more of the other specified arguments") + } + Self::MissingRequiredArgument => { + Some("One or more required arguments were not provided") + } + Self::MissingSubcommand => Some("A subcommand is required but one was not provided"), + Self::UnexpectedMultipleUsage => { + Some("An argument was provided more than once but cannot be used multiple times") + } + Self::InvalidUtf8 => Some("Invalid UTF-8 was detected in one or more arguments"), + Self::DisplayHelp => None, + Self::DisplayHelpOnMissingArgumentOrSubcommand => None, + Self::DisplayVersion => None, + Self::ArgumentNotFound => Some("An argument wasn't found"), + Self::Io => None, + Self::Format => None, + } + } +} + +impl std::fmt::Display for ErrorKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_str().unwrap_or_default().fmt(f) + } +} diff --git a/vendor/clap-3.2.20/src/error/mod.rs b/vendor/clap-3.2.20/src/error/mod.rs new file mode 100644 index 000000000..fbd2b30a8 --- /dev/null +++ b/vendor/clap-3.2.20/src/error/mod.rs @@ -0,0 +1,1153 @@ +//! Error reporting +#![allow(deprecated)] + +// Std +use std::{ + borrow::Cow, + convert::From, + error, + fmt::{self, Debug, Display, Formatter}, + io::{self, BufRead}, + result::Result as StdResult, +}; + +// Internal +use crate::output::fmt::Colorizer; +use crate::output::fmt::Stream; +use crate::parser::features::suggestions; +use crate::util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE}; +use crate::AppSettings; +use crate::Command; + +mod context; +mod kind; + +pub use context::ContextKind; +pub use context::ContextValue; +pub use kind::ErrorKind; + +/// Short hand for [`Result`] type +/// +/// [`Result`]: std::result::Result +pub type Result = StdResult; + +/// Command Line Argument Parser Error +/// +/// See [`Command::error`] to create an error. +/// +/// [`Command::error`]: crate::Command::error +#[derive(Debug)] +pub struct Error { + inner: Box, + /// Deprecated, replaced with [`Error::kind()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Error::kind()`") + )] + pub kind: ErrorKind, + /// Deprecated, replaced with [`Error::context()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `Error::context()`") + )] + pub info: Vec, +} + +#[derive(Debug)] +struct ErrorInner { + kind: ErrorKind, + context: Vec<(ContextKind, ContextValue)>, + message: Option, + source: Option>, + help_flag: Option<&'static str>, + color_when: ColorChoice, + wait_on_exit: bool, + backtrace: Option, +} + +impl Error { + /// Create an unformatted error + /// + /// This is for you need to pass the error up to + /// a place that has access to the `Command` at which point you can call [`Error::format`]. + /// + /// Prefer [`Command::error`] for generating errors. + /// + /// [`Command::error`]: crate::Command::error + pub fn raw(kind: ErrorKind, message: impl std::fmt::Display) -> Self { + Self::new(kind).set_message(message.to_string()) + } + + /// Format the existing message with the Command's context + #[must_use] + pub fn format(mut self, cmd: &mut Command) -> Self { + cmd._build_self(); + let usage = cmd.render_usage(); + if let Some(message) = self.inner.message.as_mut() { + message.format(cmd, usage); + } + self.with_cmd(cmd) + } + + /// Type of error for programmatic processing + pub fn kind(&self) -> ErrorKind { + self.inner.kind + } + + /// Additional information to further qualify the error + pub fn context(&self) -> impl Iterator { + self.inner.context.iter().map(|(k, v)| (*k, v)) + } + + /// Should the message be written to `stdout` or not? + #[inline] + pub fn use_stderr(&self) -> bool { + self.stream() == Stream::Stderr + } + + pub(crate) fn stream(&self) -> Stream { + match self.kind() { + ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => Stream::Stdout, + _ => Stream::Stderr, + } + } + + /// Prints the error and exits. + /// + /// Depending on the error kind, this either prints to `stderr` and exits with a status of `2` + /// or prints to `stdout` and exits with a status of `0`. + pub fn exit(&self) -> ! { + if self.use_stderr() { + // Swallow broken pipe errors + let _ = self.print(); + + if self.inner.wait_on_exit { + wlnerr!("\nPress [ENTER] / [RETURN] to continue..."); + let mut s = String::new(); + let i = io::stdin(); + i.lock().read_line(&mut s).unwrap(); + } + + safe_exit(USAGE_CODE); + } + + // Swallow broken pipe errors + let _ = self.print(); + safe_exit(SUCCESS_CODE) + } + + /// Prints formatted and colored error to `stdout` or `stderr` according to its error kind + /// + /// # Example + /// ```no_run + /// use clap::Command; + /// + /// match Command::new("Command").try_get_matches() { + /// Ok(matches) => { + /// // do_something + /// }, + /// Err(err) => { + /// err.print().expect("Error writing Error"); + /// // do_something + /// }, + /// }; + /// ``` + pub fn print(&self) -> io::Result<()> { + self.formatted().print() + } + + /// Deprecated, replaced with [`Command::error`] + /// + /// [`Command::error`]: crate::Command::error + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Command::error`") + )] + #[doc(hidden)] + pub fn with_description(description: String, kind: ErrorKind) -> Self { + Error::raw(kind, description) + } + + fn new(kind: ErrorKind) -> Self { + Self { + inner: Box::new(ErrorInner { + kind, + context: Vec::new(), + message: None, + source: None, + help_flag: None, + color_when: ColorChoice::Never, + wait_on_exit: false, + backtrace: Backtrace::new(), + }), + kind, + info: vec![], + } + } + + #[inline(never)] + fn for_app(kind: ErrorKind, cmd: &Command, colorizer: Colorizer, info: Vec) -> Self { + Self::new(kind) + .set_message(colorizer) + .with_cmd(cmd) + .set_info(info) + } + + pub(crate) fn with_cmd(self, cmd: &Command) -> Self { + self.set_wait_on_exit(cmd.is_set(AppSettings::WaitOnError)) + .set_color(cmd.get_color()) + .set_help_flag(get_help_flag(cmd)) + } + + pub(crate) fn set_message(mut self, message: impl Into) -> Self { + self.inner.message = Some(message.into()); + self + } + + pub(crate) fn set_info(mut self, info: Vec) -> Self { + self.info = info; + self + } + + pub(crate) fn set_source(mut self, source: Box) -> Self { + self.inner.source = Some(source); + self + } + + pub(crate) fn set_color(mut self, color_when: ColorChoice) -> Self { + self.inner.color_when = color_when; + self + } + + pub(crate) fn set_help_flag(mut self, help_flag: Option<&'static str>) -> Self { + self.inner.help_flag = help_flag; + self + } + + pub(crate) fn set_wait_on_exit(mut self, yes: bool) -> Self { + self.inner.wait_on_exit = yes; + self + } + + /// Does not verify if `ContextKind` is already present + #[inline(never)] + pub(crate) fn insert_context_unchecked( + mut self, + kind: ContextKind, + value: ContextValue, + ) -> Self { + self.inner.context.push((kind, value)); + self + } + + /// Does not verify if `ContextKind` is already present + #[inline(never)] + pub(crate) fn extend_context_unchecked( + mut self, + context: [(ContextKind, ContextValue); N], + ) -> Self { + self.inner.context.extend(context); + self + } + + #[inline(never)] + fn get_context(&self, kind: ContextKind) -> Option<&ContextValue> { + self.inner + .context + .iter() + .find_map(|(k, v)| (*k == kind).then(|| v)) + } + + pub(crate) fn display_help(cmd: &Command, colorizer: Colorizer) -> Self { + Self::for_app(ErrorKind::DisplayHelp, cmd, colorizer, vec![]) + } + + pub(crate) fn display_help_error(cmd: &Command, colorizer: Colorizer) -> Self { + Self::for_app( + ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand, + cmd, + colorizer, + vec![], + ) + } + + pub(crate) fn display_version(cmd: &Command, colorizer: Colorizer) -> Self { + Self::for_app(ErrorKind::DisplayVersion, cmd, colorizer, vec![]) + } + + pub(crate) fn argument_conflict( + cmd: &Command, + arg: String, + mut others: Vec, + usage: String, + ) -> Self { + let info = others.clone(); + let others = match others.len() { + 0 => ContextValue::None, + 1 => ContextValue::String(others.pop().unwrap()), + _ => ContextValue::Strings(others), + }; + Self::new(ErrorKind::ArgumentConflict) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::PriorArg, others), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn empty_value(cmd: &Command, good_vals: &[&str], arg: String) -> Self { + let info = vec![arg.clone()]; + let mut err = Self::new(ErrorKind::EmptyValue) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]); + if !good_vals.is_empty() { + err = err.insert_context_unchecked( + ContextKind::ValidValue, + ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()), + ); + } + err + } + + pub(crate) fn no_equals(cmd: &Command, arg: String, usage: String) -> Self { + let info = vec![arg.clone()]; + Self::new(ErrorKind::NoEquals) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn invalid_value( + cmd: &Command, + bad_val: String, + good_vals: &[&str], + arg: String, + ) -> Self { + let mut info = vec![arg.clone(), bad_val.clone()]; + info.extend(good_vals.iter().map(|s| (*s).to_owned())); + + let suggestion = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop(); + let mut err = Self::new(ErrorKind::InvalidValue) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::InvalidValue, ContextValue::String(bad_val)), + ( + ContextKind::ValidValue, + ContextValue::Strings(good_vals.iter().map(|s| (*s).to_owned()).collect()), + ), + ]); + if let Some(suggestion) = suggestion { + err = err.insert_context_unchecked( + ContextKind::SuggestedValue, + ContextValue::String(suggestion), + ); + } + err + } + + pub(crate) fn invalid_subcommand( + cmd: &Command, + subcmd: String, + did_you_mean: String, + name: String, + usage: String, + ) -> Self { + let info = vec![subcmd.clone()]; + let suggestion = format!("{} -- {}", name, subcmd); + Self::new(ErrorKind::InvalidSubcommand) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)), + ( + ContextKind::SuggestedSubcommand, + ContextValue::String(did_you_mean), + ), + ( + ContextKind::SuggestedCommand, + ContextValue::String(suggestion), + ), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn unrecognized_subcommand(cmd: &Command, subcmd: String, usage: String) -> Self { + let info = vec![subcmd.clone()]; + Self::new(ErrorKind::UnrecognizedSubcommand) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidSubcommand, ContextValue::String(subcmd)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn missing_required_argument( + cmd: &Command, + required: Vec, + usage: String, + ) -> Self { + let info = required.clone(); + Self::new(ErrorKind::MissingRequiredArgument) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::Strings(required)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn missing_subcommand(cmd: &Command, name: String, usage: String) -> Self { + let info = vec![]; + Self::new(ErrorKind::MissingSubcommand) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidSubcommand, ContextValue::String(name)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn invalid_utf8(cmd: &Command, usage: String) -> Self { + let info = vec![]; + Self::new(ErrorKind::InvalidUtf8) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([(ContextKind::Usage, ContextValue::String(usage))]) + } + + pub(crate) fn too_many_occurrences( + cmd: &Command, + arg: String, + max_occurs: usize, + curr_occurs: usize, + usage: String, + ) -> Self { + let info = vec![arg.clone(), curr_occurs.to_string(), max_occurs.to_string()]; + Self::new(ErrorKind::TooManyOccurrences) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + ( + ContextKind::MaxOccurrences, + ContextValue::Number(max_occurs as isize), + ), + ( + ContextKind::ActualNumValues, + ContextValue::Number(curr_occurs as isize), + ), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn too_many_values(cmd: &Command, val: String, arg: String, usage: String) -> Self { + let info = vec![arg.clone(), val.clone()]; + Self::new(ErrorKind::TooManyValues) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::InvalidValue, ContextValue::String(val)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn too_few_values( + cmd: &Command, + arg: String, + min_vals: usize, + curr_vals: usize, + usage: String, + ) -> Self { + let info = vec![arg.clone(), curr_vals.to_string(), min_vals.to_string()]; + Self::new(ErrorKind::TooFewValues) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + ( + ContextKind::MinValues, + ContextValue::Number(min_vals as isize), + ), + ( + ContextKind::ActualNumValues, + ContextValue::Number(curr_vals as isize), + ), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn value_validation( + arg: String, + val: String, + err: Box, + ) -> Self { + let info = vec![arg.clone(), val.to_string(), err.to_string()]; + Self::new(ErrorKind::ValueValidation) + .set_info(info) + .set_source(err) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::InvalidValue, ContextValue::String(val)), + ]) + } + + pub(crate) fn wrong_number_of_values( + cmd: &Command, + arg: String, + num_vals: usize, + curr_vals: usize, + usage: String, + ) -> Self { + let info = vec![arg.clone(), curr_vals.to_string(), num_vals.to_string()]; + Self::new(ErrorKind::WrongNumberOfValues) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + ( + ContextKind::ExpectedNumValues, + ContextValue::Number(num_vals as isize), + ), + ( + ContextKind::ActualNumValues, + ContextValue::Number(curr_vals as isize), + ), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn unexpected_multiple_usage(cmd: &Command, arg: String, usage: String) -> Self { + let info = vec![arg.clone()]; + Self::new(ErrorKind::UnexpectedMultipleUsage) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn unknown_argument( + cmd: &Command, + arg: String, + did_you_mean: Option<(String, Option)>, + usage: String, + ) -> Self { + let info = vec![arg.clone()]; + let mut err = Self::new(ErrorKind::UnknownArgument) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::Usage, ContextValue::String(usage)), + ]); + if let Some((flag, sub)) = did_you_mean { + err = err.insert_context_unchecked( + ContextKind::SuggestedArg, + ContextValue::String(format!("--{}", flag)), + ); + if let Some(sub) = sub { + err = err.insert_context_unchecked( + ContextKind::SuggestedSubcommand, + ContextValue::String(sub), + ); + } + } + err + } + + pub(crate) fn unnecessary_double_dash(cmd: &Command, arg: String, usage: String) -> Self { + let info = vec![arg.clone()]; + Self::new(ErrorKind::UnknownArgument) + .with_cmd(cmd) + .set_info(info) + .extend_context_unchecked([ + (ContextKind::InvalidArg, ContextValue::String(arg)), + (ContextKind::TrailingArg, ContextValue::Bool(true)), + (ContextKind::Usage, ContextValue::String(usage)), + ]) + } + + pub(crate) fn argument_not_found_auto(arg: String) -> Self { + let info = vec![arg.clone()]; + Self::new(ErrorKind::ArgumentNotFound) + .set_info(info) + .extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]) + } + + fn formatted(&self) -> Cow<'_, Colorizer> { + if let Some(message) = self.inner.message.as_ref() { + message.formatted() + } else { + let mut c = Colorizer::new(self.stream(), self.inner.color_when); + + start_error(&mut c); + + if !self.write_dynamic_context(&mut c) { + if let Some(msg) = self.kind().as_str() { + c.none(msg.to_owned()); + } else if let Some(source) = self.inner.source.as_ref() { + c.none(source.to_string()); + } else { + c.none("Unknown cause"); + } + } + + let usage = self.get_context(ContextKind::Usage); + if let Some(ContextValue::String(usage)) = usage { + put_usage(&mut c, usage); + } + + try_help(&mut c, self.inner.help_flag); + + Cow::Owned(c) + } + } + + #[must_use] + fn write_dynamic_context(&self, c: &mut Colorizer) -> bool { + match self.kind() { + ErrorKind::ArgumentConflict => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let prior_arg = self.get_context(ContextKind::PriorArg); + if let (Some(ContextValue::String(invalid_arg)), Some(prior_arg)) = + (invalid_arg, prior_arg) + { + c.none("The argument '"); + c.warning(invalid_arg); + c.none("' cannot be used with"); + + match prior_arg { + ContextValue::Strings(values) => { + c.none(":"); + for v in values { + c.none("\n "); + c.warning(&**v); + } + } + ContextValue::String(value) => { + c.none(" '"); + c.warning(value); + c.none("'"); + } + _ => { + c.none(" one or more of the other specified arguments"); + } + } + true + } else { + false + } + } + ErrorKind::EmptyValue => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::String(invalid_arg)) = invalid_arg { + c.none("The argument '"); + c.warning(invalid_arg); + c.none("' requires a value but none was supplied"); + + let possible_values = self.get_context(ContextKind::ValidValue); + if let Some(ContextValue::Strings(possible_values)) = possible_values { + c.none("\n\t[possible values: "); + if let Some((last, elements)) = possible_values.split_last() { + for v in elements { + c.good(escape(v)); + c.none(", "); + } + c.good(escape(last)); + } + c.none("]"); + } + true + } else { + false + } + } + ErrorKind::NoEquals => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::String(invalid_arg)) = invalid_arg { + c.none("Equal sign is needed when assigning values to '"); + c.warning(invalid_arg); + c.none("'."); + true + } else { + false + } + } + ErrorKind::InvalidValue => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let invalid_value = self.get_context(ContextKind::InvalidValue); + if let ( + Some(ContextValue::String(invalid_arg)), + Some(ContextValue::String(invalid_value)), + ) = (invalid_arg, invalid_value) + { + c.none(quote(invalid_value)); + c.none(" isn't a valid value for '"); + c.warning(invalid_arg); + c.none("'"); + + let possible_values = self.get_context(ContextKind::ValidValue); + if let Some(ContextValue::Strings(possible_values)) = possible_values { + c.none("\n\t[possible values: "); + if let Some((last, elements)) = possible_values.split_last() { + for v in elements { + c.good(escape(v)); + c.none(", "); + } + c.good(escape(last)); + } + c.none("]"); + } + + let suggestion = self.get_context(ContextKind::SuggestedValue); + if let Some(ContextValue::String(suggestion)) = suggestion { + c.none("\n\n\tDid you mean "); + c.good(quote(suggestion)); + c.none("?"); + } + true + } else { + false + } + } + ErrorKind::InvalidSubcommand => { + let invalid_sub = self.get_context(ContextKind::InvalidSubcommand); + if let Some(ContextValue::String(invalid_sub)) = invalid_sub { + c.none("The subcommand '"); + c.warning(invalid_sub); + c.none("' wasn't recognized"); + + let valid_sub = self.get_context(ContextKind::SuggestedSubcommand); + if let Some(ContextValue::String(valid_sub)) = valid_sub { + c.none("\n\n\tDid you mean "); + c.good(valid_sub); + c.none("?"); + } + + let suggestion = self.get_context(ContextKind::SuggestedCommand); + if let Some(ContextValue::String(suggestion)) = suggestion { + c.none( + "\n\nIf you believe you received this message in error, try re-running with '", + ); + c.good(suggestion); + c.none("'"); + } + true + } else { + false + } + } + ErrorKind::UnrecognizedSubcommand => { + let invalid_sub = self.get_context(ContextKind::InvalidSubcommand); + if let Some(ContextValue::String(invalid_sub)) = invalid_sub { + c.none("The subcommand '"); + c.warning(invalid_sub); + c.none("' wasn't recognized"); + true + } else { + false + } + } + ErrorKind::MissingRequiredArgument => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::Strings(invalid_arg)) = invalid_arg { + c.none("The following required arguments were not provided:"); + for v in invalid_arg { + c.none("\n "); + c.good(&**v); + } + true + } else { + false + } + } + ErrorKind::MissingSubcommand => { + let invalid_sub = self.get_context(ContextKind::InvalidSubcommand); + if let Some(ContextValue::String(invalid_sub)) = invalid_sub { + c.none("'"); + c.warning(invalid_sub); + c.none("' requires a subcommand but one was not provided"); + true + } else { + false + } + } + ErrorKind::InvalidUtf8 => false, + ErrorKind::TooManyOccurrences => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let actual_num_occurs = self.get_context(ContextKind::ActualNumOccurrences); + let max_occurs = self.get_context(ContextKind::MaxOccurrences); + if let ( + Some(ContextValue::String(invalid_arg)), + Some(ContextValue::Number(actual_num_occurs)), + Some(ContextValue::Number(max_occurs)), + ) = (invalid_arg, actual_num_occurs, max_occurs) + { + let were_provided = Error::singular_or_plural(*actual_num_occurs as usize); + c.none("The argument '"); + c.warning(invalid_arg); + c.none("' allows at most "); + c.warning(max_occurs.to_string()); + c.none(" occurrences but "); + c.warning(actual_num_occurs.to_string()); + c.none(were_provided); + true + } else { + false + } + } + ErrorKind::TooManyValues => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let invalid_value = self.get_context(ContextKind::InvalidValue); + if let ( + Some(ContextValue::String(invalid_arg)), + Some(ContextValue::String(invalid_value)), + ) = (invalid_arg, invalid_value) + { + c.none("The value '"); + c.warning(invalid_value); + c.none("' was provided to '"); + c.warning(invalid_arg); + c.none("' but it wasn't expecting any more values"); + true + } else { + false + } + } + ErrorKind::TooFewValues => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let actual_num_values = self.get_context(ContextKind::ActualNumValues); + let min_values = self.get_context(ContextKind::MinValues); + if let ( + Some(ContextValue::String(invalid_arg)), + Some(ContextValue::Number(actual_num_values)), + Some(ContextValue::Number(min_values)), + ) = (invalid_arg, actual_num_values, min_values) + { + let were_provided = Error::singular_or_plural(*actual_num_values as usize); + c.none("The argument '"); + c.warning(invalid_arg); + c.none("' requires at least "); + c.warning(min_values.to_string()); + c.none(" values but only "); + c.warning(actual_num_values.to_string()); + c.none(were_provided); + true + } else { + false + } + } + ErrorKind::ValueValidation => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let invalid_value = self.get_context(ContextKind::InvalidValue); + if let ( + Some(ContextValue::String(invalid_arg)), + Some(ContextValue::String(invalid_value)), + ) = (invalid_arg, invalid_value) + { + c.none("Invalid value "); + c.warning(quote(invalid_value)); + c.none(" for '"); + c.warning(invalid_arg); + if let Some(source) = self.inner.source.as_deref() { + c.none("': "); + c.none(source.to_string()); + } else { + c.none("'"); + } + true + } else { + false + } + } + ErrorKind::WrongNumberOfValues => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + let actual_num_values = self.get_context(ContextKind::ActualNumValues); + let num_values = self.get_context(ContextKind::ExpectedNumValues); + if let ( + Some(ContextValue::String(invalid_arg)), + Some(ContextValue::Number(actual_num_values)), + Some(ContextValue::Number(num_values)), + ) = (invalid_arg, actual_num_values, num_values) + { + let were_provided = Error::singular_or_plural(*actual_num_values as usize); + c.none("The argument '"); + c.warning(invalid_arg); + c.none("' requires "); + c.warning(num_values.to_string()); + c.none(" values, but "); + c.warning(actual_num_values.to_string()); + c.none(were_provided); + true + } else { + false + } + } + ErrorKind::UnexpectedMultipleUsage => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::String(invalid_arg)) = invalid_arg { + c.none("The argument '"); + c.warning(invalid_arg.to_string()); + c.none("' was provided more than once, but cannot be used multiple times"); + true + } else { + false + } + } + ErrorKind::UnknownArgument => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::String(invalid_arg)) = invalid_arg { + c.none("Found argument '"); + c.warning(invalid_arg.to_string()); + c.none("' which wasn't expected, or isn't valid in this context"); + + let valid_sub = self.get_context(ContextKind::SuggestedSubcommand); + let valid_arg = self.get_context(ContextKind::SuggestedArg); + match (valid_sub, valid_arg) { + ( + Some(ContextValue::String(valid_sub)), + Some(ContextValue::String(valid_arg)), + ) => { + c.none("\n\n\tDid you mean "); + c.none("to put '"); + c.good(valid_arg); + c.none("' after the subcommand '"); + c.good(valid_sub); + c.none("'?"); + } + (None, Some(ContextValue::String(valid_arg))) => { + c.none("\n\n\tDid you mean '"); + c.good(valid_arg); + c.none("'?"); + } + (_, _) => {} + } + + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::String(invalid_arg)) = invalid_arg { + if invalid_arg.starts_with('-') { + c.none(format!( + "\n\n\tIf you tried to supply `{}` as a value rather than a flag, use `-- {}`", + invalid_arg, invalid_arg + )); + } + + let trailing_arg = self.get_context(ContextKind::TrailingArg); + if trailing_arg == Some(&ContextValue::Bool(true)) { + c.none(format!( + "\n\n\tIf you tried to supply `{}` as a subcommand, remove the '--' before it.", + invalid_arg + )); + } + } + true + } else { + false + } + } + ErrorKind::ArgumentNotFound => { + let invalid_arg = self.get_context(ContextKind::InvalidArg); + if let Some(ContextValue::String(invalid_arg)) = invalid_arg { + c.none("The argument '"); + c.warning(invalid_arg.to_string()); + c.none("' wasn't found"); + true + } else { + false + } + } + ErrorKind::DisplayHelp + | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand + | ErrorKind::DisplayVersion + | ErrorKind::Io + | ErrorKind::Format => false, + } + } + + /// Returns the singular or plural form on the verb to be based on the argument's value. + fn singular_or_plural(n: usize) -> &'static str { + if n > 1 { + " were provided" + } else { + " was provided" + } + } +} + +impl From for Error { + fn from(e: io::Error) -> Self { + Error::raw(ErrorKind::Io, e) + } +} + +impl From for Error { + fn from(e: fmt::Error) -> Self { + Error::raw(ErrorKind::Format, e) + } +} + +impl error::Error for Error { + #[allow(trivial_casts)] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + self.inner.source.as_ref().map(|e| e.as_ref() as _) + } +} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // Assuming `self.message` already has a trailing newline, from `try_help` or similar + write!(f, "{}", self.formatted())?; + if let Some(backtrace) = self.inner.backtrace.as_ref() { + writeln!(f)?; + writeln!(f, "Backtrace:")?; + writeln!(f, "{}", backtrace)?; + } + Ok(()) + } +} + +fn start_error(c: &mut Colorizer) { + c.error("error:"); + c.none(" "); +} + +fn put_usage(c: &mut Colorizer, usage: impl Into) { + c.none("\n\n"); + c.none(usage); +} + +fn get_help_flag(cmd: &Command) -> Option<&'static str> { + if !cmd.is_disable_help_flag_set() { + Some("--help") + } else if cmd.has_subcommands() && !cmd.is_disable_help_subcommand_set() { + Some("help") + } else { + None + } +} + +fn try_help(c: &mut Colorizer, help: Option<&str>) { + if let Some(help) = help { + c.none("\n\nFor more information try "); + c.good(help); + c.none("\n"); + } else { + c.none("\n"); + } +} + +fn quote(s: impl AsRef) -> String { + let s = s.as_ref(); + format!("{:?}", s) +} + +fn escape(s: impl AsRef) -> String { + let s = s.as_ref(); + if s.contains(char::is_whitespace) { + quote(s) + } else { + s.to_owned() + } +} + +#[derive(Clone, Debug)] +pub(crate) enum Message { + Raw(String), + Formatted(Colorizer), +} + +impl Message { + fn format(&mut self, cmd: &Command, usage: String) { + match self { + Message::Raw(s) => { + let mut c = Colorizer::new(Stream::Stderr, cmd.get_color()); + + let mut message = String::new(); + std::mem::swap(s, &mut message); + start_error(&mut c); + c.none(message); + put_usage(&mut c, usage); + try_help(&mut c, get_help_flag(cmd)); + *self = Self::Formatted(c); + } + Message::Formatted(_) => {} + } + } + + fn formatted(&self) -> Cow { + match self { + Message::Raw(s) => { + let mut c = Colorizer::new(Stream::Stderr, ColorChoice::Never); + start_error(&mut c); + c.none(s); + Cow::Owned(c) + } + Message::Formatted(c) => Cow::Borrowed(c), + } + } +} + +impl From for Message { + fn from(inner: String) -> Self { + Self::Raw(inner) + } +} + +impl From for Message { + fn from(inner: Colorizer) -> Self { + Self::Formatted(inner) + } +} + +#[cfg(feature = "debug")] +#[derive(Debug)] +struct Backtrace(backtrace::Backtrace); + +#[cfg(feature = "debug")] +impl Backtrace { + fn new() -> Option { + Some(Self(backtrace::Backtrace::new())) + } +} + +#[cfg(feature = "debug")] +impl Display for Backtrace { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // `backtrace::Backtrace` uses `Debug` instead of `Display` + write!(f, "{:?}", self.0) + } +} + +#[cfg(not(feature = "debug"))] +#[derive(Debug)] +struct Backtrace; + +#[cfg(not(feature = "debug"))] +impl Backtrace { + fn new() -> Option { + None + } +} + +#[cfg(not(feature = "debug"))] +impl Display for Backtrace { + fn fmt(&self, _: &mut Formatter) -> fmt::Result { + Ok(()) + } +} + +#[test] +fn check_auto_traits() { + static_assertions::assert_impl_all!(Error: Send, Sync, Unpin); +} diff --git a/vendor/clap-3.2.20/src/lib.rs b/vendor/clap-3.2.20/src/lib.rs new file mode 100644 index 000000000..5cefe6ec1 --- /dev/null +++ b/vendor/clap-3.2.20/src/lib.rs @@ -0,0 +1,232 @@ +// Copyright ⓒ 2015-2016 Kevin B. Knapp and [`clap-rs` contributors](https://github.com/clap-rs/clap/graphs/contributors). +// Licensed under the MIT license +// (see LICENSE or ) All files in the project carrying such +// notice may not be copied, modified, or distributed except according to those terms. + +//! > **Command Line Argument Parser for Rust** +//! +//! Quick Links: +//! - Derive [tutorial][_derive::_tutorial] and [reference][_derive] +//! - Builder [tutorial][_tutorial] and [reference](index.html) +//! - [Cookbook][_cookbook] +//! - [FAQ][_faq] +//! - [Discussions](https://github.com/clap-rs/clap/discussions) +//! +//! ## Aspirations +//! +//! - Out of the box, users get a polished CLI experience +//! - Including common argument behavior, help generation, suggested fixes for users, colored output, [shell completions](https://github.com/clap-rs/clap/tree/master/clap_complete), etc +//! - Flexible enough to port your existing CLI interface +//! - However, we won't necessarily streamline support for each use case +//! - Reasonable parse performance +//! - Resilient maintainership, including +//! - Willing to break compatibility rather than batching up breaking changes in large releases +//! - Leverage feature flags to keep to one active branch +//! - Being under [WG-CLI](https://github.com/rust-cli/team/) to increase the bus factor +//! - We follow semver and will wait about 6-9 months between major breaking changes +//! - We will support the last two minor Rust releases (MSRV, currently 1.56.1) +//! +//! While these aspirations can be at odds with fast build times and low binary +//! size, we will still strive to keep these reasonable for the flexibility you +//! get. Check out the +//! [argparse-benchmarks](https://github.com/rust-cli/argparse-benchmarks-rs) for +//! CLI parsers optimized for other use cases. +//! +//! ## Example +//! +//! Run +//! ```console +//! $ cargo add clap --features derive +//! ``` +//! *(See also [feature flag reference][_features])* +//! +//! Then define your CLI in `main.rs`: +#![cfg_attr(not(feature = "derive"), doc = " ```ignore")] +#![cfg_attr(feature = "derive", doc = " ```no_run")] +#![doc = include_str!("../examples/demo.rs")] +//! ``` +//! +//! And try it out: +#![doc = include_str!("../examples/demo.md")] +//! +//! See also the derive [tutorial][_derive::_tutorial] and [reference][_derive] +//! +//! ### Related Projects +//! +//! Augment clap: +//! - [wild](https://crates.io/crates/wild) for supporting wildcards (`*`) on Windows like you do Linux +//! - [argfile](https://crates.io/crates/argfile) for loading additional arguments from a file (aka response files) +//! - [shadow-rs](https://crates.io/crates/shadow-rs) for generating `Command::long_version` +//! - [clap_mangen](https://crates.io/crates/clap_mangen) for generating man page source (roff) +//! - [clap_complete](https://crates.io/crates/clap_complete) for shell completion support +//! +//! CLI Helpers +//! - [clap-verbosity-flag](https://crates.io/crates/clap-verbosity-flag) +//! - [clap-cargo](https://crates.io/crates/clap-cargo) +//! - [concolor-clap](https://crates.io/crates/concolor-clap) +//! +//! Testing +//! - [`trycmd`](https://crates.io/crates/trycmd): Bulk snapshot testing +//! - [`snapbox`](https://crates.io/crates/snapbox): Specialized snapshot testing +//! - [`assert_cmd`](https://crates.io/crates/assert_cmd) and [`assert_fs`](https://crates.io/crates/assert_fs): Customized testing +//! +//! Documentation: +//! - [Command-line Apps for Rust](https://rust-cli.github.io/book/index.html) book +//! + +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc(html_logo_url = "https://raw.githubusercontent.com/clap-rs/clap/master/assets/clap.png")] +#![warn( + missing_docs, + missing_debug_implementations, + missing_copy_implementations, + trivial_casts, + unused_allocation, + trivial_numeric_casts, + clippy::single_char_pattern +)] +#![forbid(unsafe_code)] +// HACK https://github.com/rust-lang/rust-clippy/issues/7290 +#![allow(clippy::single_component_path_imports)] +#![allow(clippy::branches_sharing_code)] +// Doesn't allow for debug statements, etc to be unique +#![allow(clippy::if_same_then_else)] + +#[cfg(not(feature = "std"))] +compile_error!("`std` feature is currently required to build `clap`"); + +pub use crate::builder::ArgAction; +pub use crate::builder::Command; +pub use crate::builder::{Arg, ArgGroup}; +pub use crate::error::Error; +pub use crate::parser::ArgMatches; +#[cfg(feature = "color")] +pub use crate::util::color::ColorChoice; +#[cfg(not(feature = "color"))] +#[allow(unused_imports)] +pub(crate) use crate::util::color::ColorChoice; + +pub use crate::derive::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum}; + +#[allow(deprecated)] +pub use crate::builder::App; +pub use crate::builder::{AppFlags, AppSettings, ArgFlags, ArgSettings, PossibleValue, ValueHint}; +pub use crate::error::{ErrorKind, Result}; +#[allow(deprecated)] +pub use crate::parser::{Indices, OsValues, ValueSource, Values}; + +#[cfg(feature = "yaml")] +#[doc(hidden)] +#[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" + ) +)] +#[doc(hidden)] +pub use yaml_rust::YamlLoader; + +#[cfg(feature = "derive")] +#[doc(hidden)] +pub use clap_derive::{self, *}; + +/// Deprecated, replaced with [`CommandFactory`] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `CommandFactory`") +)] +pub use CommandFactory as IntoApp; +/// Deprecated, replaced with [`Parser`] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Parser`") +)] +#[doc(hidden)] +pub use Parser as StructOpt; +/// Deprecated, replaced with [`ValueEnum`] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ValueEnum`") +)] +pub use ValueEnum as ArgEnum; + +#[cfg(feature = "unstable-doc")] +pub mod _cookbook; +#[cfg(feature = "unstable-doc")] +pub mod _derive; +#[cfg(feature = "unstable-doc")] +pub mod _faq; +#[cfg(feature = "unstable-doc")] +pub mod _features; +#[cfg(feature = "unstable-doc")] +pub mod _tutorial; + +#[doc(hidden)] +pub mod __macro_refs { + #[cfg(any(feature = "derive", feature = "cargo"))] + #[doc(hidden)] + pub use once_cell; +} + +#[macro_use] +#[allow(missing_docs)] +mod macros; + +mod derive; + +#[cfg(feature = "regex")] +pub use crate::builder::RegexRef; + +pub mod builder; +pub mod error; +pub mod parser; + +mod mkeymap; +mod output; +mod util; + +const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \ + report at https://github.com/clap-rs/clap/issues"; +const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point"; + +/// Deprecated, replaced with [`Command::new`], unless you were looking for [Subcommand] +#[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `Command::new` unless you intended the `Subcommand` trait" + ) +)] +#[doc(hidden)] +#[derive(Debug, Copy, Clone)] +pub struct SubCommand {} + +#[allow(deprecated)] +impl SubCommand { + /// Deprecated, replaced with [`Command::new`]. + /// Did you mean Subcommand (lower-case c)? + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `Command::new`") + )] + #[doc(hidden)] + pub fn with_name<'help>(name: &str) -> App<'help> { + Command::new(name) + } + + /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? + #[cfg(feature = "yaml")] + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" + ) + )] + #[doc(hidden)] + pub fn from_yaml(yaml: &yaml_rust::Yaml) -> App { + #![allow(deprecated)] + Command::from_yaml(yaml) + } +} diff --git a/vendor/clap-3.2.20/src/macros.rs b/vendor/clap-3.2.20/src/macros.rs new file mode 100644 index 000000000..1f9167408 --- /dev/null +++ b/vendor/clap-3.2.20/src/macros.rs @@ -0,0 +1,1058 @@ +/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? +#[cfg(feature = "yaml")] +#[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" + ) +)] +#[doc(hidden)] +#[macro_export] +macro_rules! load_yaml { + ($yaml:expr) => { + &$crate::YamlLoader::load_from_str(include_str!($yaml)).expect("failed to load YAML file") + [0] + }; +} + +/// Deprecated, replaced with [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t] +#[macro_export] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`") +)] +#[doc(hidden)] +macro_rules! value_t { + ($m:ident, $v:expr, $t:ty) => { + $crate::value_t!($m.value_of($v), $t) + }; + ($m:ident.value_of($v:expr), $t:ty) => { + $m.value_of_t::<$t>($v) + }; +} + +/// Deprecated, replaced with [`ArgMatches::value_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit] +#[macro_export] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`") +)] +#[doc(hidden)] +macro_rules! value_t_or_exit { + ($m:ident, $v:expr, $t:ty) => { + value_t_or_exit!($m.value_of($v), $t) + }; + ($m:ident.value_of($v:expr), $t:ty) => { + $m.value_of_t_or_exit::<$t>($v) + }; +} + +/// Deprecated, replaced with [`ArgMatches::values_of_t`][crate::ArgMatches::value_of_t] +#[macro_export] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`") +)] +#[doc(hidden)] +macro_rules! values_t { + ($m:ident, $v:expr, $t:ty) => { + values_t!($m.values_of($v), $t) + }; + ($m:ident.values_of($v:expr), $t:ty) => { + $m.values_of_t::<$t>($v) + }; +} + +/// Deprecated, replaced with [`ArgMatches::values_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit] +#[macro_export] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`") +)] +#[doc(hidden)] +macro_rules! values_t_or_exit { + ($m:ident, $v:expr, $t:ty) => { + values_t_or_exit!($m.values_of($v), $t) + }; + ($m:ident.values_of($v:expr), $t:ty) => { + $m.values_of_t_or_exit::<$t>($v) + }; +} + +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`") +)] +#[doc(hidden)] +#[macro_export] +macro_rules! _clap_count_exprs { + () => { 0 }; + ($e:expr) => { 1 }; + ($e:expr, $($es:expr),+) => { 1 + $crate::_clap_count_exprs!($($es),*) }; +} + +/// Deprecated, replaced with [`ArgEnum`][crate::ArgEnum] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`") +)] +#[doc(hidden)] +#[macro_export] +macro_rules! arg_enum { + (@as_item $($i:item)*) => ($($i)*); + (@impls ( $($tts:tt)* ) -> ($e:ident, $($v:ident),+)) => { + $crate::arg_enum!(@as_item + $($tts)* + + impl ::std::str::FromStr for $e { + type Err = String; + + fn from_str(s: &str) -> ::std::result::Result { + #[allow(deprecated, unused_imports)] + use ::std::ascii::AsciiExt; + match s { + $(stringify!($v) | + _ if s.eq_ignore_ascii_case(stringify!($v)) => Ok($e::$v)),+, + _ => Err({ + let v = vec![ + $(stringify!($v),)+ + ]; + format!("valid values: {}", + v.join(", ")) + }), + } + } + } + impl ::std::fmt::Display for $e { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + $($e::$v => write!(f, stringify!($v)),)+ + } + } + } + impl $e { + #[allow(dead_code)] + pub fn variants() -> [&'static str; $crate::_clap_count_exprs!($(stringify!($v)),+)] { + [ + $(stringify!($v),)+ + ] + } + }); + }; + ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + $crate::arg_enum!(@impls + ($(#[$($m),+])+ + pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + $crate::arg_enum!(@impls + ($(#[$($m),+])+ + pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + $crate::arg_enum!(@impls + ($(#[$($m),+])+ + enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + $crate::arg_enum!(@impls + ($(#[$($m),+])+ + enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + $crate::arg_enum!(@impls + (pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + $crate::arg_enum!(@impls + (pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + $crate::arg_enum!(@impls + (enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + $crate::arg_enum!(@impls + (enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; +} + +/// Allows you to pull the version from your Cargo.toml at compile time as +/// `MAJOR.MINOR.PATCH_PKGVERSION_PRE` +/// +/// # Examples +/// +/// ```no_run +/// # #[macro_use] +/// # extern crate clap; +/// # use clap::Command; +/// # fn main() { +/// let m = Command::new("cmd") +/// .version(crate_version!()) +/// .get_matches(); +/// # } +/// ``` +#[cfg(feature = "cargo")] +#[macro_export] +macro_rules! crate_version { + () => { + env!("CARGO_PKG_VERSION") + }; +} + +/// Allows you to pull the authors for the command from your Cargo.toml at +/// compile time in the form: +/// `"author1 lastname :author2 lastname "` +/// +/// You can replace the colons with a custom separator by supplying a +/// replacement string, so, for example, +/// `crate_authors!(",\n")` would become +/// `"author1 lastname ,\nauthor2 lastname ,\nauthor3 lastname "` +/// +/// # Examples +/// +/// ```no_run +/// # #[macro_use] +/// # extern crate clap; +/// # use clap::Command; +/// # fn main() { +/// let m = Command::new("cmd") +/// .author(crate_authors!("\n")) +/// .get_matches(); +/// # } +/// ``` +#[cfg(feature = "cargo")] +#[macro_export] +macro_rules! crate_authors { + ($sep:expr) => {{ + static CACHED: clap::__macro_refs::once_cell::sync::Lazy = + clap::__macro_refs::once_cell::sync::Lazy::new(|| { + env!("CARGO_PKG_AUTHORS").replace(':', $sep) + }); + + let s: &'static str = &*CACHED; + s + }}; + () => { + env!("CARGO_PKG_AUTHORS") + }; +} + +/// Allows you to pull the description from your Cargo.toml at compile time. +/// +/// # Examples +/// +/// ```no_run +/// # #[macro_use] +/// # extern crate clap; +/// # use clap::Command; +/// # fn main() { +/// let m = Command::new("cmd") +/// .about(crate_description!()) +/// .get_matches(); +/// # } +/// ``` +#[cfg(feature = "cargo")] +#[macro_export] +macro_rules! crate_description { + () => { + env!("CARGO_PKG_DESCRIPTION") + }; +} + +/// Allows you to pull the name from your Cargo.toml at compile time. +/// +/// # Examples +/// +/// ```no_run +/// # #[macro_use] +/// # extern crate clap; +/// # use clap::Command; +/// # fn main() { +/// let m = Command::new(crate_name!()) +/// .get_matches(); +/// # } +/// ``` +#[cfg(feature = "cargo")] +#[macro_export] +macro_rules! crate_name { + () => { + env!("CARGO_PKG_NAME") + }; +} + +/// Allows you to build the `Command` instance from your Cargo.toml at compile time. +/// +/// **NOTE:** Changing the values in your `Cargo.toml` does not trigger a re-build automatically, +/// and therefore won't change the generated output until you recompile. +/// +/// In some cases you can "trick" the compiler into triggering a rebuild when your +/// `Cargo.toml` is changed by including this in your `src/main.rs` file +/// `include_str!("../Cargo.toml");` +/// +/// # Examples +/// +/// ```no_run +/// # #[macro_use] +/// # extern crate clap; +/// # fn main() { +/// let m = command!().get_matches(); +/// # } +/// ``` +#[cfg(feature = "cargo")] +#[macro_export] +macro_rules! command { + () => {{ + $crate::command!($crate::crate_name!()) + }}; + ($name:expr) => {{ + let mut cmd = $crate::Command::new($name).version($crate::crate_version!()); + + let author = $crate::crate_authors!(); + if !author.is_empty() { + cmd = cmd.author(author) + } + + let about = $crate::crate_description!(); + if !about.is_empty() { + cmd = cmd.about(about) + } + + cmd + }}; +} + +/// Requires `cargo` feature flag to be enabled. +#[cfg(not(feature = "cargo"))] +#[macro_export] +macro_rules! command { + () => {{ + compile_error!("`cargo` feature flag is required"); + }}; + ($name:expr) => {{ + compile_error!("`cargo` feature flag is required"); + }}; +} + +/// Deprecated, replaced with [`clap::command!`][crate::command] +#[cfg(feature = "cargo")] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.1.0", note = "Replaced with `clap::command!") +)] +#[macro_export] +macro_rules! app_from_crate { + () => {{ + let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!()); + + let author = $crate::crate_authors!(", "); + if !author.is_empty() { + cmd = cmd.author(author) + } + + let about = $crate::crate_description!(); + if !about.is_empty() { + cmd = cmd.about(about) + } + + cmd + }}; + ($sep:expr) => {{ + let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!()); + + let author = $crate::crate_authors!($sep); + if !author.is_empty() { + cmd = cmd.author(author) + } + + let about = $crate::crate_description!(); + if !about.is_empty() { + cmd = cmd.about(about) + } + + cmd + }}; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! arg_impl { + ( @string $val:ident ) => { + stringify!($val) + }; + ( @string $val:literal ) => {{ + let ident_or_string_literal: &str = $val; + ident_or_string_literal + }}; + ( @string $val:tt ) => { + ::std::compile_error!("Only identifiers or string literals supported"); + }; + ( @string ) => { + None + }; + + ( @char $val:ident ) => {{ + let ident_or_char_literal = stringify!($val); + debug_assert_eq!( + ident_or_char_literal.len(), + 1, + "Single-letter identifier expected, got {}", + ident_or_char_literal + ); + ident_or_char_literal.chars().next().unwrap() + }}; + ( @char $val:literal ) => {{ + let ident_or_char_literal: char = $val; + ident_or_char_literal + }}; + ( @char ) => {{ + None + }}; + + ( + @arg + ($arg:expr) + --$long:ident + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } + + let mut arg = $arg; + let long = $crate::arg_impl! { @string $long }; + if arg.get_id().is_empty() { + arg = arg.id(long); + } + arg.long(long) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + --$long:literal + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } + + let mut arg = $arg; + let long = $crate::arg_impl! { @string $long }; + if arg.get_id().is_empty() { + arg = arg.id(long); + } + arg.long(long) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + -$short:ident + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); + debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } + + $arg.short($crate::arg_impl! { @char $short }) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + -$short:literal + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); + debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } + + $arg.short($crate::arg_impl! { @char $short }) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + <$value_name:ident> + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } + debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); + + let mut arg = $arg; + + arg = arg.required(true); + arg = arg.takes_value(true); + + let value_name = $crate::arg_impl! { @string $value_name }; + if arg.get_id().is_empty() { + arg = arg.id(value_name); + } + arg.value_name(value_name) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + <$value_name:literal> + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } + debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); + + let mut arg = $arg; + + arg = arg.required(true); + arg = arg.takes_value(true); + + let value_name = $crate::arg_impl! { @string $value_name }; + if arg.get_id().is_empty() { + arg = arg.id(value_name); + } + arg.value_name(value_name) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + [$value_name:ident] + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } + debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); + + let mut arg = $arg; + + if arg.get_long().is_none() && arg.get_short().is_none() { + arg = arg.required(false); + } else { + arg = arg.min_values(0).max_values(1); + } + arg = arg.takes_value(true); + + let value_name = $crate::arg_impl! { @string $value_name }; + if arg.get_id().is_empty() { + arg = arg.id(value_name); + } + arg.value_name(value_name) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + [$value_name:literal] + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({ + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } + debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); + + let mut arg = $arg; + + if arg.get_long().is_none() && arg.get_short().is_none() { + arg = arg.required(false); + } else { + arg = arg.min_values(0).max_values(1); + } + arg = arg.takes_value(true); + + let value_name = $crate::arg_impl! { @string $value_name }; + if arg.get_id().is_empty() { + arg = arg.id(value_name); + } + arg.value_name(value_name) + }) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + ... + $($tail:tt)* + ) => { + $crate::arg_impl! { + @arg + ({#[allow(deprecated)]{ + $arg.multiple_occurrences(true) + }}) + $($tail)* + } + }; + ( + @arg + ($arg:expr) + $help:literal + ) => { + $arg.help($help) + }; + ( + @arg + ($arg:expr) + ) => { + $arg + }; +} + +/// Create an [`Arg`] from a usage string. +/// +/// Allows creation of basic settings for the [`Arg`]. +/// +/// **NOTE**: Not all settings may be set using the usage string method. Some properties are +/// only available via the builder pattern. +/// +/// # Syntax +/// +/// Usage strings typically following the form: +/// +/// ```notrust +/// [explicit name] [short] [long] [value names] [...] [help string] +/// ``` +/// +/// ### Explicit Name +/// +/// The name may be either a bare-word or a string, followed by a `:`, like `name:` or +/// `"name":`. +/// +/// *Note:* This is an optional field, if it's omitted the argument will use one of the additional +/// fields as the name using the following priority order: +/// +/// 1. Explicit Name +/// 2. Long +/// 3. Value Name +/// +/// See [`Arg::name`][crate::Arg::name]. +/// +/// ### Short +/// +/// A short flag is a `-` followed by either a bare-character or quoted character, like `-f` or +/// `-'f'`. +/// +/// See [`Arg::short`][crate::Arg::short]. +/// +/// ### Long +/// +/// A long flag is a `--` followed by either a bare-word or a string, like `--foo` or +/// `--"foo"`. +/// +/// See [`Arg::long`][crate::Arg::long]. +/// +/// ### Values (Value Notation) +/// +/// This is set by placing bare-word between: +/// - `[]` like `[FOO]` +/// - Positional argument: optional +/// - Named argument: optional value +/// - `<>` like ``: required +/// +/// See [`Arg::value_name`][crate::Arg::value_name]. +/// +/// ### `...` +/// +/// `...` (three consecutive dots/periods) specifies that this argument may occur multiple +/// times (not to be confused with multiple values per occurrence). +/// +/// See [`Arg::multiple_occurrences`][crate::Arg::multiple_occurrences]. +/// +/// ### Help String +/// +/// The help string is denoted between a pair of double quotes `""` and may contain any +/// characters. +/// +/// # Examples +/// +/// ```rust +/// # use clap::{Command, Arg, arg}; +/// Command::new("prog") +/// .args(&[ +/// arg!(--config "a required file for the configuration and no short"), +/// arg!(-d --debug ... "turns on debugging information and allows multiples"), +/// arg!([input] "an optional input file to use") +/// ]) +/// # ; +/// ``` +/// [`Arg`]: ./struct.Arg.html +#[macro_export] +macro_rules! arg { + ( $name:ident: $($tail:tt)+ ) => { + $crate::arg_impl! { + @arg ($crate::Arg::new($crate::arg_impl! { @string $name })) $($tail)+ + } + }; + ( $($tail:tt)+ ) => {{ + let arg = $crate::arg_impl! { + @arg ($crate::Arg::default()) $($tail)+ + }; + debug_assert!(!arg.get_id().is_empty(), "Without a value or long flag, the `name:` prefix is required"); + arg + }}; +} + +/// Deprecated, replaced with [`clap::Parser`][crate::Parser] and [`clap::arg!`][crate::arg] (Issue clap-rs/clap#2835) +#[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.0.0", + note = "Replaced with `clap::Parser` for a declarative API (Issue clap-rs/clap#2835)" + ) +)] +#[doc(hidden)] +#[macro_export] +macro_rules! clap_app { + (@app ($builder:expr)) => { $builder }; + (@app ($builder:expr) (@arg ($name:expr): $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($builder.arg( + $crate::clap_app!{ @arg ($crate::Arg::new($name)) (-) $($tail)* })) + $($tt)* + } + }; + (@app ($builder:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($builder.arg( + $crate::clap_app!{ @arg ($crate::Arg::new(stringify!($name))) (-) $($tail)* })) + $($tt)* + } + }; + (@app ($builder:expr) (@setting $setting:ident) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($builder.setting($crate::AppSettings::$setting)) + $($tt)* + } + }; +// Treat the application builder as an argument to set its attributes + (@app ($builder:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app ($crate::clap_app!{ @arg ($builder) $($attr)* }) $($tt)* } + }; + (@app ($builder:expr) (@group $name:ident => $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name))) $($tail)* }) + $($tt)* + } + }; + (@app ($builder:expr) (@group $name:ident !$ident:ident => $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(false)) $($tail)* }) + $($tt)* + } + }; + (@app ($builder:expr) (@group $name:ident +$ident:ident => $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(true)) $($tail)* }) + $($tt)* + } + }; +// Handle subcommand creation + (@app ($builder:expr) (@subcommand $name:ident => $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @app + ($builder.subcommand( + $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* } + )) + $($tt)* + } + }; +// Yaml like function calls - used for setting various meta directly against the app + (@app ($builder:expr) ($ident:ident: $($v:expr),*) $($tt:tt)*) => { +// $crate::clap_app!{ @app ($builder.$ident($($v),*)) $($tt)* } + $crate::clap_app!{ @app + ($builder.$ident($($v),*)) + $($tt)* + } + }; + +// Add members to group and continue argument handling with the parent builder + (@group ($builder:expr, $group:expr)) => { $builder.group($group) }; + // Treat the group builder as an argument to set its attributes + (@group ($builder:expr, $group:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @group ($builder, $crate::clap_app!{ @arg ($group) (-) $($attr)* }) $($tt)* } + }; + (@group ($builder:expr, $group:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => { + $crate::clap_app!{ @group + ($crate::clap_app!{ @app ($builder) (@arg $name: $($tail)*) }, + $group.arg(stringify!($name))) + $($tt)* + } + }; + +// No more tokens to munch + (@arg ($arg:expr) $modes:tt) => { $arg }; +// Shorthand tokens influenced by the usage_string + (@arg ($arg:expr) $modes:tt --($long:expr) $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.long($long)) $modes $($tail)* } + }; + (@arg ($arg:expr) $modes:tt --$long:ident $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.long(stringify!($long))) $modes $($tail)* } + }; + (@arg ($arg:expr) $modes:tt -$short:ident $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.short(stringify!($short).chars().next().unwrap())) $modes $($tail)* } + }; + (@arg ($arg:expr) (-) <$var:ident> $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value +required $($tail)* } + }; + (@arg ($arg:expr) (+) <$var:ident> $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* } + }; + (@arg ($arg:expr) (-) [$var:ident] $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value $($tail)* } + }; + (@arg ($arg:expr) (+) [$var:ident] $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* } + }; + (@arg ($arg:expr) $modes:tt ... $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg) $modes +multiple +takes_value $($tail)* } + }; +// Shorthand magic + (@arg ($arg:expr) $modes:tt #{$n:expr, $m:expr} $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg) $modes min_values($n) max_values($m) $($tail)* } + }; + (@arg ($arg:expr) $modes:tt * $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg) $modes +required $($tail)* } + }; +// !foo -> .foo(false) + (@arg ($arg:expr) $modes:tt !$ident:ident $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.$ident(false)) $modes $($tail)* } + }; +// +foo -> .foo(true) + (@arg ($arg:expr) $modes:tt +$ident:ident $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.$ident(true)) $modes $($tail)* } + }; +// Validator + (@arg ($arg:expr) $modes:tt {$fn_:expr} $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.validator($fn_)) $modes $($tail)* } + }; + (@as_expr $expr:expr) => { $expr }; +// Help + (@arg ($arg:expr) $modes:tt $desc:tt) => { $arg.help($crate::clap_app!{ @as_expr $desc }) }; +// Handle functions that need to be called multiple times for each argument + (@arg ($arg:expr) $modes:tt $ident:ident[$($target:ident)*] $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg $( .$ident(stringify!($target)) )*) $modes $($tail)* } + }; +// Inherit builder's functions, e.g. `index(2)`, `requires_if("val", "arg")` + (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr),*) $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } + }; +// Inherit builder's functions with trailing comma, e.g. `index(2,)`, `requires_if("val", "arg",)` + (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr,)*) $($tail:tt)*) => { + $crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } + }; + +// Build a subcommand outside of an app. + (@subcommand $name:ident => $($tail:tt)*) => { + $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* } + }; +// Start the magic + (($name:expr) => $($tail:tt)*) => {{ + $crate::clap_app!{ @app ($crate::Command::new($name)) $($tail)*} + }}; + + ($name:ident => $($tail:tt)*) => {{ + $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)*} + }}; +} + +macro_rules! impl_settings { + ($settings:ident, $flags:ident, + $( + $(#[$inner:ident $($args:tt)*])* + $setting:ident => $flag:path + ),+ + ) => { + impl $flags { + #[allow(dead_code)] + pub(crate) fn empty() -> Self { + $flags(Flags::empty()) + } + + #[allow(dead_code)] + pub(crate) fn insert(&mut self, rhs: Self) { + self.0.insert(rhs.0); + } + + #[allow(dead_code)] + pub(crate) fn remove(&mut self, rhs: Self) { + self.0.remove(rhs.0); + } + + #[allow(dead_code)] + pub(crate) fn set(&mut self, s: $settings) { + #[allow(deprecated)] // some Settings might be deprecated + match s { + $( + $(#[$inner $($args)*])* + $settings::$setting => self.0.insert($flag), + )* + } + } + + #[allow(dead_code)] + pub(crate) fn unset(&mut self, s: $settings) { + #[allow(deprecated)] // some Settings might be deprecated + match s { + $( + $(#[$inner $($args)*])* + $settings::$setting => self.0.remove($flag), + )* + } + } + + #[allow(dead_code)] + pub(crate) fn is_set(&self, s: $settings) -> bool { + #[allow(deprecated)] // some Settings might be deprecated + match s { + $( + $(#[$inner $($args)*])* + $settings::$setting => self.0.contains($flag), + )* + } + } + } + + impl BitOr for $flags { + type Output = Self; + + fn bitor(mut self, rhs: Self) -> Self::Output { + self.0.insert(rhs.0); + self + } + } + + impl From<$settings> for $flags { + fn from(setting: $settings) -> Self { + let mut flags = $flags::empty(); + flags.set(setting); + flags + } + } + + impl BitOr<$settings> for $flags { + type Output = Self; + + fn bitor(mut self, rhs: $settings) -> Self::Output { + self.set(rhs); + self + } + } + + impl BitOr for $settings { + type Output = $flags; + + fn bitor(self, rhs: Self) -> Self::Output { + let mut flags = $flags::empty(); + flags.set(self); + flags.set(rhs); + flags + } + } + } +} + +// Convenience for writing to stderr thanks to https://github.com/BurntSushi +macro_rules! wlnerr { + ($($arg:tt)*) => ({ + use std::io::{Write, stderr}; + writeln!(&mut stderr(), $($arg)*).ok(); + }) +} + +#[cfg(feature = "debug")] +macro_rules! debug { + ($($arg:tt)*) => ({ + let prefix = format!("[{:>w$}] \t", module_path!(), w = 28); + let body = format!($($arg)*); + let mut color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto); + color.hint(prefix); + color.hint(body); + color.none("\n"); + let _ = color.print(); + }) +} + +#[cfg(not(feature = "debug"))] +macro_rules! debug { + ($($arg:tt)*) => {}; +} diff --git a/vendor/clap-3.2.20/src/mkeymap.rs b/vendor/clap-3.2.20/src/mkeymap.rs new file mode 100644 index 000000000..97ecdda77 --- /dev/null +++ b/vendor/clap-3.2.20/src/mkeymap.rs @@ -0,0 +1,193 @@ +use std::iter::Iterator; +use std::ops::Index; +use std::{ffi::OsStr, ffi::OsString}; + +use crate::util::Id; +use crate::Arg; +use crate::INTERNAL_ERROR_MSG; + +#[derive(PartialEq, Eq, Debug, Clone)] +pub(crate) struct Key { + key: KeyType, + index: usize, +} + +#[derive(Default, PartialEq, Eq, Debug, Clone)] +pub(crate) struct MKeyMap<'help> { + /// All of the arguments. + args: Vec>, + + // Cache part: + /// Will be set after `_build()`. + keys: Vec, +} + +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub(crate) enum KeyType { + Short(char), + Long(OsString), + Position(usize), +} + +impl KeyType { + pub(crate) fn is_position(&self) -> bool { + matches!(self, KeyType::Position(_)) + } +} + +impl PartialEq for KeyType { + fn eq(&self, rhs: &usize) -> bool { + match self { + KeyType::Position(x) => x == rhs, + _ => false, + } + } +} + +impl PartialEq<&str> for KeyType { + fn eq(&self, rhs: &&str) -> bool { + match self { + KeyType::Long(l) => l == rhs, + _ => false, + } + } +} + +impl PartialEq for KeyType { + fn eq(&self, rhs: &str) -> bool { + match self { + KeyType::Long(l) => l == rhs, + _ => false, + } + } +} + +impl PartialEq for KeyType { + fn eq(&self, rhs: &OsStr) -> bool { + match self { + KeyType::Long(l) => l == rhs, + _ => false, + } + } +} + +impl PartialEq for KeyType { + fn eq(&self, rhs: &char) -> bool { + match self { + KeyType::Short(c) => c == rhs, + _ => false, + } + } +} + +impl<'help> MKeyMap<'help> { + /// If any arg has corresponding key in this map, we can search the key with + /// u64(for positional argument), char(for short flag), &str and OsString + /// (for long flag) + pub(crate) fn contains(&self, key: K) -> bool + where + KeyType: PartialEq, + { + self.keys.iter().any(|x| x.key == key) + } + + /// Reserves capacity for at least additional more elements to be inserted + pub(crate) fn reserve(&mut self, additional: usize) { + self.args.reserve(additional); + } + + /// Push an argument in the map. + pub(crate) fn push(&mut self, new_arg: Arg<'help>) { + self.args.push(new_arg); + } + + /// Find the arg have corresponding key in this map, we can search the key + /// with u64(for positional argument), char(for short flag), &str and + /// OsString (for long flag) + pub(crate) fn get(&self, key: &K) -> Option<&Arg<'help>> + where + KeyType: PartialEq, + { + self.keys + .iter() + .find(|k| &k.key == key) + .map(|k| &self.args[k.index]) + } + + /// Find out if the map have no arg. + pub(crate) fn is_empty(&self) -> bool { + self.args.is_empty() + } + + /// Return iterators of all keys. + pub(crate) fn keys(&self) -> impl Iterator { + self.keys.iter().map(|x| &x.key) + } + + /// Return iterators of all args. + pub(crate) fn args(&self) -> impl Iterator> { + self.args.iter() + } + + /// Return mutable iterators of all args. + pub(crate) fn args_mut<'map>(&'map mut self) -> impl Iterator> { + self.args.iter_mut() + } + + /// We need a lazy build here since some we may change args after creating + /// the map, you can checkout who uses `args_mut`. + pub(crate) fn _build(&mut self) { + for (i, arg) in self.args.iter().enumerate() { + append_keys(&mut self.keys, arg, i); + } + } + + /// Remove an arg in the graph by Id, usually used by `mut_arg`. Return + /// `Some(arg)` if removed. + pub(crate) fn remove_by_name(&mut self, name: &Id) -> Option> { + self.args + .iter() + .position(|arg| &arg.id == name) + // since it's a cold function, using this wouldn't hurt much + .map(|i| self.args.remove(i)) + } + + /// Remove an arg based on index + pub(crate) fn remove(&mut self, index: usize) -> Arg<'help> { + self.args.remove(index) + } +} + +impl<'help> Index<&'_ KeyType> for MKeyMap<'help> { + type Output = Arg<'help>; + + fn index(&self, key: &KeyType) -> &Self::Output { + self.get(key).expect(INTERNAL_ERROR_MSG) + } +} + +/// Generate key types for an specific Arg. +fn append_keys(keys: &mut Vec, arg: &Arg, index: usize) { + if let Some(pos_index) = arg.index { + let key = KeyType::Position(pos_index); + keys.push(Key { key, index }); + } else { + if let Some(short) = arg.short { + let key = KeyType::Short(short); + keys.push(Key { key, index }); + } + if let Some(long) = arg.long { + let key = KeyType::Long(OsString::from(long)); + keys.push(Key { key, index }); + } + + for (short, _) in arg.short_aliases.iter() { + let key = KeyType::Short(*short); + keys.push(Key { key, index }); + } + for (long, _) in arg.aliases.iter() { + let key = KeyType::Long(OsString::from(long)); + keys.push(Key { key, index }); + } + } +} diff --git a/vendor/clap-3.2.20/src/output/fmt.rs b/vendor/clap-3.2.20/src/output/fmt.rs new file mode 100644 index 000000000..dc1f46e08 --- /dev/null +++ b/vendor/clap-3.2.20/src/output/fmt.rs @@ -0,0 +1,158 @@ +use crate::util::color::ColorChoice; + +use std::{ + fmt::{self, Display, Formatter}, + io::{self, Write}, +}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) enum Stream { + Stdout, + Stderr, +} + +#[derive(Clone, Debug)] +pub(crate) struct Colorizer { + stream: Stream, + #[allow(unused)] + color_when: ColorChoice, + pieces: Vec<(String, Style)>, +} + +impl Colorizer { + #[inline(never)] + pub(crate) fn new(stream: Stream, color_when: ColorChoice) -> Self { + Colorizer { + stream, + color_when, + pieces: vec![], + } + } + + #[inline(never)] + pub(crate) fn good(&mut self, msg: impl Into) { + self.pieces.push((msg.into(), Style::Good)); + } + + #[inline(never)] + pub(crate) fn warning(&mut self, msg: impl Into) { + self.pieces.push((msg.into(), Style::Warning)); + } + + #[inline(never)] + pub(crate) fn error(&mut self, msg: impl Into) { + self.pieces.push((msg.into(), Style::Error)); + } + + #[inline(never)] + #[allow(dead_code)] + pub(crate) fn hint(&mut self, msg: impl Into) { + self.pieces.push((msg.into(), Style::Hint)); + } + + #[inline(never)] + pub(crate) fn none(&mut self, msg: impl Into) { + self.pieces.push((msg.into(), Style::Default)); + } +} + +/// Printing methods. +impl Colorizer { + #[cfg(feature = "color")] + pub(crate) fn print(&self) -> io::Result<()> { + use termcolor::{BufferWriter, ColorChoice as DepColorChoice, ColorSpec, WriteColor}; + + let color_when = match self.color_when { + ColorChoice::Always => DepColorChoice::Always, + ColorChoice::Auto if is_a_tty(self.stream) => DepColorChoice::Auto, + _ => DepColorChoice::Never, + }; + + let writer = match self.stream { + Stream::Stderr => BufferWriter::stderr(color_when), + Stream::Stdout => BufferWriter::stdout(color_when), + }; + + let mut buffer = writer.buffer(); + + for piece in &self.pieces { + let mut color = ColorSpec::new(); + match piece.1 { + Style::Good => { + color.set_fg(Some(termcolor::Color::Green)); + } + Style::Warning => { + color.set_fg(Some(termcolor::Color::Yellow)); + } + Style::Error => { + color.set_fg(Some(termcolor::Color::Red)); + color.set_bold(true); + } + Style::Hint => { + color.set_dimmed(true); + } + Style::Default => {} + } + + buffer.set_color(&color)?; + buffer.write_all(piece.0.as_bytes())?; + buffer.reset()?; + } + + writer.print(&buffer) + } + + #[cfg(not(feature = "color"))] + pub(crate) fn print(&self) -> io::Result<()> { + // [e]println can't be used here because it panics + // if something went wrong. We don't want that. + match self.stream { + Stream::Stdout => { + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + write!(stdout, "{}", self) + } + Stream::Stderr => { + let stderr = std::io::stderr(); + let mut stderr = stderr.lock(); + write!(stderr, "{}", self) + } + } + } +} + +/// Color-unaware printing. Never uses coloring. +impl Display for Colorizer { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + for piece in &self.pieces { + Display::fmt(&piece.0, f)?; + } + + Ok(()) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Style { + Good, + Warning, + Error, + Hint, + Default, +} + +impl Default for Style { + fn default() -> Self { + Self::Default + } +} + +#[cfg(feature = "color")] +fn is_a_tty(stream: Stream) -> bool { + let stream = match stream { + Stream::Stdout => atty::Stream::Stdout, + Stream::Stderr => atty::Stream::Stderr, + }; + + atty::is(stream) +} diff --git a/vendor/clap-3.2.20/src/output/help.rs b/vendor/clap-3.2.20/src/output/help.rs new file mode 100644 index 000000000..eb53bfa54 --- /dev/null +++ b/vendor/clap-3.2.20/src/output/help.rs @@ -0,0 +1,1176 @@ +// Std +use std::borrow::Cow; +use std::cmp; +use std::fmt::Write as _; +use std::io::{self, Write}; +use std::usize; + +// Internal +use crate::builder::{display_arg_val, Arg, Command}; +use crate::output::{fmt::Colorizer, Usage}; +use crate::PossibleValue; + +// Third party +use indexmap::IndexSet; +use textwrap::core::display_width; + +/// `clap` Help Writer. +/// +/// Wraps a writer stream providing different methods to generate help for `clap` objects. +pub(crate) struct Help<'help, 'cmd, 'writer> { + writer: HelpWriter<'writer>, + cmd: &'cmd Command<'help>, + usage: &'cmd Usage<'help, 'cmd>, + next_line_help: bool, + term_w: usize, + use_long: bool, +} + +// Public Functions +impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { + #[cfg(feature = "unstable-v4")] + const DEFAULT_TEMPLATE: &'static str = "\ + {before-help}{name} {version}\n\ + {author-with-newline}{about-with-newline}\n\ + {usage-heading}\n {usage}\n\ + \n\ + {all-args}{after-help}\ + "; + #[cfg(not(feature = "unstable-v4"))] + const DEFAULT_TEMPLATE: &'static str = "\ + {before-help}{bin} {version}\n\ + {author-with-newline}{about-with-newline}\n\ + {usage-heading}\n {usage}\n\ + \n\ + {all-args}{after-help}\ + "; + + #[cfg(feature = "unstable-v4")] + const DEFAULT_NO_ARGS_TEMPLATE: &'static str = "\ + {before-help}{name} {version}\n\ + {author-with-newline}{about-with-newline}\n\ + {usage-heading}\n {usage}{after-help}\ + "; + #[cfg(not(feature = "unstable-v4"))] + const DEFAULT_NO_ARGS_TEMPLATE: &'static str = "\ + {before-help}{bin} {version}\n\ + {author-with-newline}{about-with-newline}\n\ + {usage-heading}\n {usage}{after-help}\ + "; + + /// Create a new `Help` instance. + pub(crate) fn new( + writer: HelpWriter<'writer>, + cmd: &'cmd Command<'help>, + usage: &'cmd Usage<'help, 'cmd>, + use_long: bool, + ) -> Self { + debug!("Help::new cmd={}, use_long={}", cmd.get_name(), use_long); + let term_w = match cmd.get_term_width() { + Some(0) => usize::MAX, + Some(w) => w, + None => cmp::min( + dimensions().map_or(100, |(w, _)| w), + match cmd.get_max_term_width() { + None | Some(0) => usize::MAX, + Some(mw) => mw, + }, + ), + }; + let next_line_help = cmd.is_next_line_help_set(); + + Help { + writer, + cmd, + usage, + next_line_help, + term_w, + use_long, + } + } + + /// Writes the parser help to the wrapped stream. + pub(crate) fn write_help(&mut self) -> io::Result<()> { + debug!("Help::write_help"); + + if let Some(h) = self.cmd.get_override_help() { + self.none(h)?; + } else if let Some(tmpl) = self.cmd.get_help_template() { + self.write_templated_help(tmpl)?; + } else { + let pos = self + .cmd + .get_positionals() + .any(|arg| should_show_arg(self.use_long, arg)); + let non_pos = self + .cmd + .get_non_positionals() + .any(|arg| should_show_arg(self.use_long, arg)); + let subcmds = self.cmd.has_visible_subcommands(); + + if non_pos || pos || subcmds { + self.write_templated_help(Self::DEFAULT_TEMPLATE)?; + } else { + self.write_templated_help(Self::DEFAULT_NO_ARGS_TEMPLATE)?; + } + } + + self.none("\n")?; + + Ok(()) + } +} + +macro_rules! write_method { + ($_self:ident, $msg:ident, $meth:ident) => { + match &mut $_self.writer { + HelpWriter::Buffer(c) => { + c.$meth(($msg).into()); + Ok(()) + } + HelpWriter::Normal(w) => w.write_all($msg.as_ref()), + } + }; +} + +// Methods to write Arg help. +impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { + #[inline(never)] + fn good + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { + write_method!(self, msg, good) + } + + #[inline(never)] + fn warning + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { + write_method!(self, msg, warning) + } + + #[inline(never)] + fn none + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { + write_method!(self, msg, none) + } + + #[inline(never)] + fn spaces(&mut self, n: usize) -> io::Result<()> { + // A string with 64 consecutive spaces. + const SHORT_SPACE: &str = + " "; + if let Some(short) = SHORT_SPACE.get(..n) { + self.none(short) + } else { + self.none(" ".repeat(n)) + } + } + + /// Writes help for each argument in the order they were declared to the wrapped stream. + fn write_args_unsorted(&mut self, args: &[&Arg<'help>]) -> io::Result<()> { + debug!("Help::write_args_unsorted"); + // The shortest an arg can legally be is 2 (i.e. '-x') + let mut longest = 2; + let mut arg_v = Vec::with_capacity(10); + + for &arg in args + .iter() + .filter(|arg| should_show_arg(self.use_long, *arg)) + { + if arg.longest_filter() { + longest = longest.max(display_width(&arg.to_string())); + debug!( + "Help::write_args_unsorted: arg={:?} longest={}", + arg.get_id(), + longest + ); + } + arg_v.push(arg) + } + + let next_line_help = self.will_args_wrap(args, longest); + + let argc = arg_v.len(); + for (i, arg) in arg_v.iter().enumerate() { + self.write_arg(arg, i + 1 == argc, next_line_help, longest)?; + } + Ok(()) + } + + /// Sorts arguments by length and display order and write their help to the wrapped stream. + fn write_args(&mut self, args: &[&Arg<'help>], _category: &str) -> io::Result<()> { + debug!("Help::write_args {}", _category); + // The shortest an arg can legally be is 2 (i.e. '-x') + let mut longest = 2; + let mut ord_v = Vec::new(); + + // Determine the longest + for &arg in args.iter().filter(|arg| { + // If it's NextLineHelp we don't care to compute how long it is because it may be + // NextLineHelp on purpose simply *because* it's so long and would throw off all other + // args alignment + should_show_arg(self.use_long, *arg) + }) { + if arg.longest_filter() { + longest = longest.max(display_width(&arg.to_string())); + debug!( + "Help::write_args: arg={:?} longest={}", + arg.get_id(), + longest + ); + } + + // Formatting key like this to ensure that: + // 1. Argument has long flags are printed just after short flags. + // 2. For two args both have short flags like `-c` and `-C`, the + // `-C` arg is printed just after the `-c` arg + // 3. For args without short or long flag, print them at last(sorted + // by arg name). + // Example order: -a, -b, -B, -s, --select-file, --select-folder, -x + + let key = if let Some(x) = arg.short { + let mut s = x.to_ascii_lowercase().to_string(); + s.push(if x.is_ascii_lowercase() { '0' } else { '1' }); + s + } else if let Some(x) = arg.long { + x.to_string() + } else { + let mut s = '{'.to_string(); + s.push_str(arg.name); + s + }; + ord_v.push((arg.get_display_order(), key, arg)); + } + ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1))); + + let next_line_help = self.will_args_wrap(args, longest); + + for (i, (_, _, arg)) in ord_v.iter().enumerate() { + let last_arg = i + 1 == ord_v.len(); + self.write_arg(arg, last_arg, next_line_help, longest)?; + } + Ok(()) + } + + /// Writes help for an argument to the wrapped stream. + fn write_arg( + &mut self, + arg: &Arg<'help>, + last_arg: bool, + next_line_help: bool, + longest: usize, + ) -> io::Result<()> { + let spec_vals = &self.spec_vals(arg); + + self.short(arg)?; + self.long(arg)?; + self.val(arg)?; + self.align_to_about(arg, next_line_help, longest)?; + + let about = if self.use_long { + arg.long_help.or(arg.help).unwrap_or("") + } else { + arg.help.or(arg.long_help).unwrap_or("") + }; + + self.help(Some(arg), about, spec_vals, next_line_help, longest)?; + + if !last_arg { + self.none("\n")?; + if next_line_help { + self.none("\n")?; + } + } + Ok(()) + } + + /// Writes argument's short command to the wrapped stream. + fn short(&mut self, arg: &Arg<'help>) -> io::Result<()> { + debug!("Help::short"); + + self.none(TAB)?; + + if let Some(s) = arg.short { + self.good(format!("-{}", s)) + } else if !arg.is_positional() { + self.none(TAB) + } else { + Ok(()) + } + } + + /// Writes argument's long command to the wrapped stream. + fn long(&mut self, arg: &Arg<'help>) -> io::Result<()> { + debug!("Help::long"); + if let Some(long) = arg.long { + if arg.short.is_some() { + self.none(", ")?; + } + self.good(format!("--{}", long))?; + } + Ok(()) + } + + /// Writes argument's possible values to the wrapped stream. + fn val(&mut self, arg: &Arg<'help>) -> io::Result<()> { + debug!("Help::val: arg={}", arg.name); + let mut need_closing_bracket = false; + if arg.is_takes_value_set() && !arg.is_positional() { + let is_optional_val = arg.min_vals == Some(0); + let sep = if arg.is_require_equals_set() { + if is_optional_val { + need_closing_bracket = true; + "[=" + } else { + "=" + } + } else if is_optional_val { + need_closing_bracket = true; + " [" + } else { + " " + }; + self.none(sep)?; + } + + if arg.is_takes_value_set() || arg.is_positional() { + display_arg_val( + arg, + |s, good| if good { self.good(s) } else { self.none(s) }, + )?; + } + + if need_closing_bracket { + self.none("]")?; + } + Ok(()) + } + + /// Write alignment padding between arg's switches/values and its about message. + fn align_to_about( + &mut self, + arg: &Arg<'help>, + next_line_help: bool, + longest: usize, + ) -> io::Result<()> { + debug!( + "Help::align_to_about: arg={}, next_line_help={}, longest={}", + arg.name, next_line_help, longest + ); + if self.use_long || next_line_help { + // long help prints messages on the next line so it doesn't need to align text + debug!("Help::align_to_about: printing long help so skip alignment"); + } else if !arg.is_positional() { + let self_len = display_width(&arg.to_string()); + // Since we're writing spaces from the tab point we first need to know if we + // had a long and short, or just short + let padding = if arg.long.is_some() { + // Only account 4 after the val + 4 + } else { + // Only account for ', --' + 4 after the val + 8 + }; + let spcs = longest + padding - self_len; + debug!( + "Help::align_to_about: positional=false arg_len={}, spaces={}", + self_len, spcs + ); + + self.spaces(spcs)?; + } else { + let self_len = display_width(&arg.to_string()); + let padding = 4; + let spcs = longest + padding - self_len; + debug!( + "Help::align_to_about: positional=true arg_len={}, spaces={}", + self_len, spcs + ); + + self.spaces(spcs)?; + } + Ok(()) + } + + fn write_before_help(&mut self) -> io::Result<()> { + debug!("Help::write_before_help"); + let before_help = if self.use_long { + self.cmd + .get_before_long_help() + .or_else(|| self.cmd.get_before_help()) + } else { + self.cmd.get_before_help() + }; + if let Some(output) = before_help { + self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w))?; + self.none("\n\n")?; + } + Ok(()) + } + + fn write_after_help(&mut self) -> io::Result<()> { + debug!("Help::write_after_help"); + let after_help = if self.use_long { + self.cmd + .get_after_long_help() + .or_else(|| self.cmd.get_after_help()) + } else { + self.cmd.get_after_help() + }; + if let Some(output) = after_help { + self.none("\n\n")?; + self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w))?; + } + Ok(()) + } + + /// Writes argument's help to the wrapped stream. + fn help( + &mut self, + arg: Option<&Arg<'help>>, + about: &str, + spec_vals: &str, + next_line_help: bool, + longest: usize, + ) -> io::Result<()> { + debug!("Help::help"); + let mut help = String::from(about) + spec_vals; + debug!("Help::help: Next Line...{:?}", next_line_help); + + let spaces = if next_line_help { + 12 // "tab" * 3 + } else { + longest + 12 + }; + + let too_long = spaces + display_width(&help) >= self.term_w; + + // Is help on next line, if so then indent + if next_line_help { + self.none(format!("\n{}{}{}", TAB, TAB, TAB))?; + } + + debug!("Help::help: Too long..."); + if too_long && spaces <= self.term_w || help.contains("{n}") { + debug!("Yes"); + debug!("Help::help: help...{}", help); + debug!("Help::help: help width...{}", display_width(&help)); + // Determine how many newlines we need to insert + let avail_chars = self.term_w - spaces; + debug!("Help::help: Usable space...{}", avail_chars); + help = text_wrapper(&help.replace("{n}", "\n"), avail_chars); + } else { + debug!("No"); + } + if let Some(part) = help.lines().next() { + self.none(part)?; + } + + // indent of help + let spaces = if next_line_help { + TAB_WIDTH * 3 + } else if let Some(true) = arg.map(|a| a.is_positional()) { + longest + TAB_WIDTH * 2 + } else { + longest + TAB_WIDTH * 3 + }; + + for part in help.lines().skip(1) { + self.none("\n")?; + self.spaces(spaces)?; + self.none(part)?; + } + + #[cfg(feature = "unstable-v4")] + if let Some(arg) = arg { + const DASH_SPACE: usize = "- ".len(); + const COLON_SPACE: usize = ": ".len(); + let possible_vals = arg.get_possible_values2(); + if self.use_long + && !arg.is_hide_possible_values_set() + && possible_vals.iter().any(PossibleValue::should_show_help) + { + debug!("Help::help: Found possible vals...{:?}", possible_vals); + if !help.is_empty() { + self.none("\n\n")?; + self.spaces(spaces)?; + } + self.none("Possible values:")?; + let longest = possible_vals + .iter() + .filter_map(|f| f.get_visible_quoted_name().map(|name| display_width(&name))) + .max() + .expect("Only called with possible value"); + let help_longest = possible_vals + .iter() + .filter_map(|f| f.get_visible_help().map(display_width)) + .max() + .expect("Only called with possible value with help"); + // should new line + let taken = longest + spaces + DASH_SPACE; + + let possible_value_new_line = + self.term_w >= taken && self.term_w < taken + COLON_SPACE + help_longest; + + let spaces = spaces + TAB_WIDTH - DASH_SPACE; + let spaces_help = if possible_value_new_line { + spaces + DASH_SPACE + } else { + spaces + longest + DASH_SPACE + COLON_SPACE + }; + + for pv in possible_vals.iter().filter(|pv| !pv.is_hide_set()) { + self.none("\n")?; + self.spaces(spaces)?; + self.none("- ")?; + self.good(pv.get_name())?; + if let Some(help) = pv.get_help() { + debug!("Help::help: Possible Value help"); + + if possible_value_new_line { + self.none(":\n")?; + self.spaces(spaces_help)?; + } else { + self.none(": ")?; + // To align help messages + self.spaces(longest - display_width(pv.get_name()))?; + } + + let avail_chars = if self.term_w > spaces_help { + self.term_w - spaces_help + } else { + usize::MAX + }; + + let help = text_wrapper(help, avail_chars); + let mut help = help.lines(); + + self.none(help.next().unwrap_or_default())?; + for part in help { + self.none("\n")?; + self.spaces(spaces_help)?; + self.none(part)?; + } + } + } + } + } + Ok(()) + } + + /// Will use next line help on writing args. + fn will_args_wrap(&self, args: &[&Arg<'help>], longest: usize) -> bool { + args.iter() + .filter(|arg| should_show_arg(self.use_long, *arg)) + .any(|arg| { + let spec_vals = &self.spec_vals(arg); + self.arg_next_line_help(arg, spec_vals, longest) + }) + } + + fn arg_next_line_help(&self, arg: &Arg<'help>, spec_vals: &str, longest: usize) -> bool { + if self.next_line_help || arg.is_next_line_help_set() || self.use_long { + // setting_next_line + true + } else { + // force_next_line + let h = arg.help.unwrap_or(""); + let h_w = display_width(h) + display_width(spec_vals); + let taken = longest + 12; + self.term_w >= taken + && (taken as f32 / self.term_w as f32) > 0.40 + && h_w > (self.term_w - taken) + } + } + + fn spec_vals(&self, a: &Arg) -> String { + debug!("Help::spec_vals: a={}", a); + let mut spec_vals = vec![]; + #[cfg(feature = "env")] + if let Some(ref env) = a.env { + if !a.is_hide_env_set() { + debug!( + "Help::spec_vals: Found environment variable...[{:?}:{:?}]", + env.0, env.1 + ); + let env_val = if !a.is_hide_env_values_set() { + format!( + "={}", + env.1 + .as_ref() + .map_or(Cow::Borrowed(""), |val| val.to_string_lossy()) + ) + } else { + String::new() + }; + let env_info = format!("[env: {}{}]", env.0.to_string_lossy(), env_val); + spec_vals.push(env_info); + } + } + if a.is_takes_value_set() && !a.is_hide_default_value_set() && !a.default_vals.is_empty() { + debug!( + "Help::spec_vals: Found default value...[{:?}]", + a.default_vals + ); + + let pvs = a + .default_vals + .iter() + .map(|&pvs| pvs.to_string_lossy()) + .map(|pvs| { + if pvs.contains(char::is_whitespace) { + Cow::from(format!("{:?}", pvs)) + } else { + pvs + } + }) + .collect::>() + .join(" "); + + spec_vals.push(format!("[default: {}]", pvs)); + } + if !a.aliases.is_empty() { + debug!("Help::spec_vals: Found aliases...{:?}", a.aliases); + + let als = a + .aliases + .iter() + .filter(|&als| als.1) // visible + .map(|&als| als.0) // name + .collect::>() + .join(", "); + + if !als.is_empty() { + spec_vals.push(format!("[aliases: {}]", als)); + } + } + + if !a.short_aliases.is_empty() { + debug!( + "Help::spec_vals: Found short aliases...{:?}", + a.short_aliases + ); + + let als = a + .short_aliases + .iter() + .filter(|&als| als.1) // visible + .map(|&als| als.0.to_string()) // name + .collect::>() + .join(", "); + + if !als.is_empty() { + spec_vals.push(format!("[short aliases: {}]", als)); + } + } + + let possible_vals = a.get_possible_values2(); + if !(a.is_hide_possible_values_set() + || possible_vals.is_empty() + || cfg!(feature = "unstable-v4") + && self.use_long + && possible_vals.iter().any(PossibleValue::should_show_help)) + { + debug!("Help::spec_vals: Found possible vals...{:?}", possible_vals); + + let pvs = possible_vals + .iter() + .filter_map(PossibleValue::get_visible_quoted_name) + .collect::>() + .join(", "); + + spec_vals.push(format!("[possible values: {}]", pvs)); + } + let connector = if self.use_long { "\n" } else { " " }; + let prefix = if !spec_vals.is_empty() && !a.get_help().unwrap_or("").is_empty() { + if self.use_long { + "\n\n" + } else { + " " + } + } else { + "" + }; + prefix.to_string() + &spec_vals.join(connector) + } + + fn write_about(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> { + let about = if self.use_long { + self.cmd.get_long_about().or_else(|| self.cmd.get_about()) + } else { + self.cmd.get_about() + }; + if let Some(output) = about { + if before_new_line { + self.none("\n")?; + } + self.none(text_wrapper(output, self.term_w))?; + if after_new_line { + self.none("\n")?; + } + } + Ok(()) + } + + fn write_author(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> { + if let Some(author) = self.cmd.get_author() { + if before_new_line { + self.none("\n")?; + } + self.none(text_wrapper(author, self.term_w))?; + if after_new_line { + self.none("\n")?; + } + } + Ok(()) + } + + fn write_version(&mut self) -> io::Result<()> { + let version = self + .cmd + .get_version() + .or_else(|| self.cmd.get_long_version()); + if let Some(output) = version { + self.none(text_wrapper(output, self.term_w))?; + } + Ok(()) + } +} + +/// Methods to write a single subcommand +impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { + fn write_subcommand( + &mut self, + sc_str: &str, + cmd: &Command<'help>, + next_line_help: bool, + longest: usize, + ) -> io::Result<()> { + debug!("Help::write_subcommand"); + + let spec_vals = &self.sc_spec_vals(cmd); + + let about = cmd + .get_about() + .or_else(|| cmd.get_long_about()) + .unwrap_or(""); + + self.subcmd(sc_str, next_line_help, longest)?; + self.help(None, about, spec_vals, next_line_help, longest) + } + + fn sc_spec_vals(&self, a: &Command) -> String { + debug!("Help::sc_spec_vals: a={}", a.get_name()); + let mut spec_vals = vec![]; + if 0 < a.get_all_aliases().count() || 0 < a.get_all_short_flag_aliases().count() { + debug!( + "Help::spec_vals: Found aliases...{:?}", + a.get_all_aliases().collect::>() + ); + debug!( + "Help::spec_vals: Found short flag aliases...{:?}", + a.get_all_short_flag_aliases().collect::>() + ); + + let mut short_als = a + .get_visible_short_flag_aliases() + .map(|a| format!("-{}", a)) + .collect::>(); + + let als = a.get_visible_aliases().map(|s| s.to_string()); + + short_als.extend(als); + + let all_als = short_als.join(", "); + + if !all_als.is_empty() { + spec_vals.push(format!(" [aliases: {}]", all_als)); + } + } + spec_vals.join(" ") + } + + fn subcommand_next_line_help( + &self, + cmd: &Command<'help>, + spec_vals: &str, + longest: usize, + ) -> bool { + if self.next_line_help | self.use_long { + // setting_next_line + true + } else { + // force_next_line + let h = cmd.get_about().unwrap_or(""); + let h_w = display_width(h) + display_width(spec_vals); + let taken = longest + 12; + self.term_w >= taken + && (taken as f32 / self.term_w as f32) > 0.40 + && h_w > (self.term_w - taken) + } + } + + /// Writes subcommand to the wrapped stream. + fn subcmd(&mut self, sc_str: &str, next_line_help: bool, longest: usize) -> io::Result<()> { + self.none(TAB)?; + self.good(sc_str)?; + if !next_line_help { + let width = display_width(sc_str); + self.spaces(width.max(longest + 4) - width)?; + } + Ok(()) + } +} + +// Methods to write Parser help. +impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { + /// Writes help for all arguments (options, flags, args, subcommands) + /// including titles of a Parser Object to the wrapped stream. + pub(crate) fn write_all_args(&mut self) -> io::Result<()> { + debug!("Help::write_all_args"); + let pos = self + .cmd + .get_positionals_with_no_heading() + .filter(|arg| should_show_arg(self.use_long, arg)) + .collect::>(); + let non_pos = self + .cmd + .get_non_positionals_with_no_heading() + .filter(|arg| should_show_arg(self.use_long, arg)) + .collect::>(); + let subcmds = self.cmd.has_visible_subcommands(); + + let custom_headings = self + .cmd + .get_arguments() + .filter_map(|arg| arg.get_help_heading()) + .collect::>(); + + let mut first = if !pos.is_empty() { + // Write positional args if any + self.warning("ARGS:\n")?; + self.write_args_unsorted(&pos)?; + false + } else { + true + }; + + if !non_pos.is_empty() { + if !first { + self.none("\n\n")?; + } + self.warning("OPTIONS:\n")?; + self.write_args(&non_pos, "OPTIONS")?; + first = false; + } + if !custom_headings.is_empty() { + for heading in custom_headings { + let args = self + .cmd + .get_arguments() + .filter(|a| { + if let Some(help_heading) = a.get_help_heading() { + return help_heading == heading; + } + false + }) + .filter(|arg| should_show_arg(self.use_long, arg)) + .collect::>(); + + if !args.is_empty() { + if !first { + self.none("\n\n")?; + } + self.warning(format!("{}:\n", heading))?; + self.write_args(&args, heading)?; + first = false + } + } + } + + if subcmds { + if !first { + self.none("\n\n")?; + } + + self.warning( + self.cmd + .get_subcommand_help_heading() + .unwrap_or("SUBCOMMANDS"), + )?; + self.warning(":\n")?; + + self.write_subcommands(self.cmd)?; + } + + Ok(()) + } + + /// Will use next line help on writing subcommands. + fn will_subcommands_wrap<'a>( + &self, + subcommands: impl IntoIterator>, + longest: usize, + ) -> bool + where + 'help: 'a, + { + subcommands + .into_iter() + .filter(|&subcommand| should_show_subcommand(subcommand)) + .any(|subcommand| { + let spec_vals = &self.sc_spec_vals(subcommand); + self.subcommand_next_line_help(subcommand, spec_vals, longest) + }) + } + + /// Writes help for subcommands of a Parser Object to the wrapped stream. + fn write_subcommands(&mut self, cmd: &Command<'help>) -> io::Result<()> { + debug!("Help::write_subcommands"); + // The shortest an arg can legally be is 2 (i.e. '-x') + let mut longest = 2; + let mut ord_v = Vec::new(); + for subcommand in cmd + .get_subcommands() + .filter(|subcommand| should_show_subcommand(subcommand)) + { + let mut sc_str = String::new(); + sc_str.push_str(subcommand.get_name()); + if let Some(short) = subcommand.get_short_flag() { + write!(sc_str, " -{}", short).unwrap(); + } + if let Some(long) = subcommand.get_long_flag() { + write!(sc_str, " --{}", long).unwrap(); + } + longest = longest.max(display_width(&sc_str)); + ord_v.push((subcommand.get_display_order(), sc_str, subcommand)); + } + ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1))); + + debug!("Help::write_subcommands longest = {}", longest); + + let next_line_help = self.will_subcommands_wrap(cmd.get_subcommands(), longest); + + let mut first = true; + for (_, sc_str, sc) in &ord_v { + if first { + first = false; + } else { + self.none("\n")?; + } + self.write_subcommand(sc_str, sc, next_line_help, longest)?; + } + Ok(()) + } + + /// Writes binary name of a Parser Object to the wrapped stream. + fn write_display_name(&mut self) -> io::Result<()> { + debug!("Help::write_display_name"); + + let display_name = text_wrapper( + &self + .cmd + .get_display_name() + .unwrap_or_else(|| self.cmd.get_name()) + .replace("{n}", "\n"), + self.term_w, + ); + self.good(&display_name)?; + Ok(()) + } + + /// Writes binary name of a Parser Object to the wrapped stream. + fn write_bin_name(&mut self) -> io::Result<()> { + debug!("Help::write_bin_name"); + + let bin_name = if let Some(bn) = self.cmd.get_bin_name() { + if bn.contains(' ') { + // In case we're dealing with subcommands i.e. git mv is translated to git-mv + bn.replace(' ', "-") + } else { + text_wrapper(&self.cmd.get_name().replace("{n}", "\n"), self.term_w) + } + } else { + text_wrapper(&self.cmd.get_name().replace("{n}", "\n"), self.term_w) + }; + self.good(&bin_name)?; + Ok(()) + } +} + +// Methods to write Parser help using templates. +impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { + /// Write help to stream for the parser in the format defined by the template. + /// + /// For details about the template language see [`Command::help_template`]. + /// + /// [`Command::help_template`]: Command::help_template() + fn write_templated_help(&mut self, template: &str) -> io::Result<()> { + debug!("Help::write_templated_help"); + + // The strategy is to copy the template from the reader to wrapped stream + // until a tag is found. Depending on its value, the appropriate content is copied + // to the wrapped stream. + // The copy from template is then resumed, repeating this sequence until reading + // the complete template. + + macro_rules! tags { + ( + match $part:ident { + $( $tag:expr => $action:stmt )* + } + ) => { + match $part { + $( + part if part.starts_with(concat!($tag, "}")) => { + $action + let rest = &part[$tag.len()+1..]; + self.none(rest)?; + } + )* + + // Unknown tag, write it back. + part => { + self.none("{")?; + self.none(part)?; + } + } + }; + } + + let mut parts = template.split('{'); + if let Some(first) = parts.next() { + self.none(first)?; + } + + for part in parts { + tags! { + match part { + "name" => { + self.write_display_name()?; + } + "bin" => { + self.write_bin_name()?; + } + "version" => { + self.write_version()?; + } + "author" => { + self.write_author(false, false)?; + } + "author-with-newline" => { + self.write_author(false, true)?; + } + "author-section" => { + self.write_author(true, true)?; + } + "about" => { + self.write_about(false, false)?; + } + "about-with-newline" => { + self.write_about(false, true)?; + } + "about-section" => { + self.write_about(true, true)?; + } + "usage-heading" => { + self.warning("USAGE:")?; + } + "usage" => { + self.none(self.usage.create_usage_no_title(&[]))?; + } + "all-args" => { + self.write_all_args()?; + } + "options" => { + // Include even those with a heading as we don't have a good way of + // handling help_heading in the template. + self.write_args(&self.cmd.get_non_positionals().collect::>(), "options")?; + } + "positionals" => { + self.write_args(&self.cmd.get_positionals().collect::>(), "positionals")?; + } + "subcommands" => { + self.write_subcommands(self.cmd)?; + } + "after-help" => { + self.write_after_help()?; + } + "before-help" => { + self.write_before_help()?; + } + } + } + } + + Ok(()) + } +} + +pub(crate) fn dimensions() -> Option<(usize, usize)> { + #[cfg(not(feature = "wrap_help"))] + return None; + + #[cfg(feature = "wrap_help")] + terminal_size::terminal_size().map(|(w, h)| (w.0.into(), h.0.into())) +} + +const TAB: &str = " "; +const TAB_WIDTH: usize = 4; + +pub(crate) enum HelpWriter<'writer> { + Normal(&'writer mut dyn Write), + Buffer(&'writer mut Colorizer), +} + +fn should_show_arg(use_long: bool, arg: &Arg) -> bool { + debug!("should_show_arg: use_long={:?}, arg={}", use_long, arg.name); + if arg.is_hide_set() { + return false; + } + (!arg.is_hide_long_help_set() && use_long) + || (!arg.is_hide_short_help_set() && !use_long) + || arg.is_next_line_help_set() +} + +fn should_show_subcommand(subcommand: &Command) -> bool { + !subcommand.is_hide_set() +} + +fn text_wrapper(help: &str, width: usize) -> String { + let wrapper = textwrap::Options::new(width) + .break_words(false) + .word_splitter(textwrap::WordSplitter::NoHyphenation); + help.lines() + .map(|line| textwrap::fill(line, &wrapper)) + .collect::>() + .join("\n") +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn wrap_help_last_word() { + let help = String::from("foo bar baz"); + assert_eq!(text_wrapper(&help, 5), "foo\nbar\nbaz"); + } + + #[test] + fn display_width_handles_non_ascii() { + // Popular Danish tongue-twister, the name of a fruit dessert. + let text = "rødgrød med fløde"; + assert_eq!(display_width(text), 17); + // Note that the string width is smaller than the string + // length. This is due to the precomposed non-ASCII letters: + assert_eq!(text.len(), 20); + } + + #[test] + fn display_width_handles_emojis() { + let text = "😂"; + // There is a single `char`... + assert_eq!(text.chars().count(), 1); + // but it is double-width: + assert_eq!(display_width(text), 2); + // This is much less than the byte length: + assert_eq!(text.len(), 4); + } +} diff --git a/vendor/clap-3.2.20/src/output/mod.rs b/vendor/clap-3.2.20/src/output/mod.rs new file mode 100644 index 000000000..e32aac26a --- /dev/null +++ b/vendor/clap-3.2.20/src/output/mod.rs @@ -0,0 +1,7 @@ +mod help; +mod usage; + +pub(crate) mod fmt; + +pub(crate) use self::help::{Help, HelpWriter}; +pub(crate) use self::usage::Usage; diff --git a/vendor/clap-3.2.20/src/output/usage.rs b/vendor/clap-3.2.20/src/output/usage.rs new file mode 100644 index 000000000..6f7a2cad4 --- /dev/null +++ b/vendor/clap-3.2.20/src/output/usage.rs @@ -0,0 +1,449 @@ +use indexmap::IndexSet; + +// Internal +use crate::builder::AppSettings as AS; +use crate::builder::{Arg, ArgPredicate, Command}; +use crate::parser::ArgMatcher; +use crate::util::ChildGraph; +use crate::util::Id; +use crate::INTERNAL_ERROR_MSG; + +pub(crate) struct Usage<'help, 'cmd> { + cmd: &'cmd Command<'help>, + required: Option<&'cmd ChildGraph>, +} + +impl<'help, 'cmd> Usage<'help, 'cmd> { + pub(crate) fn new(cmd: &'cmd Command<'help>) -> Self { + Usage { + cmd, + required: None, + } + } + + pub(crate) fn required(mut self, required: &'cmd ChildGraph) -> Self { + self.required = Some(required); + self + } + + // Creates a usage string for display. This happens just after all arguments were parsed, but before + // any subcommands have been parsed (so as to give subcommands their own usage recursively) + pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> String { + debug!("Usage::create_usage_with_title"); + let mut usage = String::with_capacity(75); + usage.push_str("USAGE:\n "); + usage.push_str(&*self.create_usage_no_title(used)); + usage + } + + // Creates a usage string (*without title*) if one was not provided by the user manually. + pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String { + debug!("Usage::create_usage_no_title"); + if let Some(u) = self.cmd.get_override_usage() { + String::from(&*u) + } else if used.is_empty() { + self.create_help_usage(true) + } else { + self.create_smart_usage(used) + } + } + + // Creates a usage string for display in help messages (i.e. not for errors) + fn create_help_usage(&self, incl_reqs: bool) -> String { + debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs); + let mut usage = String::with_capacity(75); + let name = self + .cmd + .get_usage_name() + .or_else(|| self.cmd.get_bin_name()) + .unwrap_or_else(|| self.cmd.get_name()); + usage.push_str(name); + let req_string = if incl_reqs { + self.get_required_usage_from(&[], None, false) + .iter() + .fold(String::new(), |a, s| a + " " + s) + } else { + String::new() + }; + + if self.needs_options_tag() { + usage.push_str(" [OPTIONS]"); + } + + let allow_missing_positional = self.cmd.is_allow_missing_positional_set(); + if !allow_missing_positional { + usage.push_str(&req_string); + } + + let has_last = self.cmd.get_positionals().any(|p| p.is_last_set()); + // places a '--' in the usage string if there are args and options + // supporting multiple values + if self + .cmd + .get_non_positionals() + .any(|o| o.is_multiple_values_set()) + && self.cmd.get_positionals().any(|p| !p.is_required_set()) + && !(self.cmd.has_visible_subcommands() || self.cmd.is_allow_external_subcommands_set()) + && !has_last + { + usage.push_str(" [--]"); + } + let not_req_or_hidden = + |p: &Arg| (!p.is_required_set() || p.is_last_set()) && !p.is_hide_set(); + if self.cmd.get_positionals().any(not_req_or_hidden) { + if let Some(args_tag) = self.get_args_tag(incl_reqs) { + usage.push_str(&*args_tag); + } else { + usage.push_str(" [ARGS]"); + } + if has_last && incl_reqs { + let pos = self + .cmd + .get_positionals() + .find(|p| p.is_last_set()) + .expect(INTERNAL_ERROR_MSG); + debug!("Usage::create_help_usage: '{}' has .last(true)", pos.name); + let req = pos.is_required_set(); + if req && self.cmd.get_positionals().any(|p| !p.is_required_set()) { + usage.push_str(" -- <"); + } else if req { + usage.push_str(" [--] <"); + } else { + usage.push_str(" [-- <"); + } + usage.push_str(&*pos.name_no_brackets()); + usage.push('>'); + usage.push_str(pos.multiple_str()); + if !req { + usage.push(']'); + } + } + } + + if allow_missing_positional { + usage.push_str(&req_string); + } + + // incl_reqs is only false when this function is called recursively + if self.cmd.has_visible_subcommands() && incl_reqs + || self.cmd.is_allow_external_subcommands_set() + { + let placeholder = self.cmd.get_subcommand_value_name().unwrap_or("SUBCOMMAND"); + #[allow(deprecated)] + if self.cmd.is_subcommand_negates_reqs_set() + || self.cmd.is_args_conflicts_with_subcommands_set() + { + usage.push_str("\n "); + if !self.cmd.is_args_conflicts_with_subcommands_set() { + usage.push_str(&*self.create_help_usage(false)); + } else { + usage.push_str(&*name); + } + usage.push_str(" <"); + usage.push_str(placeholder); + usage.push('>'); + } else if self.cmd.is_subcommand_required_set() + || self.cmd.is_set(AS::SubcommandRequiredElseHelp) + { + usage.push_str(" <"); + usage.push_str(placeholder); + usage.push('>'); + } else { + usage.push_str(" ["); + usage.push_str(placeholder); + usage.push(']'); + } + } + let usage = usage.trim().to_owned(); + debug!("Usage::create_help_usage: usage={}", usage); + usage + } + + // Creates a context aware usage string, or "smart usage" from currently used + // args, and requirements + fn create_smart_usage(&self, used: &[Id]) -> String { + debug!("Usage::create_smart_usage"); + let mut usage = String::with_capacity(75); + + let r_string = self + .get_required_usage_from(used, None, true) + .iter() + .fold(String::new(), |acc, s| acc + " " + s); + + usage.push_str( + self.cmd + .get_usage_name() + .or_else(|| self.cmd.get_bin_name()) + .unwrap_or_else(|| self.cmd.get_name()), + ); + usage.push_str(&*r_string); + if self.cmd.is_subcommand_required_set() { + usage.push_str(" <"); + usage.push_str(self.cmd.get_subcommand_value_name().unwrap_or("SUBCOMMAND")); + usage.push('>'); + } + usage.shrink_to_fit(); + usage + } + + // Gets the `[ARGS]` tag for the usage string + fn get_args_tag(&self, incl_reqs: bool) -> Option { + debug!("Usage::get_args_tag; incl_reqs = {:?}", incl_reqs); + let mut count = 0; + for pos in self + .cmd + .get_positionals() + .filter(|pos| !pos.is_required_set()) + .filter(|pos| !pos.is_hide_set()) + .filter(|pos| !pos.is_last_set()) + { + debug!("Usage::get_args_tag:iter:{}", pos.name); + let required = self.cmd.groups_for_arg(&pos.id).any(|grp_s| { + debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s); + // if it's part of a required group we don't want to count it + self.cmd.get_groups().any(|g| g.required && (g.id == grp_s)) + }); + if !required { + count += 1; + debug!( + "Usage::get_args_tag:iter: {} Args not required or hidden", + count + ); + } + } + + if !self.cmd.is_dont_collapse_args_in_usage_set() && count > 1 { + debug!("Usage::get_args_tag:iter: More than one, returning [ARGS]"); + + // [ARGS] + None + } else if count == 1 && incl_reqs { + let pos = self + .cmd + .get_positionals() + .find(|pos| { + !pos.is_required_set() + && !pos.is_hide_set() + && !pos.is_last_set() + && !self.cmd.groups_for_arg(&pos.id).any(|grp_s| { + debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s); + // if it's part of a required group we don't want to count it + self.cmd.get_groups().any(|g| g.required && (g.id == grp_s)) + }) + }) + .expect(INTERNAL_ERROR_MSG); + + debug!( + "Usage::get_args_tag:iter: Exactly one, returning '{}'", + pos.name + ); + + Some(format!( + " [{}]{}", + pos.name_no_brackets(), + pos.multiple_str() + )) + } else if self.cmd.is_dont_collapse_args_in_usage_set() + && self.cmd.has_positionals() + && incl_reqs + { + debug!("Usage::get_args_tag:iter: Don't collapse returning all"); + Some( + self.cmd + .get_positionals() + .filter(|pos| !pos.is_required_set()) + .filter(|pos| !pos.is_hide_set()) + .filter(|pos| !pos.is_last_set()) + .map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())) + .collect::>() + .join(""), + ) + } else if !incl_reqs { + debug!("Usage::get_args_tag:iter: incl_reqs=false, building secondary usage string"); + let highest_req_pos = self + .cmd + .get_positionals() + .filter_map(|pos| { + if pos.is_required_set() && !pos.is_last_set() { + Some(pos.index) + } else { + None + } + }) + .max() + .unwrap_or_else(|| Some(self.cmd.get_positionals().count())); + Some( + self.cmd + .get_positionals() + .filter(|pos| pos.index <= highest_req_pos) + .filter(|pos| !pos.is_required_set()) + .filter(|pos| !pos.is_hide_set()) + .filter(|pos| !pos.is_last_set()) + .map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())) + .collect::>() + .join(""), + ) + } else { + Some("".into()) + } + } + + // Determines if we need the `[OPTIONS]` tag in the usage string + fn needs_options_tag(&self) -> bool { + debug!("Usage::needs_options_tag"); + 'outer: for f in self.cmd.get_non_positionals() { + debug!("Usage::needs_options_tag:iter: f={}", f.name); + + // Don't print `[OPTIONS]` just for help or version + if f.long == Some("help") || f.long == Some("version") { + debug!("Usage::needs_options_tag:iter Option is built-in"); + continue; + } + + if f.is_hide_set() { + debug!("Usage::needs_options_tag:iter Option is hidden"); + continue; + } + if f.is_required_set() { + debug!("Usage::needs_options_tag:iter Option is required"); + continue; + } + for grp_s in self.cmd.groups_for_arg(&f.id) { + debug!("Usage::needs_options_tag:iter:iter: grp_s={:?}", grp_s); + if self.cmd.get_groups().any(|g| g.id == grp_s && g.required) { + debug!("Usage::needs_options_tag:iter:iter: Group is required"); + continue 'outer; + } + } + + debug!("Usage::needs_options_tag:iter: [OPTIONS] required"); + return true; + } + + debug!("Usage::needs_options_tag: [OPTIONS] not required"); + false + } + + // Returns the required args in usage string form by fully unrolling all groups + // `incl_last`: should we include args that are Arg::Last? (i.e. `prog [foo] -- [last]). We + // can't do that for required usages being built for subcommands because it would look like: + // `prog [foo] -- [last] ` which is totally wrong. + pub(crate) fn get_required_usage_from( + &self, + incls: &[Id], + matcher: Option<&ArgMatcher>, + incl_last: bool, + ) -> IndexSet { + debug!( + "Usage::get_required_usage_from: incls={:?}, matcher={:?}, incl_last={:?}", + incls, + matcher.is_some(), + incl_last + ); + let mut ret_val = IndexSet::new(); + + let mut unrolled_reqs = IndexSet::new(); + + let required_owned; + let required = if let Some(required) = self.required { + required + } else { + required_owned = self.cmd.required_graph(); + &required_owned + }; + + for a in required.iter() { + let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option { + let required = match val { + ArgPredicate::Equals(_) => { + if let Some(matcher) = matcher { + matcher.check_explicit(a, *val) + } else { + false + } + } + ArgPredicate::IsPresent => true, + }; + required.then(|| req_arg.clone()) + }; + + for aa in self.cmd.unroll_arg_requires(is_relevant, a) { + // if we don't check for duplicates here this causes duplicate error messages + // see https://github.com/clap-rs/clap/issues/2770 + unrolled_reqs.insert(aa); + } + // always include the required arg itself. it will not be enumerated + // by unroll_requirements_for_arg. + unrolled_reqs.insert(a.clone()); + } + + debug!( + "Usage::get_required_usage_from: unrolled_reqs={:?}", + unrolled_reqs + ); + + let mut required_groups_members = IndexSet::new(); + let mut required_opts = IndexSet::new(); + let mut required_groups = IndexSet::new(); + let mut required_positionals = Vec::new(); + for req in unrolled_reqs.iter().chain(incls.iter()) { + if let Some(arg) = self.cmd.find(req) { + let is_present = matcher + .map(|m| m.check_explicit(req, ArgPredicate::IsPresent)) + .unwrap_or(false); + debug!( + "Usage::get_required_usage_from:iter:{:?} arg is_present={}", + req, is_present + ); + if !is_present { + if arg.is_positional() { + if incl_last || !arg.is_last_set() { + required_positionals.push((arg.index.unwrap(), arg.to_string())); + } + } else { + required_opts.insert(arg.to_string()); + } + } + } else { + debug_assert!(self.cmd.find_group(req).is_some()); + let group_members = self.cmd.unroll_args_in_group(req); + let is_present = matcher + .map(|m| { + group_members + .iter() + .any(|arg| m.check_explicit(arg, ArgPredicate::IsPresent)) + }) + .unwrap_or(false); + debug!( + "Usage::get_required_usage_from:iter:{:?} group is_present={}", + req, is_present + ); + if !is_present { + let elem = self.cmd.format_group(req); + required_groups.insert(elem); + required_groups_members.extend( + group_members + .iter() + .flat_map(|id| self.cmd.find(id)) + .map(|arg| arg.to_string()), + ); + } + } + } + + required_opts.retain(|arg| !required_groups_members.contains(arg)); + ret_val.extend(required_opts); + + ret_val.extend(required_groups); + + required_positionals.sort_by_key(|(ind, _)| *ind); // sort by index + for (_, p) in required_positionals { + if !required_groups_members.contains(&p) { + ret_val.insert(p); + } + } + + debug!("Usage::get_required_usage_from: ret_val={:?}", ret_val); + ret_val + } +} diff --git a/vendor/clap-3.2.20/src/parser/arg_matcher.rs b/vendor/clap-3.2.20/src/parser/arg_matcher.rs new file mode 100644 index 000000000..22087e722 --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/arg_matcher.rs @@ -0,0 +1,280 @@ +// Std +use std::collections::HashMap; +use std::ffi::OsString; +use std::mem; +use std::ops::Deref; + +// Internal +use crate::builder::{Arg, ArgPredicate, Command}; +use crate::parser::AnyValue; +use crate::parser::Identifier; +use crate::parser::PendingArg; +use crate::parser::{ArgMatches, MatchedArg, SubCommand, ValueSource}; +use crate::util::Id; +use crate::INTERNAL_ERROR_MSG; + +#[derive(Debug, Default)] +pub(crate) struct ArgMatcher { + matches: ArgMatches, + pending: Option, +} + +impl ArgMatcher { + pub(crate) fn new(_cmd: &Command) -> Self { + ArgMatcher { + matches: ArgMatches { + #[cfg(debug_assertions)] + valid_args: { + let args = _cmd.get_arguments().map(|a| a.id.clone()); + let groups = _cmd.get_groups().map(|g| g.id.clone()); + args.chain(groups).collect() + }, + #[cfg(debug_assertions)] + valid_subcommands: _cmd.get_subcommands().map(|sc| sc.get_id()).collect(), + // HACK: Allow an external subcommand's ArgMatches be a stand-in for any ArgMatches + // since users can't detect it and avoid the asserts. + // + // See clap-rs/clap#3263 + #[cfg(debug_assertions)] + #[cfg(not(feature = "unstable-v4"))] + disable_asserts: _cmd.is_allow_external_subcommands_set(), + #[cfg(debug_assertions)] + #[cfg(feature = "unstable-v4")] + disable_asserts: false, + ..Default::default() + }, + pending: None, + } + } + + pub(crate) fn into_inner(self) -> ArgMatches { + self.matches + } + + pub(crate) fn propagate_globals(&mut self, global_arg_vec: &[Id]) { + debug!( + "ArgMatcher::get_global_values: global_arg_vec={:?}", + global_arg_vec + ); + let mut vals_map = HashMap::new(); + self.fill_in_global_values(global_arg_vec, &mut vals_map); + } + + fn fill_in_global_values( + &mut self, + global_arg_vec: &[Id], + vals_map: &mut HashMap, + ) { + for global_arg in global_arg_vec { + if let Some(ma) = self.get(global_arg) { + // We have to check if the parent's global arg wasn't used but still exists + // such as from a default value. + // + // For example, `myprog subcommand --global-arg=value` where `--global-arg` defines + // a default value of `other` myprog would have an existing MatchedArg for + // `--global-arg` where the value is `other` + let to_update = if let Some(parent_ma) = vals_map.get(global_arg) { + if parent_ma.source() > ma.source() { + parent_ma + } else { + ma + } + } else { + ma + } + .clone(); + vals_map.insert(global_arg.clone(), to_update); + } + } + if let Some(ref mut sc) = self.matches.subcommand { + let mut am = ArgMatcher { + matches: mem::take(&mut sc.matches), + pending: None, + }; + am.fill_in_global_values(global_arg_vec, vals_map); + mem::swap(&mut am.matches, &mut sc.matches); + } + + for (name, matched_arg) in vals_map.iter_mut() { + self.matches.args.insert(name.clone(), matched_arg.clone()); + } + } + + pub(crate) fn get(&self, arg: &Id) -> Option<&MatchedArg> { + self.matches.args.get(arg) + } + + pub(crate) fn get_mut(&mut self, arg: &Id) -> Option<&mut MatchedArg> { + self.matches.args.get_mut(arg) + } + + pub(crate) fn remove(&mut self, arg: &Id) { + self.matches.args.swap_remove(arg); + } + + pub(crate) fn contains(&self, arg: &Id) -> bool { + self.matches.args.contains_key(arg) + } + + pub(crate) fn arg_ids(&self) -> indexmap::map::Keys { + self.matches.args.keys() + } + + pub(crate) fn entry(&mut self, arg: &Id) -> indexmap::map::Entry { + self.matches.args.entry(arg.clone()) + } + + pub(crate) fn subcommand(&mut self, sc: SubCommand) { + self.matches.subcommand = Some(Box::new(sc)); + } + + pub(crate) fn subcommand_name(&self) -> Option<&str> { + self.matches.subcommand_name() + } + + pub(crate) fn iter(&self) -> indexmap::map::Iter { + self.matches.args.iter() + } + + pub(crate) fn check_explicit<'a>(&self, arg: &Id, predicate: ArgPredicate<'a>) -> bool { + self.get(arg).map_or(false, |a| a.check_explicit(predicate)) + } + + pub(crate) fn start_custom_arg(&mut self, arg: &Arg, source: ValueSource) { + let id = &arg.id; + debug!( + "ArgMatcher::start_custom_arg: id={:?}, source={:?}", + id, source + ); + let ma = self.entry(id).or_insert(MatchedArg::new_arg(arg)); + debug_assert_eq!(ma.type_id(), Some(arg.get_value_parser().type_id())); + ma.set_source(source); + ma.new_val_group(); + } + + pub(crate) fn start_custom_group(&mut self, id: &Id, source: ValueSource) { + debug!( + "ArgMatcher::start_custom_arg: id={:?}, source={:?}", + id, source + ); + let ma = self.entry(id).or_insert(MatchedArg::new_group()); + debug_assert_eq!(ma.type_id(), None); + ma.set_source(source); + ma.new_val_group(); + } + + pub(crate) fn start_occurrence_of_arg(&mut self, arg: &Arg) { + let id = &arg.id; + debug!("ArgMatcher::start_occurrence_of_arg: id={:?}", id); + let ma = self.entry(id).or_insert(MatchedArg::new_arg(arg)); + debug_assert_eq!(ma.type_id(), Some(arg.get_value_parser().type_id())); + ma.set_source(ValueSource::CommandLine); + #[allow(deprecated)] + ma.inc_occurrences(); + ma.new_val_group(); + } + + pub(crate) fn start_occurrence_of_group(&mut self, id: &Id) { + debug!("ArgMatcher::start_occurrence_of_group: id={:?}", id); + let ma = self.entry(id).or_insert(MatchedArg::new_group()); + debug_assert_eq!(ma.type_id(), None); + ma.set_source(ValueSource::CommandLine); + #[allow(deprecated)] + ma.inc_occurrences(); + ma.new_val_group(); + } + + pub(crate) fn start_occurrence_of_external(&mut self, cmd: &crate::Command) { + let id = &Id::empty_hash(); + debug!("ArgMatcher::start_occurrence_of_external: id={:?}", id,); + let ma = self.entry(id).or_insert(MatchedArg::new_external(cmd)); + debug_assert_eq!( + ma.type_id(), + Some( + cmd.get_external_subcommand_value_parser() + .expect(INTERNAL_ERROR_MSG) + .type_id() + ) + ); + ma.set_source(ValueSource::CommandLine); + #[allow(deprecated)] + ma.inc_occurrences(); + ma.new_val_group(); + } + + pub(crate) fn add_val_to(&mut self, arg: &Id, val: AnyValue, raw_val: OsString) { + let ma = self.get_mut(arg).expect(INTERNAL_ERROR_MSG); + ma.append_val(val, raw_val); + } + + pub(crate) fn add_index_to(&mut self, arg: &Id, idx: usize) { + let ma = self.get_mut(arg).expect(INTERNAL_ERROR_MSG); + ma.push_index(idx); + } + + pub(crate) fn needs_more_vals(&self, o: &Arg) -> bool { + let num_resolved = self.get(&o.id).map(|ma| ma.num_vals()).unwrap_or(0); + let num_pending = self + .pending + .as_ref() + .and_then(|p| (p.id == o.id).then(|| p.raw_vals.len())) + .unwrap_or(0); + let current_num = num_resolved + num_pending; + debug!( + "ArgMatcher::needs_more_vals: o={}, resolved={}, pending={}", + o.name, num_resolved, num_pending + ); + if current_num == 0 { + true + } else if let Some(num) = o.num_vals { + debug!("ArgMatcher::needs_more_vals: num_vals...{}", num); + #[allow(deprecated)] + if o.is_multiple_occurrences_set() { + (current_num % num) != 0 + } else { + num != current_num + } + } else if let Some(num) = o.max_vals { + debug!("ArgMatcher::needs_more_vals: max_vals...{}", num); + current_num < num + } else if o.min_vals.is_some() { + debug!("ArgMatcher::needs_more_vals: min_vals...true"); + true + } else { + o.is_multiple_values_set() + } + } + + pub(crate) fn pending_arg_id(&self) -> Option<&Id> { + self.pending.as_ref().map(|p| &p.id) + } + + pub(crate) fn pending_values_mut( + &mut self, + id: &Id, + ident: Option, + ) -> &mut Vec { + let pending = self.pending.get_or_insert_with(|| PendingArg { + id: id.clone(), + ident, + raw_vals: Default::default(), + }); + debug_assert_eq!(pending.id, *id, "{}", INTERNAL_ERROR_MSG); + if ident.is_some() { + debug_assert_eq!(pending.ident, ident, "{}", INTERNAL_ERROR_MSG); + } + &mut pending.raw_vals + } + + pub(crate) fn take_pending(&mut self) -> Option { + self.pending.take() + } +} + +impl Deref for ArgMatcher { + type Target = ArgMatches; + + fn deref(&self) -> &Self::Target { + &self.matches + } +} diff --git a/vendor/clap-3.2.20/src/parser/error.rs b/vendor/clap-3.2.20/src/parser/error.rs new file mode 100644 index 000000000..caeba4b8f --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/error.rs @@ -0,0 +1,67 @@ +use crate::util::Id; + +/// Violation of [`ArgMatches`][crate::ArgMatches] assumptions +#[derive(Clone, Debug)] +#[allow(missing_copy_implementations)] // We might add non-Copy types in the future +#[non_exhaustive] +pub enum MatchesError { + /// Failed to downcast `AnyValue` to the specified type + #[non_exhaustive] + Downcast { + /// Type for value stored in [`ArgMatches`][crate::ArgMatches] + actual: super::AnyValueId, + /// The target type to downcast to + expected: super::AnyValueId, + }, + /// Argument not defined in [`Command`][crate::Command] + #[non_exhaustive] + UnknownArgument { + // Missing `id` but blocked on a public id type which will hopefully come with `unstable-v4` + }, +} + +impl MatchesError { + #[track_caller] + pub(crate) fn unwrap(id: &Id, r: Result) -> T { + let err = match r { + Ok(t) => { + return t; + } + Err(err) => err, + }; + panic!( + "Mismatch between definition and access of `{:?}`. {}", + id, err + ) + } +} + +impl std::error::Error for MatchesError {} + +impl std::fmt::Display for MatchesError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Downcast { actual, expected } => { + writeln!( + f, + "Could not downcast to {:?}, need to downcast to {:?}", + expected, actual + ) + } + Self::UnknownArgument {} => { + writeln!(f, "Unknown argument or group id. Make sure you are using the argument id and not the short or long flags") + } + } + } +} + +#[test] +fn check_auto_traits() { + static_assertions::assert_impl_all!( + MatchesError: Send, + Sync, + std::panic::RefUnwindSafe, + std::panic::UnwindSafe, + Unpin + ); +} diff --git a/vendor/clap-3.2.20/src/parser/features/mod.rs b/vendor/clap-3.2.20/src/parser/features/mod.rs new file mode 100644 index 000000000..bdeb766ec --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/features/mod.rs @@ -0,0 +1 @@ +pub(crate) mod suggestions; diff --git a/vendor/clap-3.2.20/src/parser/features/suggestions.rs b/vendor/clap-3.2.20/src/parser/features/suggestions.rs new file mode 100644 index 000000000..9e46f3c9e --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/features/suggestions.rs @@ -0,0 +1,105 @@ +#[cfg(feature = "suggestions")] +use std::cmp::Ordering; + +// Internal +use crate::builder::Command; + +/// Produces multiple strings from a given list of possible values which are similar +/// to the passed in value `v` within a certain confidence by least confidence. +/// Thus in a list of possible values like ["foo", "bar"], the value "fop" will yield +/// `Some("foo")`, whereas "blark" would yield `None`. +#[cfg(feature = "suggestions")] +pub(crate) fn did_you_mean(v: &str, possible_values: I) -> Vec +where + T: AsRef, + I: IntoIterator, +{ + let mut candidates: Vec<(f64, String)> = possible_values + .into_iter() + .map(|pv| (strsim::jaro_winkler(v, pv.as_ref()), pv.as_ref().to_owned())) + .filter(|(confidence, _)| *confidence > 0.8) + .collect(); + candidates.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal)); + candidates.into_iter().map(|(_, pv)| pv).collect() +} + +#[cfg(not(feature = "suggestions"))] +pub(crate) fn did_you_mean(_: &str, _: I) -> Vec +where + T: AsRef, + I: IntoIterator, +{ + Vec::new() +} + +/// Returns a suffix that can be empty, or is the standard 'did you mean' phrase +pub(crate) fn did_you_mean_flag<'a, 'help, I, T>( + arg: &str, + remaining_args: &[&str], + longs: I, + subcommands: impl IntoIterator>, +) -> Option<(String, Option)> +where + 'help: 'a, + T: AsRef, + I: IntoIterator, +{ + use crate::mkeymap::KeyType; + + match did_you_mean(arg, longs).pop() { + Some(candidate) => Some((candidate, None)), + None => subcommands + .into_iter() + .filter_map(|subcommand| { + subcommand._build_self(); + + let longs = subcommand.get_keymap().keys().filter_map(|a| { + if let KeyType::Long(v) = a { + Some(v.to_string_lossy().into_owned()) + } else { + None + } + }); + + let subcommand_name = subcommand.get_name(); + + let candidate = did_you_mean(arg, longs).pop()?; + let score = remaining_args.iter().position(|x| *x == subcommand_name)?; + Some((score, (candidate, Some(subcommand_name.to_string())))) + }) + .min_by_key(|(x, _)| *x) + .map(|(_, suggestion)| suggestion), + } +} + +#[cfg(all(test, features = "suggestions"))] +mod test { + use super::*; + + #[test] + fn possible_values_match() { + let p_vals = ["test", "possible", "values"]; + assert_eq!(did_you_mean("tst", p_vals.iter()), Some("test")); + } + + #[test] + fn possible_values_match() { + let p_vals = ["test", "temp"]; + assert_eq!(did_you_mean("te", p_vals.iter()), Some("test")); + } + + #[test] + fn possible_values_nomatch() { + let p_vals = ["test", "possible", "values"]; + assert!(did_you_mean("hahaahahah", p_vals.iter()).is_none()); + } + + #[test] + fn flag() { + let p_vals = ["test", "possible", "values"]; + assert_eq!( + did_you_mean_flag("tst", p_vals.iter(), []), + Some(("test", None)) + ); + } +} diff --git a/vendor/clap-3.2.20/src/parser/matches/any_value.rs b/vendor/clap-3.2.20/src/parser/matches/any_value.rs new file mode 100644 index 000000000..a9277e75f --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/matches/any_value.rs @@ -0,0 +1,112 @@ +#[derive(Clone)] +pub(crate) struct AnyValue { + inner: std::sync::Arc, + // While we can extract `TypeId` from `inner`, the debug repr is of a number, so let's track + // the type_name in debug builds. + id: AnyValueId, +} + +impl AnyValue { + pub(crate) fn new(inner: V) -> Self { + let id = AnyValueId::of::(); + let inner = std::sync::Arc::new(inner); + Self { inner, id } + } + + pub(crate) fn downcast_ref( + &self, + ) -> Option<&T> { + self.inner.downcast_ref::() + } + + pub(crate) fn downcast_into(self) -> Result { + let id = self.id; + let value = + std::sync::Arc::downcast::(self.inner).map_err(|inner| Self { inner, id })?; + let value = std::sync::Arc::try_unwrap(value).unwrap_or_else(|arc| (*arc).clone()); + Ok(value) + } + + pub(crate) fn type_id(&self) -> AnyValueId { + self.id + } +} + +impl std::fmt::Debug for AnyValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + f.debug_struct("AnyValue").field("inner", &self.id).finish() + } +} + +#[derive(Copy, Clone)] +pub struct AnyValueId { + type_id: std::any::TypeId, + #[cfg(debug_assertions)] + type_name: &'static str, +} + +impl AnyValueId { + pub(crate) fn of() -> Self { + Self { + type_id: std::any::TypeId::of::(), + #[cfg(debug_assertions)] + type_name: std::any::type_name::(), + } + } +} + +impl PartialEq for AnyValueId { + fn eq(&self, other: &Self) -> bool { + self.type_id == other.type_id + } +} + +impl Eq for AnyValueId {} + +impl PartialOrd for AnyValueId { + fn partial_cmp(&self, other: &Self) -> Option { + self.type_id.partial_cmp(&other.type_id) + } +} + +impl Ord for AnyValueId { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.type_id.cmp(&other.type_id) + } +} + +impl std::hash::Hash for AnyValueId { + fn hash(&self, state: &mut H) { + self.type_id.hash(state); + } +} + +impl std::fmt::Debug for AnyValueId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + #[cfg(not(debug_assertions))] + { + self.type_id.fmt(f) + } + #[cfg(debug_assertions)] + { + f.debug_struct(self.type_name).finish() + } + } +} + +impl<'a, A: ?Sized + 'static> From<&'a A> for AnyValueId { + fn from(_: &'a A) -> Self { + Self::of::() + } +} + +#[cfg(test)] +mod test { + #[test] + #[cfg(debug_assertions)] + fn debug_impl() { + use super::*; + + assert_eq!(format!("{:?}", AnyValue::new(5)), "AnyValue { inner: i32 }"); + } +} diff --git a/vendor/clap-3.2.20/src/parser/matches/arg_matches.rs b/vendor/clap-3.2.20/src/parser/matches/arg_matches.rs new file mode 100644 index 000000000..2585c0219 --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/matches/arg_matches.rs @@ -0,0 +1,1896 @@ +// Std +use std::any::Any; +use std::borrow::Cow; +use std::ffi::{OsStr, OsString}; +use std::fmt::{Debug, Display}; +use std::iter::{Cloned, Flatten, Map}; +use std::slice::Iter; +use std::str::FromStr; + +// Third Party +use indexmap::IndexMap; + +// Internal +use crate::parser::AnyValue; +use crate::parser::AnyValueId; +use crate::parser::MatchedArg; +use crate::parser::MatchesError; +use crate::parser::ValueSource; +use crate::util::{Id, Key}; +use crate::Error; +use crate::INTERNAL_ERROR_MSG; + +/// Container for parse results. +/// +/// Used to get information about the arguments that were supplied to the program at runtime by +/// the user. New instances of this struct are obtained by using the [`Command::get_matches`] family of +/// methods. +/// +/// # Examples +/// +/// ```no_run +/// # use clap::{Command, Arg, ValueSource}; +/// let matches = Command::new("MyApp") +/// .arg(Arg::new("out") +/// .long("output") +/// .required(true) +/// .takes_value(true) +/// .default_value("-")) +/// .arg(Arg::new("cfg") +/// .short('c') +/// .takes_value(true)) +/// .get_matches(); // builds the instance of ArgMatches +/// +/// // to get information about the "cfg" argument we created, such as the value supplied we use +/// // various ArgMatches methods, such as [ArgMatches::get_one] +/// if let Some(c) = matches.get_one::("cfg") { +/// println!("Value for -c: {}", c); +/// } +/// +/// // The ArgMatches::get_one method returns an Option because the user may not have supplied +/// // that argument at runtime. But if we specified that the argument was "required" as we did +/// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually +/// // used at runtime. +/// println!("Value for --output: {}", matches.get_one::("out").unwrap()); +/// +/// // You can check the presence of an argument's values +/// if matches.contains_id("out") { +/// // However, if you want to know where the value came from +/// if matches.value_source("out").expect("checked contains_id") == ValueSource::CommandLine { +/// println!("`out` set by user"); +/// } else { +/// println!("`out` is defaulted"); +/// } +/// } +/// ``` +/// [`Command::get_matches`]: crate::Command::get_matches() +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct ArgMatches { + #[cfg(debug_assertions)] + pub(crate) valid_args: Vec, + #[cfg(debug_assertions)] + pub(crate) valid_subcommands: Vec, + #[cfg(debug_assertions)] + pub(crate) disable_asserts: bool, + pub(crate) args: IndexMap, + pub(crate) subcommand: Option>, +} + +/// # Arguments +impl ArgMatches { + /// Gets the value of a specific option or positional argument. + /// + /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime. + /// + /// Returns an error if the wrong type was used. + /// + /// Returns `None` if the option wasn't present. + /// + /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set. + /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime. + /// + /// # Panic + /// + /// If the argument definition and access mismatch. To handle this case programmatically, see + /// [`ArgMatches::try_get_one`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, value_parser}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("port") + /// .value_parser(value_parser!(usize)) + /// .takes_value(true) + /// .required(true)) + /// .get_matches_from(vec!["myapp", "2020"]); + /// + /// let port: usize = *m + /// .get_one("port") + /// .expect("`port`is required"); + /// assert_eq!(port, 2020); + /// ``` + /// [option]: crate::Arg::takes_value() + /// [positional]: crate::Arg::index() + /// [`default_value`]: crate::Arg::default_value() + #[track_caller] + pub fn get_one(&self, id: &str) -> Option<&T> { + let internal_id = Id::from(id); + MatchesError::unwrap(&internal_id, self.try_get_one(id)) + } + + /// Gets the value of a specific [`ArgAction::Count`][crate::ArgAction::Count] flag + /// + /// # Panic + /// + /// If the argument's action is not [`ArgAction::Count`][crate::ArgAction::Count] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::Count) + /// ); + /// + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// assert_eq!( + /// matches.get_count("flag"), + /// 2 + /// ); + /// ``` + #[track_caller] + pub fn get_count(&self, id: &str) -> u8 { + *self + .get_one::(id) + .expect("ArgAction::Count is defaulted") + } + + /// Gets the value of a specific [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] flag + /// + /// # Panic + /// + /// If the argument's action is not [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] + /// + /// # Examples + /// + /// ```rust + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("flag") + /// .long("flag") + /// .action(clap::ArgAction::SetTrue) + /// ); + /// + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// assert!(matches.contains_id("flag")); + /// assert_eq!( + /// matches.get_flag("flag"), + /// true + /// ); + /// ``` + #[track_caller] + pub fn get_flag(&self, id: &str) -> bool { + *self + .get_one::(id) + .expect("ArgAction::SetTrue / ArgAction::SetFalse is defaulted") + } + + /// Iterate over values of a specific option or positional argument. + /// + /// i.e. an argument that takes multiple values at runtime. + /// + /// Returns an error if the wrong type was used. + /// + /// Returns `None` if the option wasn't present. + /// + /// # Panic + /// + /// If the argument definition and access mismatch. To handle this case programmatically, see + /// [`ArgMatches::try_get_many`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, value_parser, ArgAction}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("ports") + /// .action(ArgAction::Append) + /// .value_parser(value_parser!(usize)) + /// .short('p') + /// .takes_value(true) + /// .required(true)) + /// .get_matches_from(vec![ + /// "myprog", "-p", "22", "-p", "80", "-p", "2020" + /// ]); + /// let vals: Vec = m.get_many("ports") + /// .expect("`port`is required") + /// .copied() + /// .collect(); + /// assert_eq!(vals, [22, 80, 2020]); + /// ``` + #[track_caller] + pub fn get_many( + &self, + id: &str, + ) -> Option> { + let internal_id = Id::from(id); + MatchesError::unwrap(&internal_id, self.try_get_many(id)) + } + + /// Iterate over the original argument values. + /// + /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they + /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid + /// filename on a Unix system as an argument value may contain invalid UTF-8. + /// + /// Returns `None` if the option wasn't present. + /// + /// # Panic + /// + /// If the argument definition and access mismatch. To handle this case programmatically, see + /// [`ArgMatches::try_get_raw`]. + /// + /// # Examples + /// + #[cfg_attr(not(unix), doc = " ```ignore")] + #[cfg_attr(unix, doc = " ```")] + /// # use clap::{Command, arg, value_parser}; + /// # use std::ffi::{OsStr,OsString}; + /// # use std::os::unix::ffi::{OsStrExt,OsStringExt}; + /// use std::path::PathBuf; + /// + /// let m = Command::new("utf8") + /// .arg(arg!( ... "some arg").value_parser(value_parser!(PathBuf))) + /// .get_matches_from(vec![OsString::from("myprog"), + /// // "Hi" + /// OsString::from_vec(vec![b'H', b'i']), + /// // "{0xe9}!" + /// OsString::from_vec(vec![0xe9, b'!'])]); + /// + /// let mut itr = m.get_raw("arg") + /// .expect("`port`is required") + /// .into_iter(); + /// assert_eq!(itr.next(), Some(OsStr::new("Hi"))); + /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!']))); + /// assert_eq!(itr.next(), None); + /// ``` + /// [`Iterator`]: std::iter::Iterator + /// [`OsSt`]: std::ffi::OsStr + /// [values]: OsValues + /// [`String`]: std::string::String + #[track_caller] + pub fn get_raw(&self, id: &str) -> Option> { + let internal_id = Id::from(id); + MatchesError::unwrap(&internal_id, self.try_get_raw(id)) + } + + /// Returns the value of a specific option or positional argument. + /// + /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime. + /// + /// Returns an error if the wrong type was used. No item will have been removed. + /// + /// Returns `None` if the option wasn't present. + /// + /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set. + /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime. + /// + /// # Panic + /// + /// If the argument definition and access mismatch. To handle this case programmatically, see + /// [`ArgMatches::try_remove_one`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, value_parser}; + /// let mut m = Command::new("myprog") + /// .arg(Arg::new("file") + /// .required(true) + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "myprog", "file.txt", + /// ]); + /// let vals: String = m.remove_one("file") + /// .expect("`file`is required"); + /// assert_eq!(vals, "file.txt"); + /// ``` + /// [option]: crate::Arg::takes_value() + /// [positional]: crate::Arg::index() + /// [`default_value`]: crate::Arg::default_value() + #[track_caller] + pub fn remove_one(&mut self, id: &str) -> Option { + let internal_id = Id::from(id); + MatchesError::unwrap(&internal_id, self.try_remove_one(id)) + } + + /// Return values of a specific option or positional argument. + /// + /// i.e. an argument that takes multiple values at runtime. + /// + /// Returns an error if the wrong type was used. No item will have been removed. + /// + /// Returns `None` if the option wasn't present. + /// + /// # Panic + /// + /// If the argument definition and access mismatch. To handle this case programmatically, see + /// [`ArgMatches::try_remove_many`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, value_parser, ArgAction}; + /// let mut m = Command::new("myprog") + /// .arg(Arg::new("file") + /// .action(ArgAction::Append) + /// .multiple_values(true) + /// .required(true) + /// .takes_value(true)) + /// .get_matches_from(vec![ + /// "myprog", "file1.txt", "file2.txt", "file3.txt", "file4.txt", + /// ]); + /// let vals: Vec = m.remove_many("file") + /// .expect("`file`is required") + /// .collect(); + /// assert_eq!(vals, ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]); + /// ``` + #[track_caller] + pub fn remove_many( + &mut self, + id: &str, + ) -> Option> { + let internal_id = Id::from(id); + MatchesError::unwrap(&internal_id, self.try_remove_many(id)) + } + + /// Check if values are present for the argument or group id + /// + /// *NOTE:* This will always return `true` if [`default_value`] has been set. + /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime. + /// + /// # Panics + /// + /// If `id` is is not a valid argument or group name. To handle this case programmatically, see + /// [`ArgMatches::try_contains_id`]. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("debug") + /// .short('d')) + /// .get_matches_from(vec![ + /// "myprog", "-d" + /// ]); + /// + /// assert!(m.contains_id("debug")); + /// ``` + /// + /// [`default_value`]: crate::Arg::default_value() + pub fn contains_id(&self, id: &str) -> bool { + let internal_id = Id::from(id); + MatchesError::unwrap(&internal_id, self.try_contains_id(id)) + } + + /// Check if any args were present on the command line + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let mut cmd = Command::new("myapp") + /// .arg(Arg::new("output") + /// .takes_value(true)); + /// + /// let m = cmd + /// .try_get_matches_from_mut(vec!["myapp", "something"]) + /// .unwrap(); + /// assert!(m.args_present()); + /// + /// let m = cmd + /// .try_get_matches_from_mut(vec!["myapp"]) + /// .unwrap(); + /// assert!(! m.args_present()); + pub fn args_present(&self) -> bool { + !self.args.is_empty() + } + + /// Deprecated, replaced with [`ArgMatches::get_one()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn value_of(&self, id: T) -> Option<&str> { + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = unwrap_string_arg(&id, arg.first()?); + Some(v) + } + + /// Deprecated, replaced with [`ArgMatches::get_one()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn value_of_lossy(&self, id: T) -> Option> { + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = unwrap_os_string_arg(&id, arg.first()?); + Some(v.to_string_lossy()) + } + + /// Deprecated, replaced with [`ArgMatches::get_one()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn value_of_os(&self, id: T) -> Option<&OsStr> { + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = unwrap_os_string_arg(&id, arg.first()?); + Some(v) + } + + /// Deprecated, replaced with [`ArgMatches::get_many()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn values_of(&self, id: T) -> Option { + #![allow(deprecated)] + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = Values { + iter: arg.vals_flatten().map(unwrap_string), + len: arg.num_vals(), + }; + Some(v) + } + + /// Get an [`Iterator`] over groups of values of a specific option. + /// + /// specifically grouped by the occurrences of the options. + /// + /// Each group is a `Vec<&str>` containing the arguments passed to a single occurrence + /// of the option. + /// + /// If the option doesn't support multiple occurrences, or there was only a single occurrence, + /// the iterator will only contain a single item. + /// + /// Returns `None` if the option wasn't present. + /// + /// # Panics + /// + /// If the value is invalid UTF-8. + /// + /// If `id` is not a valid argument or group id. + /// + /// # Examples + /// ```rust + /// # use clap::{Command,Arg, ArgAction}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("exec") + /// .short('x') + /// .min_values(1) + /// .action(ArgAction::Append) + /// .value_terminator(";")) + /// .get_matches_from(vec![ + /// "myprog", "-x", "echo", "hi", ";", "-x", "echo", "bye"]); + /// let vals: Vec> = m.grouped_values_of("exec").unwrap().collect(); + /// assert_eq!(vals, [["echo", "hi"], ["echo", "bye"]]); + /// ``` + /// [`Iterator`]: std::iter::Iterator + #[cfg(feature = "unstable-grouped")] + #[cfg_attr(debug_assertions, track_caller)] + pub fn grouped_values_of(&self, id: T) -> Option { + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = GroupedValues { + iter: arg.vals().map(|g| g.iter().map(unwrap_string).collect()), + len: arg.vals().len(), + }; + Some(v) + } + + /// Deprecated, replaced with [`ArgMatches::get_many()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn values_of_lossy(&self, id: T) -> Option> { + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = arg + .vals_flatten() + .map(|v| unwrap_os_string_arg(&id, v).to_string_lossy().into_owned()) + .collect(); + Some(v) + } + + /// Deprecated, replaced with [`ArgMatches::get_many()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn values_of_os(&self, id: T) -> Option { + #![allow(deprecated)] + let id = Id::from(id); + let arg = self.get_arg(&id)?; + let v = OsValues { + iter: arg.vals_flatten().map(unwrap_os_string), + len: arg.num_vals(), + }; + Some(v) + } + + /// Deprecated, replaced with [`ArgMatches::get_one()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn value_of_t(&self, name: &str) -> Result + where + R: FromStr, + ::Err: Display, + { + #![allow(deprecated)] + let v = self + .value_of(name) + .ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?; + v.parse::().map_err(|e| { + let message = format!( + "The argument '{}' isn't a valid value for '{}': {}", + v, name, e + ); + + Error::value_validation(name.to_string(), v.to_string(), message.into()) + }) + } + + /// Deprecated, replaced with [`ArgMatches::get_one()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn value_of_t_or_exit(&self, name: &str) -> R + where + R: FromStr, + ::Err: Display, + { + #![allow(deprecated)] + self.value_of_t(name).unwrap_or_else(|e| e.exit()) + } + + /// Deprecated, replaced with [`ArgMatches::get_many()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn values_of_t(&self, name: &str) -> Result, Error> + where + R: FromStr, + ::Err: Display, + { + #![allow(deprecated)] + let v = self + .values_of(name) + .ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?; + v.map(|v| { + v.parse::().map_err(|e| { + let message = format!("The argument '{}' isn't a valid value: {}", v, e); + + Error::value_validation(name.to_string(), v.to_string(), message.into()) + }) + }) + .collect() + } + + /// Deprecated, replaced with [`ArgMatches::get_many()`] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn values_of_t_or_exit(&self, name: &str) -> Vec + where + R: FromStr, + ::Err: Display, + { + #![allow(deprecated)] + self.values_of_t(name).unwrap_or_else(|e| e.exit()) + } + + /// Deprecated, replaced with [`ArgAction::SetTrue`][crate::ArgAction] or + /// [`ArgMatches::contains_id`]. + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with either `ArgAction::SetTrue` or `ArgMatches::contains_id(...)`" + ) + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn is_present(&self, id: T) -> bool { + let id = Id::from(id); + + #[cfg(debug_assertions)] + self.get_arg(&id); + + self.args.contains_key(&id) + } + + /// Report where argument value came from + /// + /// # Panics + /// + /// If `id` is is not a valid argument or group id. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ValueSource}; + /// let m = Command::new("myprog") + /// .arg(Arg::new("debug") + /// .short('d')) + /// .get_matches_from(vec![ + /// "myprog", "-d" + /// ]); + /// + /// assert_eq!(m.value_source("debug"), Some(ValueSource::CommandLine)); + /// ``` + /// + /// [`default_value`]: crate::Arg::default_value() + #[cfg_attr(debug_assertions, track_caller)] + pub fn value_source(&self, id: T) -> Option { + let id = Id::from(id); + + let value = self.get_arg(&id); + + value.and_then(MatchedArg::source) + } + + /// Deprecated, replaced with [`ArgAction::Count`][crate::ArgAction], + /// [`ArgMatches::get_many`]`.len()`, or [`ArgMatches::value_source`]. + #[cfg_attr( + feature = "deprecated", + deprecated( + since = "3.2.0", + note = "Replaced with either `ArgAction::Count`, `ArgMatches::get_many(...).len()`, or `ArgMatches::value_source`" + ) + )] + #[cfg_attr(debug_assertions, track_caller)] + pub fn occurrences_of(&self, id: T) -> u64 { + #![allow(deprecated)] + self.get_arg(&Id::from(id)) + .map_or(0, |a| a.get_occurrences()) + } + + /// The first index of that an argument showed up. + /// + /// Indices are similar to argv indices, but are not exactly 1:1. + /// + /// For flags (i.e. those arguments which don't have an associated value), indices refer + /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices + /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the + /// index for `val` would be recorded. This is by design. + /// + /// Besides the flag/option discrepancy, the primary difference between an argv index and clap + /// index, is that clap continues counting once all arguments have properly separated, whereas + /// an argv index does not. + /// + /// The examples should clear this up. + /// + /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first* + /// index. See [`ArgMatches::indices_of`]. + /// + /// # Panics + /// + /// If `id` is is not a valid argument or group id. + /// + /// # Examples + /// + /// The argv indices are listed in the comments below. See how they correspond to the clap + /// indices. Note that if it's not listed in a clap index, this is because it's not saved in + /// in an `ArgMatches` struct for querying. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("option") + /// .short('o') + /// .takes_value(true)) + /// .get_matches_from(vec!["myapp", "-f", "-o", "val"]); + /// // ARGV indices: ^0 ^1 ^2 ^3 + /// // clap indices: ^1 ^3 + /// + /// assert_eq!(m.index_of("flag"), Some(1)); + /// assert_eq!(m.index_of("option"), Some(3)); + /// ``` + /// + /// Now notice, if we use one of the other styles of options: + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("option") + /// .short('o') + /// .takes_value(true)) + /// .get_matches_from(vec!["myapp", "-f", "-o=val"]); + /// // ARGV indices: ^0 ^1 ^2 + /// // clap indices: ^1 ^3 + /// + /// assert_eq!(m.index_of("flag"), Some(1)); + /// assert_eq!(m.index_of("option"), Some(3)); + /// ``` + /// + /// Things become much more complicated, or clear if we look at a more complex combination of + /// flags. Let's also throw in the final option style for good measure. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("flag2") + /// .short('F')) + /// .arg(Arg::new("flag3") + /// .short('z')) + /// .arg(Arg::new("option") + /// .short('o') + /// .takes_value(true)) + /// .get_matches_from(vec!["myapp", "-fzF", "-oval"]); + /// // ARGV indices: ^0 ^1 ^2 + /// // clap indices: ^1,2,3 ^5 + /// // + /// // clap sees the above as 'myapp -f -z -F -o val' + /// // ^0 ^1 ^2 ^3 ^4 ^5 + /// assert_eq!(m.index_of("flag"), Some(1)); + /// assert_eq!(m.index_of("flag2"), Some(3)); + /// assert_eq!(m.index_of("flag3"), Some(2)); + /// assert_eq!(m.index_of("option"), Some(5)); + /// ``` + /// + /// One final combination of flags/options to see how they combine: + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("flag") + /// .short('f')) + /// .arg(Arg::new("flag2") + /// .short('F')) + /// .arg(Arg::new("flag3") + /// .short('z')) + /// .arg(Arg::new("option") + /// .short('o') + /// .takes_value(true)) + /// .get_matches_from(vec!["myapp", "-fzFoval"]); + /// // ARGV indices: ^0 ^1 + /// // clap indices: ^1,2,3^5 + /// // + /// // clap sees the above as 'myapp -f -z -F -o val' + /// // ^0 ^1 ^2 ^3 ^4 ^5 + /// assert_eq!(m.index_of("flag"), Some(1)); + /// assert_eq!(m.index_of("flag2"), Some(3)); + /// assert_eq!(m.index_of("flag3"), Some(2)); + /// assert_eq!(m.index_of("option"), Some(5)); + /// ``` + /// + /// The last part to mention is when values are sent in multiple groups with a [delimiter]. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("option") + /// .short('o') + /// .use_value_delimiter(true) + /// .multiple_values(true)) + /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); + /// // ARGV indices: ^0 ^1 + /// // clap indices: ^2 ^3 ^4 + /// // + /// // clap sees the above as 'myapp -o val1 val2 val3' + /// // ^0 ^1 ^2 ^3 ^4 + /// assert_eq!(m.index_of("option"), Some(2)); + /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 3, 4]); + /// ``` + /// [delimiter]: crate::Arg::value_delimiter() + #[cfg_attr(debug_assertions, track_caller)] + pub fn index_of(&self, id: T) -> Option { + let arg = self.get_arg(&Id::from(id))?; + let i = arg.get_index(0)?; + Some(i) + } + + /// All indices an argument appeared at when parsing. + /// + /// Indices are similar to argv indices, but are not exactly 1:1. + /// + /// For flags (i.e. those arguments which don't have an associated value), indices refer + /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices + /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the + /// index for `val` would be recorded. This is by design. + /// + /// *NOTE:* For more information about how clap indices compared to argv indices, see + /// [`ArgMatches::index_of`] + /// + /// # Panics + /// + /// If `id` is is not a valid argument or group id. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("option") + /// .short('o') + /// .use_value_delimiter(true) + /// .multiple_values(true)) + /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); + /// // ARGV indices: ^0 ^1 + /// // clap indices: ^2 ^3 ^4 + /// // + /// // clap sees the above as 'myapp -o val1 val2 val3' + /// // ^0 ^1 ^2 ^3 ^4 + /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 3, 4]); + /// ``` + /// + /// Another quick example is when flags and options are used together + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("option") + /// .short('o') + /// .takes_value(true) + /// .action(ArgAction::Append)) + /// .arg(Arg::new("flag") + /// .short('f') + /// .action(ArgAction::Count)) + /// .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]); + /// // ARGV indices: ^0 ^1 ^2 ^3 ^4 ^5 ^6 + /// // clap indices: ^2 ^3 ^5 ^6 + /// + /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 5]); + /// assert_eq!(m.indices_of("flag").unwrap().collect::>(), &[6]); + /// ``` + /// + /// One final example, which is an odd case; if we *don't* use value delimiter as we did with + /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they + /// would all be a single value of `val1,val2,val3`, in which case they'd only receive a single + /// index. + /// + /// ```rust + /// # use clap::{Command, Arg}; + /// let m = Command::new("myapp") + /// .arg(Arg::new("option") + /// .short('o') + /// .takes_value(true) + /// .multiple_values(true)) + /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); + /// // ARGV indices: ^0 ^1 + /// // clap indices: ^2 + /// // + /// // clap sees the above as 'myapp -o "val1,val2,val3"' + /// // ^0 ^1 ^2 + /// assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2]); + /// ``` + /// [`ArgMatches::index_of`]: ArgMatches::index_of() + /// [delimiter]: Arg::value_delimiter() + #[cfg_attr(debug_assertions, track_caller)] + pub fn indices_of(&self, id: T) -> Option> { + let arg = self.get_arg(&Id::from(id))?; + let i = Indices { + iter: arg.indices(), + len: arg.num_vals(), + }; + Some(i) + } + + #[inline] + #[doc(hidden)] + #[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::try_get_one()`") + )] + pub fn is_valid_arg(&self, _id: impl Key) -> bool { + #[cfg(debug_assertions)] + { + let id = Id::from(_id); + self.disable_asserts || id == Id::empty_hash() || self.valid_args.contains(&id) + } + #[cfg(not(debug_assertions))] + { + true + } + } +} + +/// # Subcommands +impl ArgMatches { + /// The name and `ArgMatches` of the current [subcommand]. + /// + /// Subcommand values are put in a child [`ArgMatches`] + /// + /// Returns `None` if the subcommand wasn't present at runtime, + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let app_m = Command::new("git") + /// .subcommand(Command::new("clone")) + /// .subcommand(Command::new("push")) + /// .subcommand(Command::new("commit")) + /// .get_matches(); + /// + /// match app_m.subcommand() { + /// Some(("clone", sub_m)) => {}, // clone was used + /// Some(("push", sub_m)) => {}, // push was used + /// Some(("commit", sub_m)) => {}, // commit was used + /// _ => {}, // Either no subcommand or one not tested for... + /// } + /// ``` + /// + /// Another useful scenario is when you want to support third party, or external, subcommands. + /// In these cases you can't know the subcommand name ahead of time, so use a variable instead + /// with pattern matching! + /// + /// ```rust + /// # use clap::Command; + /// // Assume there is an external subcommand named "subcmd" + /// let app_m = Command::new("myprog") + /// .allow_external_subcommands(true) + /// .get_matches_from(vec![ + /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" + /// ]); + /// + /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty + /// // string argument name + /// match app_m.subcommand() { + /// Some((external, sub_m)) => { + /// let ext_args: Vec<&str> = sub_m.get_many::("") + /// .unwrap().map(|s| s.as_str()).collect(); + /// assert_eq!(external, "subcmd"); + /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); + /// }, + /// _ => {}, + /// } + /// ``` + /// [subcommand]: crate::Command::subcommand + #[inline] + pub fn subcommand(&self) -> Option<(&str, &ArgMatches)> { + self.subcommand.as_ref().map(|sc| (&*sc.name, &sc.matches)) + } + + /// Return the name and `ArgMatches` of the current [subcommand]. + /// + /// Subcommand values are put in a child [`ArgMatches`] + /// + /// Returns `None` if the subcommand wasn't present at runtime, + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let mut app_m = Command::new("git") + /// .subcommand(Command::new("clone")) + /// .subcommand(Command::new("push")) + /// .subcommand(Command::new("commit")) + /// .subcommand_required(true) + /// .get_matches(); + /// + /// let (name, sub_m) = app_m.remove_subcommand().expect("required"); + /// match (name.as_str(), sub_m) { + /// ("clone", sub_m) => {}, // clone was used + /// ("push", sub_m) => {}, // push was used + /// ("commit", sub_m) => {}, // commit was used + /// (name, _) => unimplemented!("{}", name), + /// } + /// ``` + /// + /// Another useful scenario is when you want to support third party, or external, subcommands. + /// In these cases you can't know the subcommand name ahead of time, so use a variable instead + /// with pattern matching! + /// + /// ```rust + /// # use clap::Command; + /// // Assume there is an external subcommand named "subcmd" + /// let mut app_m = Command::new("myprog") + /// .allow_external_subcommands(true) + /// .get_matches_from(vec![ + /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" + /// ]); + /// + /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty + /// // string argument name + /// match app_m.remove_subcommand() { + /// Some((external, mut sub_m)) => { + /// let ext_args: Vec = sub_m.remove_many("") + /// .expect("`file`is required") + /// .collect(); + /// assert_eq!(external, "subcmd"); + /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); + /// }, + /// _ => {}, + /// } + /// ``` + /// [subcommand]: crate::Command::subcommand + pub fn remove_subcommand(&mut self) -> Option<(String, ArgMatches)> { + self.subcommand.take().map(|sc| (sc.name, sc.matches)) + } + + /// The `ArgMatches` for the current [subcommand]. + /// + /// Subcommand values are put in a child [`ArgMatches`] + /// + /// Returns `None` if the subcommand wasn't present at runtime, + /// + /// # Panics + /// + /// If `id` is is not a valid subcommand. + /// + /// # Examples + /// + /// ```rust + /// # use clap::{Command, Arg, ArgAction}; + /// let app_m = Command::new("myprog") + /// .arg(Arg::new("debug") + /// .short('d') + /// .action(ArgAction::SetTrue) + /// ) + /// .subcommand(Command::new("test") + /// .arg(Arg::new("opt") + /// .long("option") + /// .takes_value(true))) + /// .get_matches_from(vec![ + /// "myprog", "-d", "test", "--option", "val" + /// ]); + /// + /// // Both parent commands, and child subcommands can have arguments present at the same times + /// assert!(*app_m.get_one::("debug").expect("defaulted by clap")); + /// + /// // Get the subcommand's ArgMatches instance + /// if let Some(sub_m) = app_m.subcommand_matches("test") { + /// // Use the struct like normal + /// assert_eq!(sub_m.get_one::("opt").map(|s| s.as_str()), Some("val")); + /// } + /// ``` + /// + /// [subcommand]: crate::Command::subcommand + /// [`Command`]: crate::Command + pub fn subcommand_matches(&self, id: T) -> Option<&ArgMatches> { + self.get_subcommand(&id.into()).map(|sc| &sc.matches) + } + + /// The name of the current [subcommand]. + /// + /// Returns `None` if the subcommand wasn't present at runtime, + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{Command, Arg, }; + /// let app_m = Command::new("git") + /// .subcommand(Command::new("clone")) + /// .subcommand(Command::new("push")) + /// .subcommand(Command::new("commit")) + /// .get_matches(); + /// + /// match app_m.subcommand_name() { + /// Some("clone") => {}, // clone was used + /// Some("push") => {}, // push was used + /// Some("commit") => {}, // commit was used + /// _ => {}, // Either no subcommand or one not tested for... + /// } + /// ``` + /// [subcommand]: crate::Command::subcommand + /// [`Command`]: crate::Command + #[inline] + pub fn subcommand_name(&self) -> Option<&str> { + self.subcommand.as_ref().map(|sc| &*sc.name) + } + + /// Check if a subcommand can be queried + /// + /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer + /// mistakes. In some context, this doesn't work, so users can use this function to check + /// before they do a query on `ArgMatches`. + #[inline] + #[doc(hidden)] + pub fn is_valid_subcommand(&self, _id: impl Key) -> bool { + #[cfg(debug_assertions)] + { + let id = Id::from(_id); + self.disable_asserts || id == Id::empty_hash() || self.valid_subcommands.contains(&id) + } + #[cfg(not(debug_assertions))] + { + true + } + } +} + +/// # Advanced +impl ArgMatches { + /// Non-panicking version of [`ArgMatches::get_one`] + pub fn try_get_one( + &self, + id: &str, + ) -> Result, MatchesError> { + let id = Id::from(id); + let arg = self.try_get_arg_t::(&id)?; + let value = match arg.and_then(|a| a.first()) { + Some(value) => value, + None => { + return Ok(None); + } + }; + Ok(value + .downcast_ref::() + .map(Some) + .expect(INTERNAL_ERROR_MSG)) // enforced by `try_get_arg_t` + } + + /// Non-panicking version of [`ArgMatches::get_many`] + pub fn try_get_many( + &self, + id: &str, + ) -> Result>, MatchesError> { + let id = Id::from(id); + let arg = match self.try_get_arg_t::(&id)? { + Some(arg) => arg, + None => return Ok(None), + }; + let len = arg.num_vals(); + let values = arg.vals_flatten(); + let values = ValuesRef { + // enforced by `try_get_arg_t` + iter: values.map(|v| v.downcast_ref::().expect(INTERNAL_ERROR_MSG)), + len, + }; + Ok(Some(values)) + } + + /// Non-panicking version of [`ArgMatches::get_raw`] + pub fn try_get_raw(&self, id: &str) -> Result>, MatchesError> { + let id = Id::from(id); + let arg = match self.try_get_arg(&id)? { + Some(arg) => arg, + None => return Ok(None), + }; + let len = arg.num_vals(); + let values = arg.raw_vals_flatten(); + let values = RawValues { + iter: values.map(OsString::as_os_str), + len, + }; + Ok(Some(values)) + } + + /// Non-panicking version of [`ArgMatches::remove_one`] + pub fn try_remove_one( + &mut self, + id: &str, + ) -> Result, MatchesError> { + let id = Id::from(id); + match self.try_remove_arg_t::(&id)? { + Some(values) => Ok(values + .into_vals_flatten() + // enforced by `try_get_arg_t` + .map(|v| v.downcast_into::().expect(INTERNAL_ERROR_MSG)) + .next()), + None => Ok(None), + } + } + + /// Non-panicking version of [`ArgMatches::remove_many`] + pub fn try_remove_many( + &mut self, + id: &str, + ) -> Result>, MatchesError> { + let id = Id::from(id); + let arg = match self.try_remove_arg_t::(&id)? { + Some(arg) => arg, + None => return Ok(None), + }; + let len = arg.num_vals(); + let values = arg.into_vals_flatten(); + let values = Values2 { + // enforced by `try_get_arg_t` + iter: values.map(|v| v.downcast_into::().expect(INTERNAL_ERROR_MSG)), + len, + }; + Ok(Some(values)) + } + + /// Non-panicking version of [`ArgMatches::contains_id`] + pub fn try_contains_id(&self, id: &str) -> Result { + let id = Id::from(id); + + self.verify_arg(&id)?; + + let presence = self.args.contains_key(&id); + Ok(presence) + } +} + +// Private methods +impl ArgMatches { + #[inline] + fn try_get_arg(&self, arg: &Id) -> Result, MatchesError> { + self.verify_arg(arg)?; + Ok(self.args.get(arg)) + } + + #[inline] + fn try_get_arg_t( + &self, + arg: &Id, + ) -> Result, MatchesError> { + let arg = match self.try_get_arg(arg)? { + Some(arg) => arg, + None => { + return Ok(None); + } + }; + self.verify_arg_t::(arg)?; + Ok(Some(arg)) + } + + #[inline] + fn try_remove_arg_t( + &mut self, + arg: &Id, + ) -> Result, MatchesError> { + self.verify_arg(arg)?; + let matched = match self.args.remove(arg) { + Some(matched) => matched, + None => { + return Ok(None); + } + }; + + let expected = AnyValueId::of::(); + let actual = matched.infer_type_id(expected); + if actual == expected { + Ok(Some(matched)) + } else { + self.args.insert(arg.clone(), matched); + Err(MatchesError::Downcast { actual, expected }) + } + } + + fn verify_arg_t( + &self, + arg: &MatchedArg, + ) -> Result<(), MatchesError> { + let expected = AnyValueId::of::(); + let actual = arg.infer_type_id(expected); + if expected == actual { + Ok(()) + } else { + Err(MatchesError::Downcast { actual, expected }) + } + } + + #[inline] + fn verify_arg(&self, _arg: &Id) -> Result<(), MatchesError> { + #[cfg(debug_assertions)] + { + if self.disable_asserts || *_arg == Id::empty_hash() || self.valid_args.contains(_arg) { + } else if self.valid_subcommands.contains(_arg) { + debug!( + "Subcommand `{:?}` used where an argument or group name was expected.", + _arg + ); + return Err(MatchesError::UnknownArgument {}); + } else { + debug!( + "`{:?}` is not an id of an argument or a group.\n\ + Make sure you're using the name of the argument itself \ + and not the name of short or long flags.", + _arg + ); + return Err(MatchesError::UnknownArgument {}); + } + } + Ok(()) + } + + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + fn get_arg(&self, arg: &Id) -> Option<&MatchedArg> { + #[cfg(debug_assertions)] + { + if self.disable_asserts || *arg == Id::empty_hash() || self.valid_args.contains(arg) { + } else if self.valid_subcommands.contains(arg) { + panic!( + "Subcommand `{:?}` used where an argument or group name was expected.", + arg + ); + } else { + panic!( + "`{:?}` is not an id of an argument or a group.\n\ + Make sure you're using the name of the argument itself \ + and not the name of short or long flags.", + arg + ); + } + } + + self.args.get(arg) + } + + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + fn get_subcommand(&self, id: &Id) -> Option<&SubCommand> { + #[cfg(debug_assertions)] + { + if self.disable_asserts + || *id == Id::empty_hash() + || self.valid_subcommands.contains(id) + { + } else if self.valid_args.contains(id) { + panic!( + "Argument or group `{:?}` used where a subcommand name was expected.", + id + ); + } else { + panic!("`{:?}` is not a name of a subcommand.", id); + } + } + + if let Some(ref sc) = self.subcommand { + if sc.id == *id { + return Some(sc); + } + } + + None + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct SubCommand { + pub(crate) id: Id, + pub(crate) name: String, + pub(crate) matches: ArgMatches, +} + +/// Iterate over multiple values for an argument via [`ArgMatches::remove_many`]. +/// +/// # Examples +/// +/// ```rust +/// # use clap::{Command, Arg, ArgAction}; +/// let mut m = Command::new("myapp") +/// .arg(Arg::new("output") +/// .short('o') +/// .action(ArgAction::Append) +/// .takes_value(true)) +/// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]); +/// +/// let mut values = m.remove_many::("output") +/// .unwrap(); +/// +/// assert_eq!(values.next(), Some(String::from("val1"))); +/// assert_eq!(values.next(), Some(String::from("val2"))); +/// assert_eq!(values.next(), None); +/// ``` +#[derive(Clone, Debug)] +pub struct Values2 { + #[allow(clippy::type_complexity)] + iter: Map>>, fn(AnyValue) -> T>, + len: usize, +} + +impl Iterator for Values2 { + type Item = T; + + fn next(&mut self) -> Option { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl DoubleEndedIterator for Values2 { + fn next_back(&mut self) -> Option { + self.iter.next_back() + } +} + +impl ExactSizeIterator for Values2 {} + +/// Creates an empty iterator. +impl Default for Values2 { + fn default() -> Self { + let empty: Vec> = Default::default(); + Values2 { + iter: empty.into_iter().flatten().map(|_| unreachable!()), + len: 0, + } + } +} + +/// Iterate over multiple values for an argument via [`ArgMatches::get_many`]. +/// +/// # Examples +/// +/// ```rust +/// # use clap::{Command, Arg, ArgAction}; +/// let m = Command::new("myapp") +/// .arg(Arg::new("output") +/// .short('o') +/// .action(ArgAction::Append) +/// .takes_value(true)) +/// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]); +/// +/// let mut values = m.get_many::("output") +/// .unwrap() +/// .map(|s| s.as_str()); +/// +/// assert_eq!(values.next(), Some("val1")); +/// assert_eq!(values.next(), Some("val2")); +/// assert_eq!(values.next(), None); +/// ``` +#[derive(Clone, Debug)] +pub struct ValuesRef<'a, T> { + #[allow(clippy::type_complexity)] + iter: Map>>, fn(&AnyValue) -> &T>, + len: usize, +} + +impl<'a, T: 'a> Iterator for ValuesRef<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl<'a, T: 'a> DoubleEndedIterator for ValuesRef<'a, T> { + fn next_back(&mut self) -> Option { + self.iter.next_back() + } +} + +impl<'a, T: 'a> ExactSizeIterator for ValuesRef<'a, T> {} + +/// Creates an empty iterator. +impl<'a, T: 'a> Default for ValuesRef<'a, T> { + fn default() -> Self { + static EMPTY: [Vec; 0] = []; + ValuesRef { + iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), + len: 0, + } + } +} + +/// Iterate over raw argument values via [`ArgMatches::get_raw`]. +/// +/// # Examples +/// +#[cfg_attr(not(unix), doc = " ```ignore")] +#[cfg_attr(unix, doc = " ```")] +/// # use clap::{Command, arg, value_parser}; +/// use std::ffi::OsString; +/// use std::os::unix::ffi::{OsStrExt,OsStringExt}; +/// +/// let m = Command::new("utf8") +/// .arg(arg!( "some arg") +/// .value_parser(value_parser!(OsString))) +/// .get_matches_from(vec![OsString::from("myprog"), +/// // "Hi {0xe9}!" +/// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); +/// assert_eq!( +/// &*m.get_raw("arg") +/// .unwrap() +/// .next().unwrap() +/// .as_bytes(), +/// [b'H', b'i', b' ', 0xe9, b'!'] +/// ); +/// ``` +#[derive(Clone, Debug)] +pub struct RawValues<'a> { + #[allow(clippy::type_complexity)] + iter: Map>>, fn(&OsString) -> &OsStr>, + len: usize, +} + +impl<'a> Iterator for RawValues<'a> { + type Item = &'a OsStr; + + fn next(&mut self) -> Option<&'a OsStr> { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl<'a> DoubleEndedIterator for RawValues<'a> { + fn next_back(&mut self) -> Option<&'a OsStr> { + self.iter.next_back() + } +} + +impl<'a> ExactSizeIterator for RawValues<'a> {} + +/// Creates an empty iterator. +impl Default for RawValues<'_> { + fn default() -> Self { + static EMPTY: [Vec; 0] = []; + RawValues { + iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), + len: 0, + } + } +} + +// The following were taken and adapted from vec_map source +// repo: https://github.com/contain-rs/vec-map +// commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33 +// license: MIT - Copyright (c) 2015 The Rust Project Developers + +/// Deprecated, replaced with [`ArgMatches::get_many()`] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") +)] +#[derive(Clone, Debug)] +pub struct Values<'a> { + #[allow(clippy::type_complexity)] + iter: Map>>, for<'r> fn(&'r AnyValue) -> &'r str>, + len: usize, +} + +#[allow(deprecated)] +impl<'a> Iterator for Values<'a> { + type Item = &'a str; + + fn next(&mut self) -> Option<&'a str> { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +#[allow(deprecated)] +impl<'a> DoubleEndedIterator for Values<'a> { + fn next_back(&mut self) -> Option<&'a str> { + self.iter.next_back() + } +} + +#[allow(deprecated)] +impl<'a> ExactSizeIterator for Values<'a> {} + +/// Creates an empty iterator. +#[allow(deprecated)] +impl<'a> Default for Values<'a> { + fn default() -> Self { + static EMPTY: [Vec; 0] = []; + Values { + iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), + len: 0, + } + } +} + +#[derive(Clone)] +#[allow(missing_debug_implementations)] +pub struct GroupedValues<'a> { + #[allow(clippy::type_complexity)] + iter: Map>, fn(&Vec) -> Vec<&str>>, + len: usize, +} + +impl<'a> Iterator for GroupedValues<'a> { + type Item = Vec<&'a str>; + + fn next(&mut self) -> Option { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl<'a> DoubleEndedIterator for GroupedValues<'a> { + fn next_back(&mut self) -> Option { + self.iter.next_back() + } +} + +impl<'a> ExactSizeIterator for GroupedValues<'a> {} + +/// Creates an empty iterator. Used for `unwrap_or_default()`. +impl<'a> Default for GroupedValues<'a> { + fn default() -> Self { + #![allow(deprecated)] + static EMPTY: [Vec; 0] = []; + GroupedValues { + iter: EMPTY[..].iter().map(|_| unreachable!()), + len: 0, + } + } +} + +/// Deprecated, replaced with [`ArgMatches::get_many()`] +#[cfg_attr( + feature = "deprecated", + deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`") +)] +#[derive(Clone, Debug)] +pub struct OsValues<'a> { + #[allow(clippy::type_complexity)] + iter: Map>>, fn(&AnyValue) -> &OsStr>, + len: usize, +} + +#[allow(deprecated)] +impl<'a> Iterator for OsValues<'a> { + type Item = &'a OsStr; + + fn next(&mut self) -> Option<&'a OsStr> { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +#[allow(deprecated)] +impl<'a> DoubleEndedIterator for OsValues<'a> { + fn next_back(&mut self) -> Option<&'a OsStr> { + self.iter.next_back() + } +} + +#[allow(deprecated)] +impl<'a> ExactSizeIterator for OsValues<'a> {} + +/// Creates an empty iterator. +#[allow(deprecated)] +impl Default for OsValues<'_> { + fn default() -> Self { + static EMPTY: [Vec; 0] = []; + OsValues { + iter: EMPTY[..].iter().flatten().map(|_| unreachable!()), + len: 0, + } + } +} + +/// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`] +/// +/// # Examples +/// +/// ```rust +/// # use clap::{Command, Arg}; +/// let m = Command::new("myapp") +/// .arg(Arg::new("output") +/// .short('o') +/// .multiple_values(true) +/// .takes_value(true)) +/// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]); +/// +/// let mut indices = m.indices_of("output").unwrap(); +/// +/// assert_eq!(indices.next(), Some(2)); +/// assert_eq!(indices.next(), Some(3)); +/// assert_eq!(indices.next(), None); +/// ``` +/// [`ArgMatches::indices_of`]: ArgMatches::indices_of() +#[derive(Clone, Debug)] +pub struct Indices<'a> { + iter: Cloned>, + len: usize, +} + +impl<'a> Iterator for Indices<'a> { + type Item = usize; + + fn next(&mut self) -> Option { + self.iter.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl<'a> DoubleEndedIterator for Indices<'a> { + fn next_back(&mut self) -> Option { + self.iter.next_back() + } +} + +impl<'a> ExactSizeIterator for Indices<'a> {} + +/// Creates an empty iterator. +impl<'a> Default for Indices<'a> { + fn default() -> Self { + static EMPTY: [usize; 0] = []; + // This is never called because the iterator is empty: + Indices { + iter: EMPTY[..].iter().cloned(), + len: 0, + } + } +} + +#[cfg_attr(debug_assertions, track_caller)] +#[inline] +fn unwrap_string(value: &AnyValue) -> &str { + match value.downcast_ref::() { + Some(value) => value, + None => { + panic!("Must use `_os` lookups with `Arg::allow_invalid_utf8`",) + } + } +} + +#[cfg_attr(debug_assertions, track_caller)] +#[inline] +fn unwrap_string_arg<'v>(id: &Id, value: &'v AnyValue) -> &'v str { + match value.downcast_ref::() { + Some(value) => value, + None => { + panic!( + "Must use `_os` lookups with `Arg::allow_invalid_utf8` at `{:?}`", + id + ) + } + } +} + +#[cfg_attr(debug_assertions, track_caller)] +#[inline] +fn unwrap_os_string(value: &AnyValue) -> &OsStr { + match value.downcast_ref::() { + Some(value) => value, + None => { + panic!("Must use `Arg::allow_invalid_utf8` with `_os` lookups",) + } + } +} + +#[cfg_attr(debug_assertions, track_caller)] +#[inline] +fn unwrap_os_string_arg<'v>(id: &Id, value: &'v AnyValue) -> &'v OsStr { + match value.downcast_ref::() { + Some(value) => value, + None => { + panic!( + "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `{:?}`", + id + ) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_auto_traits() { + static_assertions::assert_impl_all!(ArgMatches: Send, Sync, Unpin); + } + + #[test] + fn test_default_values() { + #![allow(deprecated)] + let mut values: Values = Values::default(); + assert_eq!(values.next(), None); + } + + #[test] + fn test_default_osvalues() { + #![allow(deprecated)] + let mut values: OsValues = OsValues::default(); + assert_eq!(values.next(), None); + } + + #[test] + fn test_default_raw_values() { + let mut values: RawValues = Default::default(); + assert_eq!(values.next(), None); + } + + #[test] + fn test_default_indices() { + let mut indices: Indices = Indices::default(); + assert_eq!(indices.next(), None); + } + + #[test] + fn test_default_indices_with_shorter_lifetime() { + let matches = ArgMatches::default(); + let mut indices = matches.indices_of("").unwrap_or_default(); + assert_eq!(indices.next(), None); + } + + #[test] + fn values_exact_size() { + let l = crate::Command::new("test") + .arg( + crate::Arg::new("POTATO") + .takes_value(true) + .multiple_values(true) + .required(true), + ) + .try_get_matches_from(["test", "one"]) + .unwrap() + .get_many::("POTATO") + .expect("present") + .count(); + assert_eq!(l, 1); + } + + #[test] + fn os_values_exact_size() { + let l = crate::Command::new("test") + .arg( + crate::Arg::new("POTATO") + .takes_value(true) + .multiple_values(true) + .value_parser(crate::builder::ValueParser::os_string()) + .required(true), + ) + .try_get_matches_from(["test", "one"]) + .unwrap() + .get_many::("POTATO") + .expect("present") + .count(); + assert_eq!(l, 1); + } + + #[test] + fn indices_exact_size() { + let l = crate::Command::new("test") + .arg( + crate::Arg::new("POTATO") + .takes_value(true) + .multiple_values(true) + .required(true), + ) + .try_get_matches_from(["test", "one"]) + .unwrap() + .indices_of("POTATO") + .expect("present") + .len(); + assert_eq!(l, 1); + } +} diff --git a/vendor/clap-3.2.20/src/parser/matches/matched_arg.rs b/vendor/clap-3.2.20/src/parser/matches/matched_arg.rs new file mode 100644 index 000000000..fde6d37f3 --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/matches/matched_arg.rs @@ -0,0 +1,240 @@ +// Std +use std::{ + ffi::{OsStr, OsString}, + iter::{Cloned, Flatten}, + slice::Iter, +}; + +use crate::builder::ArgPredicate; +use crate::parser::AnyValue; +use crate::parser::AnyValueId; +use crate::parser::ValueSource; +use crate::util::eq_ignore_case; +use crate::INTERNAL_ERROR_MSG; + +#[derive(Debug, Clone)] +pub(crate) struct MatchedArg { + occurs: u64, + source: Option, + indices: Vec, + type_id: Option, + vals: Vec>, + raw_vals: Vec>, + ignore_case: bool, +} + +impl MatchedArg { + pub(crate) fn new_arg(arg: &crate::Arg) -> Self { + let ignore_case = arg.is_ignore_case_set(); + Self { + occurs: 0, + source: None, + indices: Vec::new(), + type_id: Some(arg.get_value_parser().type_id()), + vals: Vec::new(), + raw_vals: Vec::new(), + ignore_case, + } + } + + pub(crate) fn new_group() -> Self { + let ignore_case = false; + Self { + occurs: 0, + source: None, + indices: Vec::new(), + type_id: None, + vals: Vec::new(), + raw_vals: Vec::new(), + ignore_case, + } + } + + pub(crate) fn new_external(cmd: &crate::Command) -> Self { + let ignore_case = false; + Self { + occurs: 0, + source: None, + indices: Vec::new(), + type_id: Some( + cmd.get_external_subcommand_value_parser() + .expect(INTERNAL_ERROR_MSG) + .type_id(), + ), + vals: Vec::new(), + raw_vals: Vec::new(), + ignore_case, + } + } + + #[cfg_attr(feature = "deprecated", deprecated(since = "3.2.0"))] + pub(crate) fn inc_occurrences(&mut self) { + self.occurs += 1; + } + + #[cfg_attr(feature = "deprecated", deprecated(since = "3.2.0"))] + pub(crate) fn set_occurrences(&mut self, occurs: u64) { + self.occurs = occurs + } + + #[cfg_attr(feature = "deprecated", deprecated(since = "3.2.0"))] + pub(crate) fn get_occurrences(&self) -> u64 { + self.occurs + } + + pub(crate) fn indices(&self) -> Cloned> { + self.indices.iter().cloned() + } + + pub(crate) fn get_index(&self, index: usize) -> Option { + self.indices.get(index).cloned() + } + + pub(crate) fn push_index(&mut self, index: usize) { + self.indices.push(index) + } + + #[cfg(feature = "unstable-grouped")] + pub(crate) fn vals(&self) -> Iter> { + self.vals.iter() + } + + pub(crate) fn vals_flatten(&self) -> Flatten>> { + self.vals.iter().flatten() + } + + pub(crate) fn into_vals_flatten(self) -> Flatten>> { + self.vals.into_iter().flatten() + } + + pub(crate) fn raw_vals_flatten(&self) -> Flatten>> { + self.raw_vals.iter().flatten() + } + + pub(crate) fn first(&self) -> Option<&AnyValue> { + self.vals_flatten().next() + } + + #[cfg(test)] + pub(crate) fn first_raw(&self) -> Option<&OsString> { + self.raw_vals_flatten().next() + } + + pub(crate) fn new_val_group(&mut self) { + self.vals.push(vec![]); + self.raw_vals.push(vec![]); + } + + pub(crate) fn append_val(&mut self, val: AnyValue, raw_val: OsString) { + // We assume there is always a group created before. + self.vals.last_mut().expect(INTERNAL_ERROR_MSG).push(val); + self.raw_vals + .last_mut() + .expect(INTERNAL_ERROR_MSG) + .push(raw_val); + } + + pub(crate) fn num_vals(&self) -> usize { + self.vals.iter().map(|v| v.len()).sum() + } + + // Will be used later + #[allow(dead_code)] + pub(crate) fn num_vals_last_group(&self) -> usize { + self.vals.last().map(|x| x.len()).unwrap_or(0) + } + + pub(crate) fn all_val_groups_empty(&self) -> bool { + self.vals.iter().flatten().count() == 0 + } + + pub(crate) fn check_explicit(&self, predicate: ArgPredicate) -> bool { + if self.source == Some(ValueSource::DefaultValue) { + return false; + } + + match predicate { + ArgPredicate::Equals(val) => self.raw_vals_flatten().any(|v| { + if self.ignore_case { + // If `v` isn't utf8, it can't match `val`, so `OsStr::to_str` should be fine + eq_ignore_case(&v.to_string_lossy(), &val.to_string_lossy()) + } else { + OsString::as_os_str(v) == OsStr::new(val) + } + }), + ArgPredicate::IsPresent => true, + } + } + + pub(crate) fn source(&self) -> Option { + self.source + } + + pub(crate) fn set_source(&mut self, source: ValueSource) { + if let Some(existing) = self.source { + self.source = Some(existing.max(source)); + } else { + self.source = Some(source) + } + } + + pub(crate) fn type_id(&self) -> Option { + self.type_id + } + + pub(crate) fn infer_type_id(&self, expected: AnyValueId) -> AnyValueId { + self.type_id() + .or_else(|| { + self.vals_flatten() + .map(|v| v.type_id()) + .find(|actual| *actual != expected) + }) + .unwrap_or(expected) + } +} + +impl PartialEq for MatchedArg { + fn eq(&self, other: &MatchedArg) -> bool { + let MatchedArg { + occurs: self_occurs, + source: self_source, + indices: self_indices, + type_id: self_type_id, + vals: _, + raw_vals: self_raw_vals, + ignore_case: self_ignore_case, + } = self; + let MatchedArg { + occurs: other_occurs, + source: other_source, + indices: other_indices, + type_id: other_type_id, + vals: _, + raw_vals: other_raw_vals, + ignore_case: other_ignore_case, + } = other; + self_occurs == other_occurs + && self_source == other_source + && self_indices == other_indices + && self_type_id == other_type_id + && self_raw_vals == other_raw_vals + && self_ignore_case == other_ignore_case + } +} + +impl Eq for MatchedArg {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_grouped_vals_first() { + let mut m = MatchedArg::new_group(); + m.new_val_group(); + m.new_val_group(); + m.append_val(AnyValue::new(String::from("bbb")), "bbb".into()); + m.append_val(AnyValue::new(String::from("ccc")), "ccc".into()); + assert_eq!(m.first_raw(), Some(&OsString::from("bbb"))); + } +} diff --git a/vendor/clap-3.2.20/src/parser/matches/mod.rs b/vendor/clap-3.2.20/src/parser/matches/mod.rs new file mode 100644 index 000000000..7b88eeca7 --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/matches/mod.rs @@ -0,0 +1,17 @@ +mod any_value; +mod arg_matches; +mod matched_arg; +mod value_source; + +pub use any_value::AnyValueId; +pub use arg_matches::RawValues; +pub use arg_matches::ValuesRef; +pub use arg_matches::{ArgMatches, Indices}; +pub use value_source::ValueSource; + +pub(crate) use any_value::AnyValue; +pub(crate) use arg_matches::SubCommand; +pub(crate) use matched_arg::MatchedArg; + +#[allow(deprecated)] +pub use arg_matches::{OsValues, Values}; diff --git a/vendor/clap-3.2.20/src/parser/matches/value_source.rs b/vendor/clap-3.2.20/src/parser/matches/value_source.rs new file mode 100644 index 000000000..fb762d2af --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/matches/value_source.rs @@ -0,0 +1,11 @@ +/// Origin of the argument's value +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[non_exhaustive] +pub enum ValueSource { + /// Value came [`Arg::default_value`][crate::Arg::default_value] + DefaultValue, + /// Value came [`Arg::env`][crate::Arg::env] + EnvVariable, + /// Value was passed in on the command-line + CommandLine, +} diff --git a/vendor/clap-3.2.20/src/parser/mod.rs b/vendor/clap-3.2.20/src/parser/mod.rs new file mode 100644 index 000000000..da81648e1 --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/mod.rs @@ -0,0 +1,27 @@ +//! [`Command`][crate::Command] line argument parser + +mod arg_matcher; +mod error; +mod matches; +#[allow(clippy::module_inception)] +mod parser; +mod validator; + +pub(crate) mod features; + +pub(crate) use self::arg_matcher::ArgMatcher; +pub(crate) use self::matches::AnyValue; +pub(crate) use self::matches::AnyValueId; +pub(crate) use self::matches::{MatchedArg, SubCommand}; +pub(crate) use self::parser::Identifier; +pub(crate) use self::parser::PendingArg; +pub(crate) use self::parser::{ParseState, Parser}; +pub(crate) use self::validator::Validator; + +pub use self::matches::RawValues; +pub use self::matches::ValuesRef; +pub use self::matches::{ArgMatches, Indices, ValueSource}; +pub use error::MatchesError; + +#[allow(deprecated)] +pub use self::matches::{OsValues, Values}; diff --git a/vendor/clap-3.2.20/src/parser/parser.rs b/vendor/clap-3.2.20/src/parser/parser.rs new file mode 100644 index 000000000..ad2bc6e9c --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/parser.rs @@ -0,0 +1,1729 @@ +// Std +use std::{ + cell::Cell, + ffi::{OsStr, OsString}, +}; + +// Third Party +use clap_lex::RawOsStr; + +// Internal +use crate::builder::AppSettings as AS; +use crate::builder::{Arg, Command}; +use crate::error::Error as ClapError; +use crate::error::Result as ClapResult; +use crate::mkeymap::KeyType; +use crate::output::fmt::Stream; +use crate::output::{fmt::Colorizer, Usage}; +use crate::parser::features::suggestions; +use crate::parser::{ArgMatcher, SubCommand}; +use crate::parser::{Validator, ValueSource}; +use crate::util::Id; +use crate::ArgAction; +use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8}; + +pub(crate) struct Parser<'help, 'cmd> { + cmd: &'cmd mut Command<'help>, + cur_idx: Cell, + /// Index of the previous flag subcommand in a group of flags. + flag_subcmd_at: Option, + /// Counter indicating the number of items to skip + /// when revisiting the group of flags which includes the flag subcommand. + flag_subcmd_skip: usize, +} + +// Initializing Methods +impl<'help, 'cmd> Parser<'help, 'cmd> { + pub(crate) fn new(cmd: &'cmd mut Command<'help>) -> Self { + Parser { + cmd, + cur_idx: Cell::new(0), + flag_subcmd_at: None, + flag_subcmd_skip: 0, + } + } +} + +// Parsing Methods +impl<'help, 'cmd> Parser<'help, 'cmd> { + // The actual parsing function + #[allow(clippy::cognitive_complexity)] + pub(crate) fn get_matches_with( + &mut self, + matcher: &mut ArgMatcher, + raw_args: &mut clap_lex::RawArgs, + mut args_cursor: clap_lex::ArgCursor, + ) -> ClapResult<()> { + debug!("Parser::get_matches_with"); + // Verify all positional assertions pass + + let mut subcmd_name: Option = None; + let mut keep_state = false; + let mut parse_state = ParseState::ValuesDone; + let mut pos_counter = 1; + + // Already met any valid arg(then we shouldn't expect subcommands after it). + let mut valid_arg_found = false; + // If the user already passed '--'. Meaning only positional args follow. + let mut trailing_values = false; + + // Count of positional args + let positional_count = self + .cmd + .get_keymap() + .keys() + .filter(|x| x.is_position()) + .count(); + // If any arg sets .last(true) + let contains_last = self.cmd.get_arguments().any(|x| x.is_last_set()); + + while let Some(arg_os) = raw_args.next(&mut args_cursor) { + // Recover the replaced items if any. + if let Some(replaced_items) = arg_os + .to_value() + .ok() + .and_then(|a| self.cmd.get_replacement(a)) + { + debug!( + "Parser::get_matches_with: found replacer: {:?}, target: {:?}", + arg_os, replaced_items + ); + raw_args.insert(&args_cursor, replaced_items); + continue; + } + + debug!( + "Parser::get_matches_with: Begin parsing '{:?}' ({:?})", + arg_os.to_value_os(), + arg_os.to_value_os().as_raw_bytes() + ); + + // Has the user already passed '--'? Meaning only positional args follow + if !trailing_values { + if self.cmd.is_subcommand_precedence_over_arg_set() + || !matches!(parse_state, ParseState::Opt(_) | ParseState::Pos(_)) + { + // Does the arg match a subcommand name, or any of its aliases (if defined) + let sc_name = self.possible_subcommand(arg_os.to_value(), valid_arg_found); + debug!("Parser::get_matches_with: sc={:?}", sc_name); + if let Some(sc_name) = sc_name { + #[allow(deprecated)] + if sc_name == "help" + && !self.is_set(AS::NoAutoHelp) + && !self.cmd.is_disable_help_subcommand_set() + { + self.parse_help_subcommand(raw_args.remaining(&mut args_cursor))?; + unreachable!("`parse_help_subcommand` always errors"); + } else { + subcmd_name = Some(sc_name.to_owned()); + } + break; + } + } + + if arg_os.is_escape() { + if matches!(&parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if + self.cmd[opt].is_allow_hyphen_values_set()) + { + // ParseResult::MaybeHyphenValue, do nothing + } else { + debug!("Parser::get_matches_with: setting TrailingVals=true"); + trailing_values = true; + continue; + } + } else if let Some((long_arg, long_value)) = arg_os.to_long() { + let parse_result = self.parse_long_arg( + matcher, + long_arg, + long_value, + &parse_state, + &mut valid_arg_found, + trailing_values, + )?; + debug!( + "Parser::get_matches_with: After parse_long_arg {:?}", + parse_result + ); + match parse_result { + ParseResult::NoArg => { + unreachable!("`to_long` always has the flag specified") + } + ParseResult::ValuesDone => { + parse_state = ParseState::ValuesDone; + continue; + } + ParseResult::Opt(id) => { + parse_state = ParseState::Opt(id); + continue; + } + ParseResult::FlagSubCommand(name) => { + debug!( + "Parser::get_matches_with: FlagSubCommand found in long arg {:?}", + &name + ); + subcmd_name = Some(name); + break; + } + ParseResult::EqualsNotProvided { arg } => { + let _ = self.resolve_pending(matcher); + return Err(ClapError::no_equals( + self.cmd, + arg, + Usage::new(self.cmd).create_usage_with_title(&[]), + )); + } + ParseResult::NoMatchingArg { arg } => { + let _ = self.resolve_pending(matcher); + let remaining_args: Vec<_> = raw_args + .remaining(&mut args_cursor) + .map(|x| x.to_str().expect(INVALID_UTF8)) + .collect(); + return Err(self.did_you_mean_error(&arg, matcher, &remaining_args)); + } + ParseResult::UnneededAttachedValue { rest, used, arg } => { + let _ = self.resolve_pending(matcher); + return Err(ClapError::too_many_values( + self.cmd, + rest, + arg, + Usage::new(self.cmd).create_usage_no_title(&used), + )); + } + ParseResult::MaybeHyphenValue => { + // Maybe a hyphen value, do nothing. + } + ParseResult::AttachedValueNotConsumed => { + unreachable!() + } + } + } else if let Some(short_arg) = arg_os.to_short() { + // Arg looks like a short flag, and not a possible number + + // Try to parse short args like normal, if allow_hyphen_values or + // AllowNegativeNumbers is set, parse_short_arg will *not* throw + // an error, and instead return Ok(None) + let parse_result = self.parse_short_arg( + matcher, + short_arg, + &parse_state, + pos_counter, + &mut valid_arg_found, + trailing_values, + )?; + // If it's None, we then check if one of those two AppSettings was set + debug!( + "Parser::get_matches_with: After parse_short_arg {:?}", + parse_result + ); + match parse_result { + ParseResult::NoArg => { + // Is a single dash `-`, try positional. + } + ParseResult::ValuesDone => { + parse_state = ParseState::ValuesDone; + continue; + } + ParseResult::Opt(id) => { + parse_state = ParseState::Opt(id); + continue; + } + ParseResult::FlagSubCommand(name) => { + // If there are more short flags to be processed, we should keep the state, and later + // revisit the current group of short flags skipping the subcommand. + keep_state = self + .flag_subcmd_at + .map(|at| { + raw_args + .seek(&mut args_cursor, clap_lex::SeekFrom::Current(-1)); + // Since we are now saving the current state, the number of flags to skip during state recovery should + // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position. + self.flag_subcmd_skip = self.cur_idx.get() - at + 1; + }) + .is_some(); + + debug!( + "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}", + name, + keep_state, + self.flag_subcmd_skip + ); + + subcmd_name = Some(name); + break; + } + ParseResult::EqualsNotProvided { arg } => { + let _ = self.resolve_pending(matcher); + return Err(ClapError::no_equals( + self.cmd, + arg, + Usage::new(self.cmd).create_usage_with_title(&[]), + )); + } + ParseResult::NoMatchingArg { arg } => { + let _ = self.resolve_pending(matcher); + return Err(ClapError::unknown_argument( + self.cmd, + arg, + None, + Usage::new(self.cmd).create_usage_with_title(&[]), + )); + } + ParseResult::MaybeHyphenValue => { + // Maybe a hyphen value, do nothing. + } + ParseResult::UnneededAttachedValue { .. } + | ParseResult::AttachedValueNotConsumed => unreachable!(), + } + } + + if let ParseState::Opt(id) = &parse_state { + // Assume this is a value of a previous arg. + + // get the option so we can check the settings + let arg_values = matcher.pending_values_mut(id, None); + let arg = &self.cmd[id]; + let parse_result = self.split_arg_values( + arg, + arg_os.to_value_os(), + trailing_values, + arg_values, + ); + let parse_result = parse_result.unwrap_or_else(|| { + if matcher.needs_more_vals(arg) { + ParseResult::Opt(arg.id.clone()) + } else { + ParseResult::ValuesDone + } + }); + parse_state = match parse_result { + ParseResult::Opt(id) => ParseState::Opt(id), + ParseResult::ValuesDone => ParseState::ValuesDone, + _ => unreachable!(), + }; + // get the next value from the iterator + continue; + } + } + + // Correct pos_counter. + pos_counter = { + let is_second_to_last = pos_counter + 1 == positional_count; + + // The last positional argument, or second to last positional + // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)` + let low_index_mults = is_second_to_last + && self + .cmd + .get_positionals() + .any(|a| a.is_multiple() && (positional_count != a.index.unwrap_or(0))) + && self + .cmd + .get_positionals() + .last() + .map_or(false, |p_name| !p_name.is_last_set()); + + let missing_pos = self.cmd.is_allow_missing_positional_set() + && is_second_to_last + && !trailing_values; + + debug!( + "Parser::get_matches_with: Positional counter...{}", + pos_counter + ); + debug!( + "Parser::get_matches_with: Low index multiples...{:?}", + low_index_mults + ); + + if low_index_mults || missing_pos { + let skip_current = if let Some(n) = raw_args.peek(&args_cursor) { + if let Some(arg) = self + .cmd + .get_positionals() + .find(|a| a.index == Some(pos_counter)) + { + // If next value looks like a new_arg or it's a + // subcommand, skip positional argument under current + // pos_counter(which means current value cannot be a + // positional argument with a value next to it), assume + // current value matches the next arg. + self.is_new_arg(&n, arg) + || self + .possible_subcommand(n.to_value(), valid_arg_found) + .is_some() + } else { + true + } + } else { + true + }; + + if skip_current { + debug!("Parser::get_matches_with: Bumping the positional counter..."); + pos_counter + 1 + } else { + pos_counter + } + } else if trailing_values + && (self.cmd.is_allow_missing_positional_set() || contains_last) + { + // Came to -- and one positional has .last(true) set, so we go immediately + // to the last (highest index) positional + debug!("Parser::get_matches_with: .last(true) and --, setting last pos"); + positional_count + } else { + pos_counter + } + }; + + if let Some(arg) = self.cmd.get_keymap().get(&pos_counter) { + if arg.is_last_set() && !trailing_values { + let _ = self.resolve_pending(matcher); + return Err(ClapError::unknown_argument( + self.cmd, + arg_os.display().to_string(), + None, + Usage::new(self.cmd).create_usage_with_title(&[]), + )); + } + + if self.cmd.is_trailing_var_arg_set() && pos_counter == positional_count { + trailing_values = true; + } + + if matcher.pending_arg_id() != Some(&arg.id) || !arg.is_multiple_values_set() { + self.resolve_pending(matcher)?; + } + let arg_values = matcher.pending_values_mut(&arg.id, Some(Identifier::Index)); + let _parse_result = + self.split_arg_values(arg, arg_os.to_value_os(), trailing_values, arg_values); + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!( + "Parser::get_matches_with: Ignoring state {:?}; positionals do their own thing", + _parse_result + ); + } + } + + // Only increment the positional counter if it doesn't allow multiples + if !arg.is_multiple() { + pos_counter += 1; + parse_state = ParseState::ValuesDone; + } else { + parse_state = ParseState::Pos(arg.id.clone()); + } + valid_arg_found = true; + } else if let Some(external_parser) = + self.cmd.get_external_subcommand_value_parser().cloned() + { + // Get external subcommand name + let sc_name = match arg_os.to_value() { + Ok(s) => s.to_string(), + Err(_) => { + let _ = self.resolve_pending(matcher); + return Err(ClapError::invalid_utf8( + self.cmd, + Usage::new(self.cmd).create_usage_with_title(&[]), + )); + } + }; + + // Collect the external subcommand args + let mut sc_m = ArgMatcher::new(self.cmd); + if cfg!(feature = "unstable-v4") || !raw_args.is_end(&args_cursor) { + sc_m.start_occurrence_of_external(self.cmd); + } + + for raw_val in raw_args.remaining(&mut args_cursor) { + let val = external_parser.parse_ref(self.cmd, None, raw_val)?; + let external_id = &Id::empty_hash(); + sc_m.add_val_to(external_id, val, raw_val.to_os_string()); + } + + matcher.subcommand(SubCommand { + id: Id::from(&*sc_name), + name: sc_name, + matches: sc_m.into_inner(), + }); + + self.resolve_pending(matcher)?; + #[cfg(feature = "env")] + self.add_env(matcher)?; + self.add_defaults(matcher)?; + return Validator::new(self.cmd).validate(parse_state, matcher); + } else { + // Start error processing + let _ = self.resolve_pending(matcher); + return Err(self.match_arg_error(&arg_os, valid_arg_found, trailing_values)); + } + } + + if let Some(ref pos_sc_name) = subcmd_name { + let sc_name = self + .cmd + .find_subcommand(pos_sc_name) + .expect(INTERNAL_ERROR_MSG) + .get_name() + .to_owned(); + self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state)?; + } + + self.resolve_pending(matcher)?; + #[cfg(feature = "env")] + self.add_env(matcher)?; + self.add_defaults(matcher)?; + Validator::new(self.cmd).validate(parse_state, matcher) + } + + fn match_arg_error( + &self, + arg_os: &clap_lex::ParsedArg<'_>, + valid_arg_found: bool, + trailing_values: bool, + ) -> ClapError { + // If argument follows a `--` + if trailing_values { + // If the arg matches a subcommand name, or any of its aliases (if defined) + if self + .possible_subcommand(arg_os.to_value(), valid_arg_found) + .is_some() + { + return ClapError::unnecessary_double_dash( + self.cmd, + arg_os.display().to_string(), + Usage::new(self.cmd).create_usage_with_title(&[]), + ); + } + } + let candidates = suggestions::did_you_mean( + &arg_os.display().to_string(), + self.cmd.all_subcommand_names(), + ); + // If the argument looks like a subcommand. + if !candidates.is_empty() { + let candidates: Vec<_> = candidates + .iter() + .map(|candidate| format!("'{}'", candidate)) + .collect(); + return ClapError::invalid_subcommand( + self.cmd, + arg_os.display().to_string(), + candidates.join(" or "), + self.cmd + .get_bin_name() + .unwrap_or_else(|| self.cmd.get_name()) + .to_owned(), + Usage::new(self.cmd).create_usage_with_title(&[]), + ); + } + // If the argument must be a subcommand. + if !self.cmd.has_args() || self.cmd.is_infer_subcommands_set() && self.cmd.has_subcommands() + { + return ClapError::unrecognized_subcommand( + self.cmd, + arg_os.display().to_string(), + Usage::new(self.cmd).create_usage_with_title(&[]), + ); + } + ClapError::unknown_argument( + self.cmd, + arg_os.display().to_string(), + None, + Usage::new(self.cmd).create_usage_with_title(&[]), + ) + } + + // Checks if the arg matches a subcommand name, or any of its aliases (if defined) + fn possible_subcommand( + &self, + arg: Result<&str, &RawOsStr>, + valid_arg_found: bool, + ) -> Option<&str> { + debug!("Parser::possible_subcommand: arg={:?}", arg); + let arg = arg.ok()?; + + if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) { + if self.cmd.is_infer_subcommands_set() { + // For subcommand `test`, we accepts it's prefix: `t`, `te`, + // `tes` and `test`. + let v = self + .cmd + .all_subcommand_names() + .filter(|s| s.starts_with(arg)) + .collect::>(); + + if v.len() == 1 { + return Some(v[0]); + } + + // If there is any ambiguity, fallback to non-infer subcommand + // search. + } + if let Some(sc) = self.cmd.find_subcommand(arg) { + return Some(sc.get_name()); + } + } + None + } + + // Checks if the arg matches a long flag subcommand name, or any of its aliases (if defined) + fn possible_long_flag_subcommand(&self, arg: &str) -> Option<&str> { + debug!("Parser::possible_long_flag_subcommand: arg={:?}", arg); + if self.cmd.is_infer_subcommands_set() { + let options = self + .cmd + .get_subcommands() + .fold(Vec::new(), |mut options, sc| { + if let Some(long) = sc.get_long_flag() { + if long.starts_with(arg) { + options.push(long); + } + options.extend(sc.get_all_aliases().filter(|alias| alias.starts_with(arg))) + } + options + }); + if options.len() == 1 { + return Some(options[0]); + } + + for sc in options { + if sc == arg { + return Some(sc); + } + } + } else if let Some(sc_name) = self.cmd.find_long_subcmd(arg) { + return Some(sc_name); + } + None + } + + fn parse_help_subcommand( + &self, + cmds: impl Iterator, + ) -> ClapResult { + debug!("Parser::parse_help_subcommand"); + + let mut cmd = self.cmd.clone(); + let sc = { + let mut sc = &mut cmd; + + for cmd in cmds { + sc = if let Some(sc_name) = + sc.find_subcommand(cmd).map(|sc| sc.get_name().to_owned()) + { + sc._build_subcommand(&sc_name).unwrap() + } else { + return Err(ClapError::unrecognized_subcommand( + sc, + cmd.to_string_lossy().into_owned(), + Usage::new(sc).create_usage_with_title(&[]), + )); + }; + } + + sc + }; + let parser = Parser::new(sc); + + Err(parser.help_err(true, Stream::Stdout)) + } + + fn is_new_arg(&self, next: &clap_lex::ParsedArg<'_>, current_positional: &Arg) -> bool { + #![allow(clippy::needless_bool)] // Prefer consistent if/else-if ladder + + debug!( + "Parser::is_new_arg: {:?}:{:?}", + next.to_value_os(), + current_positional.name + ); + + if self.cmd.is_allow_hyphen_values_set() + || self.cmd[¤t_positional.id].is_allow_hyphen_values_set() + || (self.cmd.is_allow_negative_numbers_set() && next.is_number()) + { + // If allow hyphen, this isn't a new arg. + debug!("Parser::is_new_arg: Allow hyphen"); + false + } else if next.is_long() { + // If this is a long flag, this is a new arg. + debug!("Parser::is_new_arg: -- found"); + true + } else if next.is_short() { + // If this is a short flag, this is a new arg. But a singe '-' by + // itself is a value and typically means "stdin" on unix systems. + debug!("Parser::is_new_arg: - found"); + true + } else { + // Nothing special, this is a value. + debug!("Parser::is_new_arg: value"); + false + } + } + + fn parse_subcommand( + &mut self, + sc_name: &str, + matcher: &mut ArgMatcher, + raw_args: &mut clap_lex::RawArgs, + args_cursor: clap_lex::ArgCursor, + keep_state: bool, + ) -> ClapResult<()> { + debug!("Parser::parse_subcommand"); + + let partial_parsing_enabled = self.cmd.is_ignore_errors_set(); + + if let Some(sc) = self.cmd._build_subcommand(sc_name) { + let mut sc_matcher = ArgMatcher::new(sc); + + debug!( + "Parser::parse_subcommand: About to parse sc={}", + sc.get_name() + ); + + { + let mut p = Parser::new(sc); + // HACK: maintain indexes between parsers + // FlagSubCommand short arg needs to revisit the current short args, but skip the subcommand itself + if keep_state { + p.cur_idx.set(self.cur_idx.get()); + p.flag_subcmd_at = self.flag_subcmd_at; + p.flag_subcmd_skip = self.flag_subcmd_skip; + } + if let Err(error) = p.get_matches_with(&mut sc_matcher, raw_args, args_cursor) { + if partial_parsing_enabled { + debug!( + "Parser::parse_subcommand: ignored error in subcommand {}: {:?}", + sc_name, error + ); + } else { + return Err(error); + } + } + } + matcher.subcommand(SubCommand { + id: sc.get_id(), + name: sc.get_name().to_owned(), + matches: sc_matcher.into_inner(), + }); + } + Ok(()) + } + + fn parse_long_arg( + &mut self, + matcher: &mut ArgMatcher, + long_arg: Result<&str, &RawOsStr>, + long_value: Option<&RawOsStr>, + parse_state: &ParseState, + valid_arg_found: &mut bool, + trailing_values: bool, + ) -> ClapResult { + // maybe here lifetime should be 'a + debug!("Parser::parse_long_arg"); + + if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if + self.cmd[opt].is_allow_hyphen_values_set()) + { + return Ok(ParseResult::MaybeHyphenValue); + } + + debug!("Parser::parse_long_arg: Does it contain '='..."); + let long_arg = match long_arg { + Ok(long_arg) => long_arg, + Err(long_arg) => { + return Ok(ParseResult::NoMatchingArg { + arg: long_arg.to_str_lossy().into_owned(), + }); + } + }; + if long_arg.is_empty() { + debug_assert!( + long_value.is_some(), + "`--` should be filtered out before this point" + ); + } + + let arg = if let Some(arg) = self.cmd.get_keymap().get(long_arg) { + debug!( + "Parser::parse_long_arg: Found valid arg or flag '{}'", + arg.to_string() + ); + Some((long_arg, arg)) + } else if self.cmd.is_infer_long_args_set() { + self.cmd.get_arguments().find_map(|a| { + if let Some(long) = a.long { + if long.starts_with(long_arg) { + return Some((long, a)); + } + } + a.aliases + .iter() + .find_map(|(alias, _)| alias.starts_with(long_arg).then(|| (*alias, a))) + }) + } else { + None + }; + + if let Some((_long_arg, arg)) = arg { + let ident = Identifier::Long; + *valid_arg_found = true; + if arg.is_takes_value_set() { + debug!( + "Parser::parse_long_arg({:?}): Found an arg with value '{:?}'", + long_arg, &long_value + ); + let has_eq = long_value.is_some(); + self.parse_opt_value(ident, long_value, arg, matcher, trailing_values, has_eq) + } else if let Some(rest) = long_value { + let required = self.cmd.required_graph(); + debug!( + "Parser::parse_long_arg({:?}): Got invalid literal `{:?}`", + long_arg, rest + ); + let used: Vec = matcher + .arg_ids() + .filter(|arg_id| { + matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) + }) + .filter(|&n| { + self.cmd + .find(n) + .map_or(true, |a| !(a.is_hide_set() || required.contains(&a.id))) + }) + .cloned() + .collect(); + + Ok(ParseResult::UnneededAttachedValue { + rest: rest.to_str_lossy().into_owned(), + used, + arg: arg.to_string(), + }) + } else { + debug!("Parser::parse_long_arg({:?}): Presence validated", long_arg); + self.react(Some(ident), ValueSource::CommandLine, arg, vec![], matcher) + } + } else if let Some(sc_name) = self.possible_long_flag_subcommand(long_arg) { + Ok(ParseResult::FlagSubCommand(sc_name.to_string())) + } else if self.cmd.is_allow_hyphen_values_set() { + Ok(ParseResult::MaybeHyphenValue) + } else { + Ok(ParseResult::NoMatchingArg { + arg: long_arg.to_owned(), + }) + } + } + + fn parse_short_arg( + &mut self, + matcher: &mut ArgMatcher, + mut short_arg: clap_lex::ShortFlags<'_>, + parse_state: &ParseState, + // change this to possible pos_arg when removing the usage of &mut Parser. + pos_counter: usize, + valid_arg_found: &mut bool, + trailing_values: bool, + ) -> ClapResult { + debug!("Parser::parse_short_arg: short_arg={:?}", short_arg); + + #[allow(clippy::blocks_in_if_conditions)] + if self.cmd.is_allow_negative_numbers_set() && short_arg.is_number() { + debug!("Parser::parse_short_arg: negative number"); + return Ok(ParseResult::MaybeHyphenValue); + } else if self.cmd.is_allow_hyphen_values_set() + && short_arg + .clone() + .any(|c| !c.map(|c| self.cmd.contains_short(c)).unwrap_or_default()) + { + debug!("Parser::parse_short_args: contains non-short flag"); + return Ok(ParseResult::MaybeHyphenValue); + } else if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) + if self.cmd[opt].is_allow_hyphen_values_set()) + { + debug!("Parser::parse_short_args: prior arg accepts hyphenated values",); + return Ok(ParseResult::MaybeHyphenValue); + } else if self + .cmd + .get_keymap() + .get(&pos_counter) + .map_or(false, |arg| { + arg.is_allow_hyphen_values_set() && !arg.is_last_set() + }) + { + debug!( + "Parser::parse_short_args: positional at {} allows hyphens", + pos_counter + ); + return Ok(ParseResult::MaybeHyphenValue); + } + + let mut ret = ParseResult::NoArg; + + let skip = self.flag_subcmd_skip; + self.flag_subcmd_skip = 0; + let res = short_arg.advance_by(skip); + debug_assert_eq!( + res, + Ok(()), + "tracking of `flag_subcmd_skip` is off for `{:?}`", + short_arg + ); + while let Some(c) = short_arg.next_flag() { + let c = match c { + Ok(c) => c, + Err(rest) => { + return Ok(ParseResult::NoMatchingArg { + arg: format!("-{}", rest.to_str_lossy()), + }); + } + }; + debug!("Parser::parse_short_arg:iter:{}", c); + + // Check for matching short options, and return the name if there is no trailing + // concatenated value: -oval + // Option: -o + // Value: val + if let Some(arg) = self.cmd.get_keymap().get(&c) { + let ident = Identifier::Short; + debug!( + "Parser::parse_short_arg:iter:{}: Found valid opt or flag", + c + ); + *valid_arg_found = true; + if !arg.is_takes_value_set() { + ret = + self.react(Some(ident), ValueSource::CommandLine, arg, vec![], matcher)?; + continue; + } + + // Check for trailing concatenated value + // + // Cloning the iterator, so we rollback if it isn't there. + let val = short_arg.clone().next_value_os().unwrap_or_default(); + debug!( + "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii), short_arg={:?}", + c, val, val.as_raw_bytes(), short_arg + ); + let val = Some(val).filter(|v| !v.is_empty()); + + // Default to "we're expecting a value later". + // + // If attached value is not consumed, we may have more short + // flags to parse, continue. + // + // e.g. `-xvf`, when require_equals && x.min_vals == 0, we don't + // consume the `vf`, even if it's provided as value. + let (val, has_eq) = if let Some(val) = val.and_then(|v| v.strip_prefix('=')) { + (Some(val), true) + } else { + (val, false) + }; + match self.parse_opt_value(ident, val, arg, matcher, trailing_values, has_eq)? { + ParseResult::AttachedValueNotConsumed => continue, + x => return Ok(x), + } + } + + return if let Some(sc_name) = self.cmd.find_short_subcmd(c) { + debug!("Parser::parse_short_arg:iter:{}: subcommand={}", c, sc_name); + // Make sure indices get updated before reading `self.cur_idx` + self.resolve_pending(matcher)?; + self.cur_idx.set(self.cur_idx.get() + 1); + debug!("Parser::parse_short_arg: cur_idx:={}", self.cur_idx.get()); + + let name = sc_name.to_string(); + // Get the index of the previously saved flag subcommand in the group of flags (if exists). + // If it is a new flag subcommand, then the formentioned index should be the current one + // (ie. `cur_idx`), and should be registered. + let cur_idx = self.cur_idx.get(); + self.flag_subcmd_at.get_or_insert(cur_idx); + let done_short_args = short_arg.is_empty(); + if done_short_args { + self.flag_subcmd_at = None; + } + Ok(ParseResult::FlagSubCommand(name)) + } else { + Ok(ParseResult::NoMatchingArg { + arg: format!("-{}", c), + }) + }; + } + Ok(ret) + } + + fn parse_opt_value( + &self, + ident: Identifier, + attached_value: Option<&RawOsStr>, + arg: &Arg<'help>, + matcher: &mut ArgMatcher, + trailing_values: bool, + has_eq: bool, + ) -> ClapResult { + debug!( + "Parser::parse_opt_value; arg={}, val={:?}, has_eq={:?}", + arg.name, attached_value, has_eq + ); + debug!("Parser::parse_opt_value; arg.settings={:?}", arg.settings); + + debug!("Parser::parse_opt_value; Checking for val..."); + // require_equals is set, but no '=' is provided, try throwing error. + if arg.is_require_equals_set() && !has_eq { + if arg.min_vals == Some(0) { + debug!("Requires equals, but min_vals == 0"); + let mut arg_values = Vec::new(); + // We assume this case is valid: require equals, but min_vals == 0. + if !arg.default_missing_vals.is_empty() { + debug!("Parser::parse_opt_value: has default_missing_vals"); + for v in arg.default_missing_vals.iter() { + let trailing_values = false; // CLI should not be affecting default_missing_values + let _parse_result = self.split_arg_values( + arg, + &RawOsStr::new(v), + trailing_values, + &mut arg_values, + ); + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!("Parser::parse_opt_value: Ignoring state {:?}; no values accepted after default_missing_values", _parse_result); + } + } + } + }; + let react_result = self.react( + Some(ident), + ValueSource::CommandLine, + arg, + arg_values, + matcher, + )?; + debug_assert_eq!(react_result, ParseResult::ValuesDone); + if attached_value.is_some() { + Ok(ParseResult::AttachedValueNotConsumed) + } else { + Ok(ParseResult::ValuesDone) + } + } else { + debug!("Requires equals but not provided. Error."); + Ok(ParseResult::EqualsNotProvided { + arg: arg.to_string(), + }) + } + } else if let Some(v) = attached_value { + let mut arg_values = Vec::new(); + let parse_result = self.split_arg_values(arg, v, trailing_values, &mut arg_values); + let react_result = self.react( + Some(ident), + ValueSource::CommandLine, + arg, + arg_values, + matcher, + )?; + debug_assert_eq!(react_result, ParseResult::ValuesDone); + let mut parse_result = parse_result.unwrap_or_else(|| { + if matcher.needs_more_vals(arg) { + ParseResult::Opt(arg.id.clone()) + } else { + ParseResult::ValuesDone + } + }); + if parse_result != ParseResult::ValuesDone { + debug!("Parser::parse_opt_value: Overriding state {:?}; no values accepted after attached", parse_result); + parse_result = ParseResult::ValuesDone; + } + Ok(parse_result) + } else { + debug!("Parser::parse_opt_value: More arg vals required..."); + self.resolve_pending(matcher)?; + matcher.pending_values_mut(&arg.id, Some(ident)); + Ok(ParseResult::Opt(arg.id.clone())) + } + } + + fn split_arg_values( + &self, + arg: &Arg<'help>, + val: &RawOsStr, + trailing_values: bool, + output: &mut Vec, + ) -> Option { + debug!("Parser::split_arg_values; arg={}, val={:?}", arg.name, val); + debug!( + "Parser::split_arg_values; trailing_values={:?}, DontDelimTrailingVals={:?}", + trailing_values, + self.cmd.is_dont_delimit_trailing_values_set() + ); + + let mut delim = arg.val_delim; + if trailing_values && self.cmd.is_dont_delimit_trailing_values_set() { + delim = None; + } + match delim { + Some(delim) if val.contains(delim) => { + let vals = val.split(delim).map(|x| x.to_os_str().into_owned()); + for raw_val in vals { + if Some(raw_val.as_os_str()) == arg.terminator.map(OsStr::new) { + return Some(ParseResult::ValuesDone); + } + output.push(raw_val); + } + // Delimited values are always considered the final value + Some(ParseResult::ValuesDone) + } + _ if Some(val) == arg.terminator.map(RawOsStr::from_str) => { + Some(ParseResult::ValuesDone) + } + _ => { + output.push(val.to_os_str().into_owned()); + if arg.is_require_value_delimiter_set() { + Some(ParseResult::ValuesDone) + } else { + None + } + } + } + } + + fn push_arg_values( + &self, + arg: &Arg<'help>, + raw_vals: Vec, + matcher: &mut ArgMatcher, + ) -> ClapResult<()> { + debug!("Parser::push_arg_values: {:?}", raw_vals); + + for raw_val in raw_vals { + // update the current index because each value is a distinct index to clap + self.cur_idx.set(self.cur_idx.get() + 1); + debug!( + "Parser::add_single_val_to_arg: cur_idx:={}", + self.cur_idx.get() + ); + let value_parser = arg.get_value_parser(); + let val = value_parser.parse_ref(self.cmd, Some(arg), &raw_val)?; + + // Increment or create the group "args" + for group in self.cmd.groups_for_arg(&arg.id) { + matcher.add_val_to(&group, val.clone(), raw_val.clone()); + } + + matcher.add_val_to(&arg.id, val, raw_val); + matcher.add_index_to(&arg.id, self.cur_idx.get()); + } + + Ok(()) + } + + fn resolve_pending(&self, matcher: &mut ArgMatcher) -> ClapResult<()> { + let pending = match matcher.take_pending() { + Some(pending) => pending, + None => { + return Ok(()); + } + }; + + debug!("Parser::resolve_pending: id={:?}", pending.id); + let arg = self.cmd.find(&pending.id).expect(INTERNAL_ERROR_MSG); + let _ = self.react( + pending.ident, + ValueSource::CommandLine, + arg, + pending.raw_vals, + matcher, + )?; + + Ok(()) + } + + fn react( + &self, + ident: Option, + source: ValueSource, + arg: &Arg<'help>, + raw_vals: Vec, + matcher: &mut ArgMatcher, + ) -> ClapResult { + self.resolve_pending(matcher)?; + + debug!( + "Parser::react action={:?}, identifier={:?}, source={:?}", + arg.get_action(), + ident, + source + ); + match arg.get_action() { + ArgAction::Set => { + if source == ValueSource::CommandLine + && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) + { + // Record flag's index + self.cur_idx.set(self.cur_idx.get() + 1); + debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); + } + matcher.remove(&arg.id); + self.start_custom_arg(matcher, arg, source); + self.push_arg_values(arg, raw_vals, matcher)?; + if cfg!(debug_assertions) && matcher.needs_more_vals(arg) { + debug!( + "Parser::react not enough values passed in, leaving it to the validator to complain", + ); + } + Ok(ParseResult::ValuesDone) + } + ArgAction::Append => { + if source == ValueSource::CommandLine + && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) + { + // Record flag's index + self.cur_idx.set(self.cur_idx.get() + 1); + debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); + } + self.start_custom_arg(matcher, arg, source); + self.push_arg_values(arg, raw_vals, matcher)?; + if cfg!(debug_assertions) && matcher.needs_more_vals(arg) { + debug!( + "Parser::react not enough values passed in, leaving it to the validator to complain", + ); + } + Ok(ParseResult::ValuesDone) + } + #[allow(deprecated)] + ArgAction::StoreValue => { + if ident == Some(Identifier::Index) + && arg.is_multiple_values_set() + && matcher.contains(&arg.id) + { + // HACK: Reuse existing occurrence + } else if source == ValueSource::CommandLine { + if matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) { + // Record flag's index + self.cur_idx.set(self.cur_idx.get() + 1); + debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); + } + self.start_occurrence_of_arg(matcher, arg); + } else { + self.start_custom_arg(matcher, arg, source); + } + self.push_arg_values(arg, raw_vals, matcher)?; + if ident == Some(Identifier::Index) && arg.is_multiple_values_set() { + // HACK: Maintain existing occurrence behavior + let matched = matcher.get_mut(&arg.id).unwrap(); + #[allow(deprecated)] + matched.set_occurrences(matched.num_vals() as u64); + } + if cfg!(debug_assertions) && matcher.needs_more_vals(arg) { + debug!( + "Parser::react not enough values passed in, leaving it to the validator to complain", + ); + } + Ok(ParseResult::ValuesDone) + } + #[allow(deprecated)] + ArgAction::IncOccurrence => { + debug_assert_eq!(raw_vals, Vec::::new()); + if source == ValueSource::CommandLine { + if matches!(ident, Some(Identifier::Short) | Some(Identifier::Long)) { + // Record flag's index + self.cur_idx.set(self.cur_idx.get() + 1); + debug!("Parser::react: cur_idx:={}", self.cur_idx.get()); + } + self.start_occurrence_of_arg(matcher, arg); + } else { + self.start_custom_arg(matcher, arg, source); + } + matcher.add_index_to(&arg.id, self.cur_idx.get()); + Ok(ParseResult::ValuesDone) + } + ArgAction::SetTrue => { + let raw_vals = match raw_vals.len() { + 0 => { + vec![OsString::from("true")] + } + 1 => raw_vals, + _ => { + debug!("Parser::react ignoring trailing values: {:?}", raw_vals); + let mut raw_vals = raw_vals; + raw_vals.resize(1, Default::default()); + raw_vals + } + }; + + matcher.remove(&arg.id); + self.start_custom_arg(matcher, arg, source); + self.push_arg_values(arg, raw_vals, matcher)?; + Ok(ParseResult::ValuesDone) + } + ArgAction::SetFalse => { + let raw_vals = match raw_vals.len() { + 0 => { + vec![OsString::from("false")] + } + 1 => raw_vals, + _ => { + debug!("Parser::react ignoring trailing values: {:?}", raw_vals); + let mut raw_vals = raw_vals; + raw_vals.resize(1, Default::default()); + raw_vals + } + }; + + matcher.remove(&arg.id); + self.start_custom_arg(matcher, arg, source); + self.push_arg_values(arg, raw_vals, matcher)?; + Ok(ParseResult::ValuesDone) + } + ArgAction::Count => { + let raw_vals = match raw_vals.len() { + 0 => { + let existing_value = *matcher + .get_one::(arg.get_id()) + .unwrap_or(&0); + let next_value = existing_value.saturating_add(1); + vec![OsString::from(next_value.to_string())] + } + 1 => raw_vals, + _ => { + debug!("Parser::react ignoring trailing values: {:?}", raw_vals); + let mut raw_vals = raw_vals; + raw_vals.resize(1, Default::default()); + raw_vals + } + }; + + matcher.remove(&arg.id); + self.start_custom_arg(matcher, arg, source); + self.push_arg_values(arg, raw_vals, matcher)?; + Ok(ParseResult::ValuesDone) + } + ArgAction::Help => { + debug_assert_eq!(raw_vals, Vec::::new()); + let use_long = match ident { + Some(Identifier::Long) => true, + Some(Identifier::Short) => false, + Some(Identifier::Index) => true, + None => true, + }; + debug!("Help: use_long={}", use_long); + Err(self.help_err(use_long, Stream::Stdout)) + } + ArgAction::Version => { + debug_assert_eq!(raw_vals, Vec::::new()); + let use_long = match ident { + Some(Identifier::Long) => true, + Some(Identifier::Short) => false, + Some(Identifier::Index) => true, + None => true, + }; + debug!("Version: use_long={}", use_long); + Err(self.version_err(use_long)) + } + } + } + + fn remove_overrides(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) { + debug!("Parser::remove_overrides: id={:?}", arg.id); + for override_id in &arg.overrides { + debug!("Parser::remove_overrides:iter:{:?}: removing", override_id); + matcher.remove(override_id); + } + + // Override anything that can override us + let mut transitive = Vec::new(); + for arg_id in matcher.arg_ids() { + if let Some(overrider) = self.cmd.find(arg_id) { + if overrider.overrides.contains(&arg.id) { + transitive.push(&overrider.id); + } + } + } + for overrider_id in transitive { + debug!("Parser::remove_overrides:iter:{:?}: removing", overrider_id); + matcher.remove(overrider_id); + } + } + + #[cfg(feature = "env")] + fn add_env(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> { + debug!("Parser::add_env"); + use crate::util::str_to_bool; + + let trailing_values = false; // defaults are independent of the commandline + for arg in self.cmd.get_arguments() { + // Use env only if the arg was absent among command line args, + // early return if this is not the case. + if matcher.contains(&arg.id) { + debug!("Parser::add_env: Skipping existing arg `{}`", arg); + continue; + } + + debug!("Parser::add_env: Checking arg `{}`", arg); + if let Some((_, Some(ref val))) = arg.env { + let val = RawOsStr::new(val); + + if arg.is_takes_value_set() { + debug!( + "Parser::add_env: Found an opt with value={:?}, trailing={:?}", + val, trailing_values + ); + let mut arg_values = Vec::new(); + let _parse_result = + self.split_arg_values(arg, &val, trailing_values, &mut arg_values); + let _ = self.react(None, ValueSource::EnvVariable, arg, arg_values, matcher)?; + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!("Parser::add_env: Ignoring state {:?}; env variables are outside of the parse loop", _parse_result); + } + } + } else { + match arg.get_action() { + #[allow(deprecated)] + ArgAction::StoreValue => unreachable!("{:?} is not a flag", arg.get_id()), + #[allow(deprecated)] + ArgAction::IncOccurrence => { + debug!("Parser::add_env: Found a flag with value `{:?}`", val); + let predicate = str_to_bool(val.to_str_lossy()); + debug!("Parser::add_env: Found boolean literal `{:?}`", predicate); + if predicate.unwrap_or(true) { + let _ = self.react( + None, + ValueSource::EnvVariable, + arg, + vec![], + matcher, + )?; + } + } + ArgAction::Set + | ArgAction::Append + | ArgAction::SetTrue + | ArgAction::SetFalse + | ArgAction::Count => { + let mut arg_values = Vec::new(); + let _parse_result = + self.split_arg_values(arg, &val, trailing_values, &mut arg_values); + let _ = self.react( + None, + ValueSource::EnvVariable, + arg, + arg_values, + matcher, + )?; + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!("Parser::add_env: Ignoring state {:?}; env variables are outside of the parse loop", _parse_result); + } + } + } + // Early return on `Help` or `Version`. + ArgAction::Help | ArgAction::Version => { + let _ = + self.react(None, ValueSource::EnvVariable, arg, vec![], matcher)?; + } + } + } + } + } + + Ok(()) + } + + fn add_defaults(&self, matcher: &mut ArgMatcher) -> ClapResult<()> { + debug!("Parser::add_defaults"); + + for arg in self.cmd.get_arguments() { + debug!("Parser::add_defaults:iter:{}:", arg.name); + self.add_default_value(arg, matcher)?; + } + + Ok(()) + } + + fn add_default_value(&self, arg: &Arg<'help>, matcher: &mut ArgMatcher) -> ClapResult<()> { + let trailing_values = false; // defaults are independent of the commandline + + if !arg.default_missing_vals.is_empty() { + debug!( + "Parser::add_default_value:iter:{}: has default missing vals", + arg.name + ); + match matcher.get(&arg.id) { + Some(ma) if ma.all_val_groups_empty() => { + debug!( + "Parser::add_default_value:iter:{}: has no user defined vals", + arg.name + ); + // The flag occurred, we just want to add the val groups + let mut arg_values = Vec::new(); + for v in arg.default_missing_vals.iter() { + let _parse_result = self.split_arg_values( + arg, + &RawOsStr::new(v), + trailing_values, + &mut arg_values, + ); + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result); + } + } + } + self.start_custom_arg(matcher, arg, ValueSource::CommandLine); + self.push_arg_values(arg, arg_values, matcher)?; + } + None => { + debug!("Parser::add_default_value:iter:{}: wasn't used", arg.name); + // do nothing + } + _ => { + debug!( + "Parser::add_default_value:iter:{}: has user defined vals", + arg.name + ); + // do nothing + } + } + } else { + debug!( + "Parser::add_default_value:iter:{}: doesn't have default missing vals", + arg.name + ); + // do nothing + } + + if !arg.default_vals_ifs.is_empty() { + debug!("Parser::add_default_value: has conditional defaults"); + if !matcher.contains(&arg.id) { + for (id, val, default) in arg.default_vals_ifs.iter() { + let add = if let Some(a) = matcher.get(id) { + match val { + crate::builder::ArgPredicate::Equals(v) => { + a.raw_vals_flatten().any(|value| v == value) + } + crate::builder::ArgPredicate::IsPresent => true, + } + } else { + false + }; + + if add { + if let Some(default) = default { + let mut arg_values = Vec::new(); + let _parse_result = self.split_arg_values( + arg, + &RawOsStr::new(default), + trailing_values, + &mut arg_values, + ); + let _ = self.react( + None, + ValueSource::DefaultValue, + arg, + arg_values, + matcher, + )?; + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result); + } + } + } + return Ok(()); + } + } + } + } else { + debug!("Parser::add_default_value: doesn't have conditional defaults"); + } + + if !arg.default_vals.is_empty() { + debug!( + "Parser::add_default_value:iter:{}: has default vals", + arg.name + ); + if matcher.contains(&arg.id) { + debug!("Parser::add_default_value:iter:{}: was used", arg.name); + // do nothing + } else { + debug!("Parser::add_default_value:iter:{}: wasn't used", arg.name); + let mut arg_values = Vec::new(); + for v in arg.default_vals.iter() { + let _parse_result = self.split_arg_values( + arg, + &RawOsStr::new(v), + trailing_values, + &mut arg_values, + ); + if let Some(_parse_result) = _parse_result { + if _parse_result != ParseResult::ValuesDone { + debug!("Parser::add_default_value: Ignoring state {:?}; defaults are outside of the parse loop", _parse_result); + } + } + } + let _ = self.react(None, ValueSource::DefaultValue, arg, arg_values, matcher)?; + } + } else { + debug!( + "Parser::add_default_value:iter:{}: doesn't have default vals", + arg.name + ); + + // do nothing + } + + Ok(()) + } + + fn start_custom_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>, source: ValueSource) { + if source == ValueSource::CommandLine { + // With each new occurrence, remove overrides from prior occurrences + self.remove_overrides(arg, matcher); + } + matcher.start_custom_arg(arg, source); + for group in self.cmd.groups_for_arg(&arg.id) { + matcher.start_custom_group(&group, source); + } + } + + /// Increase occurrence of specific argument and the grouped arg it's in. + fn start_occurrence_of_arg(&self, matcher: &mut ArgMatcher, arg: &Arg<'help>) { + // With each new occurrence, remove overrides from prior occurrences + self.remove_overrides(arg, matcher); + + matcher.start_occurrence_of_arg(arg); + // Increment or create the group "args" + for group in self.cmd.groups_for_arg(&arg.id) { + matcher.start_occurrence_of_group(&group); + } + } +} + +// Error, Help, and Version Methods +impl<'help, 'cmd> Parser<'help, 'cmd> { + /// Is only used for the long flag(which is the only one needs fuzzy searching) + fn did_you_mean_error( + &mut self, + arg: &str, + matcher: &mut ArgMatcher, + remaining_args: &[&str], + ) -> ClapError { + debug!("Parser::did_you_mean_error: arg={}", arg); + // Didn't match a flag or option + let longs = self + .cmd + .get_keymap() + .keys() + .filter_map(|x| match x { + KeyType::Long(l) => Some(l.to_string_lossy().into_owned()), + _ => None, + }) + .collect::>(); + debug!("Parser::did_you_mean_error: longs={:?}", longs); + + let did_you_mean = suggestions::did_you_mean_flag( + arg, + remaining_args, + longs.iter().map(|x| &x[..]), + self.cmd.get_subcommands_mut(), + ); + + // Add the arg to the matches to build a proper usage string + if let Some((name, _)) = did_you_mean.as_ref() { + if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) { + self.start_occurrence_of_arg(matcher, arg); + } + } + + let required = self.cmd.required_graph(); + let used: Vec = matcher + .arg_ids() + .filter(|arg_id| { + matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) + }) + .filter(|n| self.cmd.find(n).map_or(true, |a| !a.is_hide_set())) + .cloned() + .collect(); + + ClapError::unknown_argument( + self.cmd, + format!("--{}", arg), + did_you_mean, + Usage::new(self.cmd) + .required(&required) + .create_usage_with_title(&*used), + ) + } + + fn help_err(&self, use_long: bool, stream: Stream) -> ClapError { + match self.cmd.write_help_err(use_long, stream) { + Ok(c) => ClapError::display_help(self.cmd, c), + Err(e) => e, + } + } + + fn version_err(&self, use_long: bool) -> ClapError { + debug!("Parser::version_err"); + + let msg = self.cmd._render_version(use_long); + let mut c = Colorizer::new(Stream::Stdout, self.cmd.color_help()); + c.none(msg); + ClapError::display_version(self.cmd, c) + } +} + +// Query Methods +impl<'help, 'cmd> Parser<'help, 'cmd> { + pub(crate) fn is_set(&self, s: AS) -> bool { + self.cmd.is_set(s) + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum ParseState { + ValuesDone, + Opt(Id), + Pos(Id), +} + +/// Recoverable Parsing results. +#[derive(Debug, PartialEq, Clone)] +#[must_use] +enum ParseResult { + FlagSubCommand(String), + Opt(Id), + ValuesDone, + /// Value attached to the short flag is not consumed(e.g. 'u' for `-cu` is + /// not consumed). + AttachedValueNotConsumed, + /// This long flag doesn't need a value but is provided one. + UnneededAttachedValue { + rest: String, + used: Vec, + arg: String, + }, + /// This flag might be an hyphen Value. + MaybeHyphenValue, + /// Equals required but not provided. + EqualsNotProvided { + arg: String, + }, + /// Failed to match a Arg. + NoMatchingArg { + arg: String, + }, + /// No argument found e.g. parser is given `-` when parsing a flag. + NoArg, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct PendingArg { + pub(crate) id: Id, + pub(crate) ident: Option, + pub(crate) raw_vals: Vec, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) enum Identifier { + Short, + Long, + Index, +} diff --git a/vendor/clap-3.2.20/src/parser/validator.rs b/vendor/clap-3.2.20/src/parser/validator.rs new file mode 100644 index 000000000..ebf2b234d --- /dev/null +++ b/vendor/clap-3.2.20/src/parser/validator.rs @@ -0,0 +1,692 @@ +// Internal +use crate::builder::{AppSettings, Arg, ArgPredicate, Command, PossibleValue}; +use crate::error::{Error, Result as ClapResult}; +use crate::output::fmt::Stream; +use crate::output::Usage; +use crate::parser::{ArgMatcher, MatchedArg, ParseState}; +use crate::util::ChildGraph; +use crate::util::Id; +use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8}; + +pub(crate) struct Validator<'help, 'cmd> { + cmd: &'cmd Command<'help>, + required: ChildGraph, +} + +impl<'help, 'cmd> Validator<'help, 'cmd> { + pub(crate) fn new(cmd: &'cmd Command<'help>) -> Self { + let required = cmd.required_graph(); + Validator { cmd, required } + } + + pub(crate) fn validate( + &mut self, + parse_state: ParseState, + matcher: &mut ArgMatcher, + ) -> ClapResult<()> { + debug!("Validator::validate"); + let mut conflicts = Conflicts::new(); + let has_subcmd = matcher.subcommand_name().is_some(); + + if let ParseState::Opt(a) = parse_state { + debug!("Validator::validate: needs_val_of={:?}", a); + + let o = &self.cmd[&a]; + let should_err = if let Some(v) = matcher.args.get(&o.id) { + v.all_val_groups_empty() && !(o.min_vals.is_some() && o.min_vals.unwrap() == 0) + } else { + true + }; + if should_err { + return Err(Error::empty_value( + self.cmd, + &get_possible_values(o) + .iter() + .filter(|pv| !pv.is_hide_set()) + .map(PossibleValue::get_name) + .collect::>(), + o.to_string(), + )); + } + } + + if !has_subcmd && self.cmd.is_arg_required_else_help_set() { + let num_user_values = matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + .count(); + if num_user_values == 0 { + let message = self.cmd.write_help_err(false, Stream::Stderr)?; + return Err(Error::display_help_error(self.cmd, message)); + } + } + #[allow(deprecated)] + if !has_subcmd && self.cmd.is_subcommand_required_set() { + let bn = self + .cmd + .get_bin_name() + .unwrap_or_else(|| self.cmd.get_name()); + return Err(Error::missing_subcommand( + self.cmd, + bn.to_string(), + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )); + } else if !has_subcmd && self.cmd.is_set(AppSettings::SubcommandRequiredElseHelp) { + debug!("Validator::new::get_matches_with: SubcommandRequiredElseHelp=true"); + let message = self.cmd.write_help_err(false, Stream::Stderr)?; + return Err(Error::display_help_error(self.cmd, message)); + } + + self.validate_conflicts(matcher, &mut conflicts)?; + if !(self.cmd.is_subcommand_negates_reqs_set() && has_subcmd) { + self.validate_required(matcher, &mut conflicts)?; + } + self.validate_matched_args(matcher)?; + + Ok(()) + } + + fn validate_arg_values(&self, arg: &Arg, ma: &MatchedArg) -> ClapResult<()> { + debug!("Validator::validate_arg_values: arg={:?}", arg.name); + for val in ma.raw_vals_flatten() { + if !arg.possible_vals.is_empty() { + debug!( + "Validator::validate_arg_values: possible_vals={:?}", + arg.possible_vals + ); + let val_str = val.to_string_lossy(); + let ok = arg + .possible_vals + .iter() + .any(|pv| pv.matches(&val_str, arg.is_ignore_case_set())); + if !ok { + return Err(Error::invalid_value( + self.cmd, + val_str.into_owned(), + &arg.possible_vals + .iter() + .filter(|pv| !pv.is_hide_set()) + .map(PossibleValue::get_name) + .collect::>(), + arg.to_string(), + )); + } + } + { + #![allow(deprecated)] + if arg.is_forbid_empty_values_set() && val.is_empty() { + debug!("Validator::validate_arg_values: illegal empty val found"); + return Err(Error::empty_value( + self.cmd, + &get_possible_values(arg) + .iter() + .filter(|pv| !pv.is_hide_set()) + .map(PossibleValue::get_name) + .collect::>(), + arg.to_string(), + )); + } + } + + if let Some(ref vtor) = arg.validator { + debug!("Validator::validate_arg_values: checking validator..."); + let mut vtor = vtor.lock().unwrap(); + if let Err(e) = vtor(&*val.to_string_lossy()) { + debug!("error"); + return Err(Error::value_validation( + arg.to_string(), + val.to_string_lossy().into_owned(), + e, + ) + .with_cmd(self.cmd)); + } else { + debug!("good"); + } + } + if let Some(ref vtor) = arg.validator_os { + debug!("Validator::validate_arg_values: checking validator_os..."); + let mut vtor = vtor.lock().unwrap(); + if let Err(e) = vtor(val) { + debug!("error"); + return Err(Error::value_validation( + arg.to_string(), + val.to_string_lossy().into(), + e, + ) + .with_cmd(self.cmd)); + } else { + debug!("good"); + } + } + } + Ok(()) + } + + fn validate_conflicts( + &mut self, + matcher: &ArgMatcher, + conflicts: &mut Conflicts, + ) -> ClapResult<()> { + debug!("Validator::validate_conflicts"); + + self.validate_exclusive(matcher)?; + + for arg_id in matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + .filter(|arg_id| self.cmd.find(arg_id).is_some()) + { + debug!("Validator::validate_conflicts::iter: id={:?}", arg_id); + let conflicts = conflicts.gather_conflicts(self.cmd, matcher, arg_id); + self.build_conflict_err(arg_id, &conflicts, matcher)?; + } + + Ok(()) + } + + fn validate_exclusive(&self, matcher: &ArgMatcher) -> ClapResult<()> { + debug!("Validator::validate_exclusive"); + let args_count = matcher + .arg_ids() + .filter(|arg_id| { + matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) + }) + .count(); + if args_count <= 1 { + // Nothing present to conflict with + return Ok(()); + } + + matcher + .arg_ids() + .filter(|arg_id| { + matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent) + }) + .filter_map(|name| { + debug!("Validator::validate_exclusive:iter:{:?}", name); + self.cmd + .find(name) + // Find `arg`s which are exclusive but also appear with other args. + .filter(|&arg| arg.is_exclusive_set() && args_count > 1) + }) + // Throw an error for the first conflict found. + .try_for_each(|arg| { + Err(Error::argument_conflict( + self.cmd, + arg.to_string(), + Vec::new(), + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )) + }) + } + + fn build_conflict_err( + &self, + name: &Id, + conflict_ids: &[Id], + matcher: &ArgMatcher, + ) -> ClapResult<()> { + if conflict_ids.is_empty() { + return Ok(()); + } + + debug!("Validator::build_conflict_err: name={:?}", name); + let mut seen = std::collections::HashSet::new(); + let conflicts = conflict_ids + .iter() + .flat_map(|c_id| { + if self.cmd.find_group(c_id).is_some() { + self.cmd.unroll_args_in_group(c_id) + } else { + vec![c_id.clone()] + } + }) + .filter_map(|c_id| { + seen.insert(c_id.clone()).then(|| { + let c_arg = self.cmd.find(&c_id).expect(INTERNAL_ERROR_MSG); + c_arg.to_string() + }) + }) + .collect(); + + let former_arg = self.cmd.find(name).expect(INTERNAL_ERROR_MSG); + let usg = self.build_conflict_err_usage(matcher, conflict_ids); + Err(Error::argument_conflict( + self.cmd, + former_arg.to_string(), + conflicts, + usg, + )) + } + + fn build_conflict_err_usage(&self, matcher: &ArgMatcher, conflicting_keys: &[Id]) -> String { + let used_filtered: Vec = matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + .filter(|n| { + // Filter out the args we don't want to specify. + self.cmd.find(n).map_or(true, |a| !a.is_hide_set()) + }) + .filter(|key| !conflicting_keys.contains(key)) + .cloned() + .collect(); + let required: Vec = used_filtered + .iter() + .filter_map(|key| self.cmd.find(key)) + .flat_map(|arg| arg.requires.iter().map(|item| &item.1)) + .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key)) + .chain(used_filtered.iter()) + .cloned() + .collect(); + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&required) + } + + fn gather_requires(&mut self, matcher: &ArgMatcher) { + debug!("Validator::gather_requires"); + for name in matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + { + debug!("Validator::gather_requires:iter:{:?}", name); + if let Some(arg) = self.cmd.find(name) { + let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option { + let required = matcher.check_explicit(&arg.id, *val); + required.then(|| req_arg.clone()) + }; + + for req in self.cmd.unroll_arg_requires(is_relevant, &arg.id) { + self.required.insert(req); + } + } else if let Some(g) = self.cmd.find_group(name) { + debug!("Validator::gather_requires:iter:{:?}:group", name); + for r in &g.requires { + self.required.insert(r.clone()); + } + } + } + } + + fn validate_matched_args(&self, matcher: &ArgMatcher) -> ClapResult<()> { + debug!("Validator::validate_matched_args"); + matcher.iter().try_for_each(|(name, ma)| { + debug!( + "Validator::validate_matched_args:iter:{:?}: vals={:#?}", + name, + ma.vals_flatten() + ); + if let Some(arg) = self.cmd.find(name) { + self.validate_arg_num_vals(arg, ma)?; + self.validate_arg_values(arg, ma)?; + self.validate_arg_num_occurs(arg, ma)?; + } + Ok(()) + }) + } + + fn validate_arg_num_occurs(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> { + #![allow(deprecated)] + debug!( + "Validator::validate_arg_num_occurs: {:?}={}", + a.name, + ma.get_occurrences() + ); + // Occurrence of positional argument equals to number of values rather + // than number of grouped values. + if ma.get_occurrences() > 1 && !a.is_multiple_occurrences_set() && !a.is_positional() { + // Not the first time, and we don't allow multiples + return Err(Error::unexpected_multiple_usage( + self.cmd, + a.to_string(), + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )); + } + if let Some(max_occurs) = a.max_occurs { + debug!( + "Validator::validate_arg_num_occurs: max_occurs set...{}", + max_occurs + ); + let occurs = ma.get_occurrences() as usize; + if occurs > max_occurs { + return Err(Error::too_many_occurrences( + self.cmd, + a.to_string(), + max_occurs, + occurs, + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )); + } + } + + Ok(()) + } + + fn validate_arg_num_vals(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> { + debug!("Validator::validate_arg_num_vals"); + if let Some(num) = a.num_vals { + let total_num = ma.num_vals(); + debug!("Validator::validate_arg_num_vals: num_vals set...{}", num); + #[allow(deprecated)] + let should_err = if a.is_multiple_occurrences_set() { + total_num % num != 0 + } else { + num != total_num + }; + if should_err { + debug!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues"); + return Err(Error::wrong_number_of_values( + self.cmd, + a.to_string(), + num, + #[allow(deprecated)] + if a.is_multiple_occurrences_set() { + total_num % num + } else { + total_num + }, + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )); + } + } + if let Some(num) = a.max_vals { + debug!("Validator::validate_arg_num_vals: max_vals set...{}", num); + if ma.num_vals() > num { + debug!("Validator::validate_arg_num_vals: Sending error TooManyValues"); + return Err(Error::too_many_values( + self.cmd, + ma.raw_vals_flatten() + .last() + .expect(INTERNAL_ERROR_MSG) + .to_str() + .expect(INVALID_UTF8) + .to_string(), + a.to_string(), + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )); + } + } + let min_vals_zero = if let Some(num) = a.min_vals { + debug!("Validator::validate_arg_num_vals: min_vals set: {}", num); + if ma.num_vals() < num && num != 0 { + debug!("Validator::validate_arg_num_vals: Sending error TooFewValues"); + return Err(Error::too_few_values( + self.cmd, + a.to_string(), + num, + ma.num_vals(), + Usage::new(self.cmd) + .required(&self.required) + .create_usage_with_title(&[]), + )); + } + num == 0 + } else { + false + }; + // Issue 665 (https://github.com/clap-rs/clap/issues/665) + // Issue 1105 (https://github.com/clap-rs/clap/issues/1105) + if a.is_takes_value_set() && !min_vals_zero && ma.all_val_groups_empty() { + return Err(Error::empty_value( + self.cmd, + &get_possible_values(a) + .iter() + .filter(|pv| !pv.is_hide_set()) + .map(PossibleValue::get_name) + .collect::>(), + a.to_string(), + )); + } + Ok(()) + } + + fn validate_required( + &mut self, + matcher: &ArgMatcher, + conflicts: &mut Conflicts, + ) -> ClapResult<()> { + debug!("Validator::validate_required: required={:?}", self.required); + self.gather_requires(matcher); + + let is_exclusive_present = matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + .any(|id| { + self.cmd + .find(id) + .map(|arg| arg.is_exclusive_set()) + .unwrap_or_default() + }); + debug!( + "Validator::validate_required: is_exclusive_present={}", + is_exclusive_present + ); + + for arg_or_group in self + .required + .iter() + .filter(|r| !matcher.check_explicit(r, ArgPredicate::IsPresent)) + { + debug!("Validator::validate_required:iter:aog={:?}", arg_or_group); + if let Some(arg) = self.cmd.find(arg_or_group) { + debug!("Validator::validate_required:iter: This is an arg"); + if !is_exclusive_present && !self.is_missing_required_ok(arg, matcher, conflicts) { + return self.missing_required_error(matcher, vec![]); + } + } else if let Some(group) = self.cmd.find_group(arg_or_group) { + debug!("Validator::validate_required:iter: This is a group"); + if !self + .cmd + .unroll_args_in_group(&group.id) + .iter() + .any(|a| matcher.check_explicit(a, ArgPredicate::IsPresent)) + { + return self.missing_required_error(matcher, vec![]); + } + } + } + + // Validate the conditionally required args + for a in self.cmd.get_arguments() { + for (other, val) in &a.r_ifs { + if matcher.check_explicit(other, ArgPredicate::Equals(std::ffi::OsStr::new(*val))) + && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent) + { + return self.missing_required_error(matcher, vec![a.id.clone()]); + } + } + + let match_all = a.r_ifs_all.iter().all(|(other, val)| { + matcher.check_explicit(other, ArgPredicate::Equals(std::ffi::OsStr::new(*val))) + }); + if match_all + && !a.r_ifs_all.is_empty() + && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent) + { + return self.missing_required_error(matcher, vec![a.id.clone()]); + } + } + + self.validate_required_unless(matcher)?; + + Ok(()) + } + + fn is_missing_required_ok( + &self, + a: &Arg<'help>, + matcher: &ArgMatcher, + conflicts: &mut Conflicts, + ) -> bool { + debug!("Validator::is_missing_required_ok: {}", a.name); + let conflicts = conflicts.gather_conflicts(self.cmd, matcher, &a.id); + !conflicts.is_empty() + } + + fn validate_required_unless(&self, matcher: &ArgMatcher) -> ClapResult<()> { + debug!("Validator::validate_required_unless"); + let failed_args: Vec<_> = self + .cmd + .get_arguments() + .filter(|&a| { + (!a.r_unless.is_empty() || !a.r_unless_all.is_empty()) + && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent) + && self.fails_arg_required_unless(a, matcher) + }) + .map(|a| a.id.clone()) + .collect(); + if failed_args.is_empty() { + Ok(()) + } else { + self.missing_required_error(matcher, failed_args) + } + } + + // Failing a required unless means, the arg's "unless" wasn't present, and neither were they + fn fails_arg_required_unless(&self, a: &Arg<'help>, matcher: &ArgMatcher) -> bool { + debug!("Validator::fails_arg_required_unless: a={:?}", a.name); + let exists = |id| matcher.check_explicit(id, ArgPredicate::IsPresent); + + (a.r_unless_all.is_empty() || !a.r_unless_all.iter().all(exists)) + && !a.r_unless.iter().any(exists) + } + + // `incl`: an arg to include in the error even if not used + fn missing_required_error(&self, matcher: &ArgMatcher, incl: Vec) -> ClapResult<()> { + debug!("Validator::missing_required_error; incl={:?}", incl); + debug!( + "Validator::missing_required_error: reqs={:?}", + self.required + ); + + let usg = Usage::new(self.cmd).required(&self.required); + + let req_args = usg + .get_required_usage_from(&incl, Some(matcher), true) + .into_iter() + .collect::>(); + + debug!( + "Validator::missing_required_error: req_args={:#?}", + req_args + ); + + let used: Vec = matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + .filter(|n| { + // Filter out the args we don't want to specify. + self.cmd.find(n).map_or(true, |a| !a.is_hide_set()) + }) + .cloned() + .chain(incl) + .collect(); + + Err(Error::missing_required_argument( + self.cmd, + req_args, + usg.create_usage_with_title(&used), + )) + } +} + +#[derive(Default, Clone, Debug)] +struct Conflicts { + potential: std::collections::HashMap>, +} + +impl Conflicts { + fn new() -> Self { + Self::default() + } + + fn gather_conflicts(&mut self, cmd: &Command, matcher: &ArgMatcher, arg_id: &Id) -> Vec { + debug!("Conflicts::gather_conflicts: arg={:?}", arg_id); + let mut conflicts = Vec::new(); + for other_arg_id in matcher + .arg_ids() + .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent)) + { + if arg_id == other_arg_id { + continue; + } + + if self + .gather_direct_conflicts(cmd, arg_id) + .contains(other_arg_id) + { + conflicts.push(other_arg_id.clone()); + } + if self + .gather_direct_conflicts(cmd, other_arg_id) + .contains(arg_id) + { + conflicts.push(other_arg_id.clone()); + } + } + debug!("Conflicts::gather_conflicts: conflicts={:?}", conflicts); + conflicts + } + + fn gather_direct_conflicts(&mut self, cmd: &Command, arg_id: &Id) -> &[Id] { + self.potential.entry(arg_id.clone()).or_insert_with(|| { + let conf = if let Some(arg) = cmd.find(arg_id) { + let mut conf = arg.blacklist.clone(); + for group_id in cmd.groups_for_arg(arg_id) { + let group = cmd.find_group(&group_id).expect(INTERNAL_ERROR_MSG); + conf.extend(group.conflicts.iter().cloned()); + if !group.multiple { + for member_id in &group.args { + if member_id != arg_id { + conf.push(member_id.clone()); + } + } + } + } + + // Overrides are implicitly conflicts + conf.extend(arg.overrides.iter().cloned()); + + conf + } else if let Some(group) = cmd.find_group(arg_id) { + group.conflicts.clone() + } else { + debug_assert!(false, "id={:?} is unknown", arg_id); + Vec::new() + }; + debug!( + "Conflicts::gather_direct_conflicts id={:?}, conflicts={:?}", + arg_id, conf + ); + conf + }) + } +} + +fn get_possible_values<'help>(a: &Arg<'help>) -> Vec> { + #![allow(deprecated)] + if !a.is_takes_value_set() { + vec![] + } else if let Some(pvs) = a.get_possible_values() { + // Check old first in case the user explicitly set possible values and the derive inferred + // a `ValueParser` with some. + pvs.to_vec() + } else { + a.get_value_parser() + .possible_values() + .map(|pvs| pvs.collect()) + .unwrap_or_default() + } +} diff --git a/vendor/clap-3.2.20/src/util/color.rs b/vendor/clap-3.2.20/src/util/color.rs new file mode 100644 index 000000000..15c9901a0 --- /dev/null +++ b/vendor/clap-3.2.20/src/util/color.rs @@ -0,0 +1,62 @@ +/// Represents the color preferences for program output +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum ColorChoice { + /// Enables colored output only when the output is going to a terminal or TTY. + /// + /// **NOTE:** This is the default behavior of `clap`. + /// + /// # Platform Specific + /// + /// This setting only applies to Unix, Linux, and macOS (i.e. non-Windows platforms). + /// + /// # Examples + /// + #[cfg_attr(not(feature = "color"), doc = " ```ignore")] + #[cfg_attr(feature = "color", doc = " ```no_run")] + /// # use clap::{Command, ColorChoice}; + /// Command::new("myprog") + /// .color(ColorChoice::Auto) + /// .get_matches(); + /// ``` + Auto, + + /// Enables colored output regardless of whether or not the output is going to a terminal/TTY. + /// + /// # Platform Specific + /// + /// This setting only applies to Unix, Linux, and macOS (i.e. non-Windows platforms). + /// + /// # Examples + /// + #[cfg_attr(not(feature = "color"), doc = " ```ignore")] + #[cfg_attr(feature = "color", doc = " ```no_run")] + /// # use clap::{Command, ColorChoice}; + /// Command::new("myprog") + /// .color(ColorChoice::Always) + /// .get_matches(); + /// ``` + Always, + + /// Disables colored output no matter if the output is going to a terminal/TTY, or not. + /// + /// # Platform Specific + /// + /// This setting only applies to Unix, Linux, and macOS (i.e. non-Windows platforms) + /// + /// # Examples + /// + #[cfg_attr(not(feature = "color"), doc = " ```ignore")] + #[cfg_attr(feature = "color", doc = " ```no_run")] + /// # use clap::{Command, ColorChoice}; + /// Command::new("myprog") + /// .color(ColorChoice::Never) + /// .get_matches(); + /// ``` + Never, +} + +impl Default for ColorChoice { + fn default() -> Self { + Self::Auto + } +} diff --git a/vendor/clap-3.2.20/src/util/fnv.rs b/vendor/clap-3.2.20/src/util/fnv.rs new file mode 100644 index 000000000..4602300a4 --- /dev/null +++ b/vendor/clap-3.2.20/src/util/fnv.rs @@ -0,0 +1,46 @@ +use std::{ + fmt::Display, + hash::{Hash, Hasher}, +}; + +const MAGIC_INIT: u64 = 0x811C_9DC5; + +// TODO: Docs +pub trait Key: Hash + Display { + fn key(&self) -> u64; +} + +impl Key for T +where + T: Hash + Display, +{ + fn key(&self) -> u64 { + let mut hasher = FnvHasher::new(); + self.hash(&mut hasher); + hasher.finish() + } +} + +pub(crate) struct FnvHasher(u64); + +impl FnvHasher { + pub(crate) fn new() -> Self { + FnvHasher(MAGIC_INIT) + } +} + +impl Hasher for FnvHasher { + fn finish(&self) -> u64 { + self.0 + } + fn write(&mut self, bytes: &[u8]) { + let FnvHasher(mut hash) = *self; + + for byte in bytes.iter() { + hash ^= u64::from(*byte); + hash = hash.wrapping_mul(0x0100_0000_01b3); + } + + *self = FnvHasher(hash); + } +} diff --git a/vendor/clap-3.2.20/src/util/graph.rs b/vendor/clap-3.2.20/src/util/graph.rs new file mode 100644 index 000000000..d646400b0 --- /dev/null +++ b/vendor/clap-3.2.20/src/util/graph.rs @@ -0,0 +1,49 @@ +#[derive(Debug)] +struct Child { + id: T, + children: Vec, +} + +impl Child { + fn new(id: T) -> Self { + Child { + id, + children: vec![], + } + } +} + +#[derive(Debug)] +pub(crate) struct ChildGraph(Vec>); + +impl ChildGraph +where + T: Sized + PartialEq + Clone, +{ + pub(crate) fn with_capacity(s: usize) -> Self { + ChildGraph(Vec::with_capacity(s)) + } + + pub(crate) fn insert(&mut self, req: T) -> usize { + self.0.iter().position(|e| e.id == req).unwrap_or_else(|| { + let idx = self.0.len(); + self.0.push(Child::new(req)); + idx + }) + } + + pub(crate) fn insert_child(&mut self, parent: usize, child: T) -> usize { + let c_idx = self.0.len(); + self.0.push(Child::new(child)); + self.0[parent].children.push(c_idx); + c_idx + } + + pub(crate) fn iter(&self) -> impl Iterator { + self.0.iter().map(|r| &r.id) + } + + pub(crate) fn contains(&self, req: &T) -> bool { + self.0.iter().any(|r| r.id == *req) + } +} diff --git a/vendor/clap-3.2.20/src/util/id.rs b/vendor/clap-3.2.20/src/util/id.rs new file mode 100644 index 000000000..63a7e003e --- /dev/null +++ b/vendor/clap-3.2.20/src/util/id.rs @@ -0,0 +1,92 @@ +use crate::util::fnv::Key; + +use std::{ + fmt::{Debug, Formatter, Result}, + hash::{Hash, Hasher}, + ops::Deref, +}; + +#[derive(Clone, Eq, Default)] +#[cfg_attr(not(debug_assertions), repr(transparent))] +pub(crate) struct Id { + #[cfg(debug_assertions)] + name: String, + id: u64, +} + +macro_rules! precomputed_hashes { + ($($fn_name:ident, $const:expr, $name:expr;)*) => { + impl Id { + $( + pub(crate) fn $fn_name() -> Self { + Id { + #[cfg(debug_assertions)] + name: $name.into(), + id: $const, + } + } + )* + } + }; +} + +// precompute some common values +precomputed_hashes! { + empty_hash, 0x1C9D_3ADB_639F_298E, ""; + help_hash, 0x5963_6393_CFFB_FE5F, "help"; + version_hash, 0x30FF_0B7C_4D07_9478, "version"; +} + +impl Id { + pub(crate) fn from_ref(val: T) -> Self { + Id { + #[cfg(debug_assertions)] + name: val.to_string(), + id: val.key(), + } + } +} + +impl Debug for Id { + fn fmt(&self, f: &mut Formatter) -> Result { + #[cfg(debug_assertions)] + write!(f, "{}", self.name)?; + #[cfg(not(debug_assertions))] + write!(f, "[hash: {:X}]", self.id)?; + + Ok(()) + } +} + +impl Deref for Id { + type Target = u64; + + fn deref(&self) -> &Self::Target { + &self.id + } +} + +impl From for Id { + fn from(val: T) -> Self { + Id { + #[cfg(debug_assertions)] + name: val.to_string(), + id: val.key(), + } + } +} + +impl Hash for Id { + fn hash(&self, state: &mut H) + where + H: Hasher, + { + self.id.hash(state) + } +} + +impl PartialEq for Id { + fn eq(&self, other: &Id) -> bool { + self.id == other.id + } +} diff --git a/vendor/clap-3.2.20/src/util/mod.rs b/vendor/clap-3.2.20/src/util/mod.rs new file mode 100644 index 000000000..8adc8db17 --- /dev/null +++ b/vendor/clap-3.2.20/src/util/mod.rs @@ -0,0 +1,40 @@ +#![allow(clippy::single_component_path_imports)] + +mod fnv; +mod graph; +mod id; +mod str_to_bool; + +pub use self::fnv::Key; + +pub(crate) use self::str_to_bool::str_to_bool; +pub(crate) use self::str_to_bool::FALSE_LITERALS; +pub(crate) use self::str_to_bool::TRUE_LITERALS; +pub(crate) use self::{graph::ChildGraph, id::Id}; + +pub(crate) mod color; + +pub(crate) const SUCCESS_CODE: i32 = 0; +// While sysexists.h defines EX_USAGE as 64, this doesn't seem to be used much in practice but +// instead 2 seems to be frequently used. +// Examples +// - GNU `ls` returns 2 +// - Python's `argparse` returns 2 +pub(crate) const USAGE_CODE: i32 = 2; + +pub(crate) fn safe_exit(code: i32) -> ! { + use std::io::Write; + + let _ = std::io::stdout().lock().flush(); + let _ = std::io::stderr().lock().flush(); + + std::process::exit(code) +} + +#[cfg(not(feature = "unicode"))] +pub(crate) fn eq_ignore_case(left: &str, right: &str) -> bool { + left.eq_ignore_ascii_case(right) +} + +#[cfg(feature = "unicode")] +pub(crate) use unicase::eq as eq_ignore_case; diff --git a/vendor/clap-3.2.20/src/util/str_to_bool.rs b/vendor/clap-3.2.20/src/util/str_to_bool.rs new file mode 100644 index 000000000..1fbdc7531 --- /dev/null +++ b/vendor/clap-3.2.20/src/util/str_to_bool.rs @@ -0,0 +1,21 @@ +/// True values are `y`, `yes`, `t`, `true`, `on`, and `1`. +pub(crate) const TRUE_LITERALS: [&str; 6] = ["y", "yes", "t", "true", "on", "1"]; + +/// False values are `n`, `no`, `f`, `false`, `off`, and `0`. +pub(crate) const FALSE_LITERALS: [&str; 6] = ["n", "no", "f", "false", "off", "0"]; + +/// Converts a string literal representation of truth to true or false. +/// +/// `false` values are `n`, `no`, `f`, `false`, `off`, and `0` (case insensitive). +/// +/// Any other value will be considered as `true`. +pub(crate) fn str_to_bool(val: impl AsRef) -> Option { + let pat: &str = &val.as_ref().to_lowercase(); + if TRUE_LITERALS.contains(&pat) { + Some(true) + } else if FALSE_LITERALS.contains(&pat) { + Some(false) + } else { + None + } +} diff --git a/vendor/clap/.cargo-checksum.json b/vendor/clap/.cargo-checksum.json deleted file mode 100644 index 22fa24875..000000000 --- a/vendor/clap/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.lock":"60560d6b2bec73734ebea64f8b916cbe9361e672157119801ba0e2f89334453c","Cargo.toml":"5def59eada2aa1a035cb39b38da4ba02baec2dd9271e4ef16731a8ef06c4d58f","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"0d687e1f07b58fe68bda74668ff6326125e5e5efa184cce755cd84ac535b7058","README.md":"ee049ee3ccab683cd3fa7c980db71c22ed8577378433cad5a93c1bc2a9dbe20f","examples/cargo-example-derive.md":"8305e66dd56619ec3a1d116951c893965cc8435574f5bf8baea923492357c626","examples/cargo-example-derive.rs":"a94003c9fadd1a11c35616ea4e5132c768bad08650e207848e1de56bffd86c8f","examples/cargo-example.md":"b7e51be8f05538ae39ce232ef12c873af81ab5abb5740c079d09b7cdd27a3b71","examples/cargo-example.rs":"be19a1ccb9d91882d76e7553f692ef89fa2a7acbbc1500232ce9fb60b6e8a85b","examples/demo.md":"9db305e9ff333f5e783dcc3142683280816d7bc111a57e9dcc4127f07ca44055","examples/demo.rs":"8a18ab15a235b84efd82017e51a891ed2df5f0154adbfce2806dcac089296b64","examples/derive_ref/augment_args.rs":"93fa1e122328a5d12ca4f921d17902dff6ec47b69fb2140124e2a00809ec4a1a","examples/derive_ref/augment_subcommands.rs":"5535f8ca1893101acb5eba8edc311497431ff9aa26f62f1d9743bdc147bef7a4","examples/derive_ref/custom-bool.md":"d92e441199c7584d4b888c45124366cc4802ec8ea67cdcbb3423ffaa3c5268ac","examples/derive_ref/custom-bool.rs":"f88e9c68d2447a24bc98e05124fea17836155f32cff30a2b8a03ad254383247c","examples/derive_ref/flatten_hand_args.rs":"abdb4e55b0cb71e5c4d14fe20ae0930df6888b2dca01225a02d3c6828bcbc791","examples/derive_ref/hand_subcommand.rs":"1a5464b9c5791361930b5591adeb6fcf6f14b83abdfa6443d2c80bcf0c097b3e","examples/derive_ref/interop_tests.md":"3a357e82cfc155f71e0348be33f78295aa77839c3e3a5b7c1783cbd1259e6a61","examples/escaped-positional-derive.md":"64329a454ad399cfde7cae37c2419fb68f1dfcdf2b7d809e113bab69c5f9b947","examples/escaped-positional-derive.rs":"68b0b474509d0d0b19a2ad756c15a18a9d3b30278390ddf1b7bc11b40fe5f937","examples/escaped-positional.md":"a8259da128ad7ad1f898527bb9e3c1c55541fdc2a59a8599fcddbe9cf58a3563","examples/escaped-positional.rs":"ca33f37267df8de835eeb5817e906a957e96c4ee9bd95b97abee3af25639f3c2","examples/git-derive.md":"280909b56757f102cad3a3274a92c884a0cec4e698c0f8718d2edee73fbbd810","examples/git-derive.rs":"2e8310364f2622b1b11c916643dda7392ec4a4fd585f30d537672d2fed48ea6e","examples/git.md":"31c172433b05ce581179aaba10d610de5cf097b0da894f1330a0437ef332feab","examples/git.rs":"9da386531604fc2afbd375685e213200ad10e34100ec92b4bfa6fb5730283aa1","examples/multicall-busybox.md":"0e07a2f79f94daf4586db85bf207b4bd8f0653b59858d6b4f0b66956a5b2178f","examples/multicall-busybox.rs":"709f71a82295a539d0a239371d35d1eeb517eaa3bb0a4db406bb7e5d3541a4a5","examples/multicall-hostname.md":"b547e42135269ab1e8be8dea4da6a4e99dfaa006a320fa319198d5934e1e97ab","examples/multicall-hostname.rs":"cc58a924dd2e57281f36e30481a1cbc8186952adbf149f9e1e13f9c673614fd9","examples/pacman.md":"c91e1582caf8a2cdeca208c856d1ede3f3ff26948b288a98ef69ea695f12f555","examples/pacman.rs":"f249824b950e1c34fae37afe04389143a037452a1f699c215172ac20e0285984","examples/repl.rs":"d50c1da634c237b26989994b1efa6fd1a087874a82d1fc8c1863be4ea8deaa8c","examples/tutorial_builder/01_quick.md":"80878c8630e0ecf7bb172c2645c2c17480ca5a37e5f4f481ab99e88d3a37da8e","examples/tutorial_builder/01_quick.rs":"c19b165fce9468fb3c9d3d9354a2b9829ceea7ffba6b7134d4941a6e986429a9","examples/tutorial_builder/02_app_settings.md":"f0f7b48afa7a97c9270f9d63a0e9e0f3117733ee0201639eae2199a4aca4944e","examples/tutorial_builder/02_app_settings.rs":"dd770d131726c3f37e202c9b10c969cc4eba90249c54a05594535cea6efe2749","examples/tutorial_builder/02_apps.md":"815a9197925d403b1d93969ace87e80e32667333fa83f2c86abcbdfa17cf0d7e","examples/tutorial_builder/02_apps.rs":"a7016469d10259ae0025fb6ad5b9d3c732cf082869348005d4774d2bb0722d2d","examples/tutorial_builder/02_crate.md":"086581912b34d305bb7cf3c5a35238c151bd366fac4c0923057883253731c250","examples/tutorial_builder/02_crate.rs":"2742c6a3f1946b89b4f1146893e126d68e1cf55ad4130fb94105091900421273","examples/tutorial_builder/03_01_flag_bool.md":"068378b1e76ce624dd0153dfaa9a7ae2d1a84205b1e169f5f1a16bebd50715cf","examples/tutorial_builder/03_01_flag_bool.rs":"d49b30b527faa6a383b334e572d546fab5c4b298a5549842073ab42a33a05c94","examples/tutorial_builder/03_01_flag_count.md":"8d62fbef076eac962a1d0082afa4916de22277aee973d693de33e9fd73b16669","examples/tutorial_builder/03_01_flag_count.rs":"2bfaac3aa9bcbbf37e18e74a40d966391e208d44b45a1e9c4ab61d22fd14dd40","examples/tutorial_builder/03_02_option.md":"585793524138da00c25b9fdd883b25eb8addfaf8742365d84cde63169a9289a7","examples/tutorial_builder/03_02_option.rs":"ce43934605e0438f1e8706e5e970cfcd930f76c4ebee02450ffc63de520994bd","examples/tutorial_builder/03_03_positional.md":"46fe5085841342243efd9614e80db7db3c52ae5af7c6cdd402b569d310e63fe9","examples/tutorial_builder/03_03_positional.rs":"fc7538d0fe8501c56070f0f22be699f128890636aa4ff8478cd6c7beeea279da","examples/tutorial_builder/03_04_subcommands.md":"fc5a92c5290b3cc119a6421779cdd8f4791465a1d3f50f4f29ccb08f3063a6f5","examples/tutorial_builder/03_04_subcommands.rs":"a309a332004edbed6dc14b64b1ba6cc0cd42871f3c5b8da7daab772764839c68","examples/tutorial_builder/03_05_default_values.md":"431800610a29d9a5587b74b30d709e67af5a0b8980900de20e5876fb9491144c","examples/tutorial_builder/03_05_default_values.rs":"b277be9cfe5d87958f9cf2e8a178bb007b070723528bedc8b81163aedb3a2880","examples/tutorial_builder/04_01_enum.md":"d1310efc5c8acb5ca9c86b57deebbcbd8766869284d2e8ea51e32b3eeac38439","examples/tutorial_builder/04_01_enum.rs":"596aa44bc401674a4ccf091b81b2df79b911dbb01d61fd167fd270d1e21a3609","examples/tutorial_builder/04_01_possible.md":"308cd6530b3c389bf2a82b2b66ad33025be230d84d94835273af35a90eb6a753","examples/tutorial_builder/04_01_possible.rs":"3d781b26d257061b55a957744c2dbd99c1d2346c151230fb18fe5f576d19585c","examples/tutorial_builder/04_02_parse.md":"ea14a355913fd7a8af5aac4be2bdecfda72c039b62ccadfb91ff8d39a447955e","examples/tutorial_builder/04_02_parse.rs":"a65f596341e65f41d555b38a6f5e22a5e03aac6faa4e8b3e3c85fa0e0935a2d7","examples/tutorial_builder/04_02_validate.md":"7536f4fb1a11ab94e54b6b98b7364c77912b7600803aeda5988c5b29f3f037c8","examples/tutorial_builder/04_02_validate.rs":"af6d9f748c6956aaa1006ce96834e0d013a9dbfb6d0acc63df5eb63caac56eef","examples/tutorial_builder/04_03_relations.md":"ffc6b8a2d606856fbb6cce677c5280e08eaffbe6a4c8e40cd68ce35959370ed7","examples/tutorial_builder/04_03_relations.rs":"a2dbb6d77587f64775ef57c4bb3869a2760e5c124e2870898bbf1191ef349b99","examples/tutorial_builder/04_04_custom.md":"d562fd072b5d91e8ea145771a2b6eb0284d3d21bfac707ba48ee00e92d76ad2d","examples/tutorial_builder/04_04_custom.rs":"ea0879629da2dab2d2e7fd25bdde53386d863a3e2d468e7ea306a6f8240a5522","examples/tutorial_builder/05_01_assert.rs":"69fc5a3d330be1f90055f886d65684204d7f0585459f362cf3c43b5caf4bbd7b","examples/tutorial_derive/01_quick.md":"1416029b09409468ba6b39ae5f91c41547f7f389c2534961f867ab17260638da","examples/tutorial_derive/01_quick.rs":"e17262c915199c4507d8950d5eafb73f3047e09b6dee2abbfe9f82ebf1b7ddd5","examples/tutorial_derive/02_app_settings.md":"3f4a81ebc7b674482768763bab70acf9bc31f68cc3ecb118c6f5493feaff3d42","examples/tutorial_derive/02_app_settings.rs":"7e81f4c1640b0bfbd87aedd3eda79ae7c47c669dee79b643b35e54c1dc076ee8","examples/tutorial_derive/02_apps.md":"27d22d45e438f60b346d34508a75783871e0fe9b1ae41ec759e56118a10feff7","examples/tutorial_derive/02_apps.rs":"e8cd02b5983b2203f1585b96858fade4cedfb124e366171d6b21fcb3f05b514e","examples/tutorial_derive/02_crate.md":"eb396e17db1dd68eb7689bcd806b63dbfe01ad48dfc12c285f00c42e1d4b8c1f","examples/tutorial_derive/02_crate.rs":"0b12a0790d23cee1e5d275893f428cc0af36d5532c2af00806e64c18ef9d309c","examples/tutorial_derive/03_01_flag_bool.md":"f6dd5ab050f0f1ac5924949a4ba45f248b2d4b1bd77210d78b9d8e9b3395d111","examples/tutorial_derive/03_01_flag_bool.rs":"07c31218d0332d7437d80e19c7e3c7be711bf0f56bee3ffb1c4d6f7f253b9304","examples/tutorial_derive/03_01_flag_count.md":"74d5c8a79581ceb7e6a11ec20ae59fa8c7f42591e10464aad50bbdd3d06916fc","examples/tutorial_derive/03_01_flag_count.rs":"945be42994845145b9c579b3834f8c6375f239293ded84fba35754bbe9fdcf9b","examples/tutorial_derive/03_02_option.md":"034b65008d05c1598fe3c1918f23d654d7a14cb610dd636a3c649d9d7a3b1559","examples/tutorial_derive/03_02_option.rs":"48be4cf49b498173200ad86d5d3cd64ce9381f86fdaaab70f05fc471f64a2185","examples/tutorial_derive/03_03_positional.md":"14f6b36eee218a38733b534e7b621f68a6f799bd96682a82980cba9f6e99a40e","examples/tutorial_derive/03_03_positional.rs":"f368ab1465ee4d84b84d175b97af6f64ce0676bec2482adef3ce966d2d8de26a","examples/tutorial_derive/03_04_subcommands.md":"3e1870fb10c78a01b63903060b1164f3f4d0e51c052e449abe11e2d06c252811","examples/tutorial_derive/03_04_subcommands.rs":"b25c8aec8f3816923b1154be91caafe0c2d2841fc1af5f0ef048f03d1273879e","examples/tutorial_derive/03_04_subcommands_alt.rs":"7ba6e81c2af6085b7e2721254500b34ee3e8622e20790b3c6f2786e165151b70","examples/tutorial_derive/03_05_default_values.md":"9ac52230ba7d9c214dcb64922cbf161970947d9650e8e7ea8d0ee949eba99c0e","examples/tutorial_derive/03_05_default_values.rs":"0ba14153a3c72a2435ac3688b990171a1670eb3f2f7cef21886732e489fad435","examples/tutorial_derive/04_01_enum.md":"ee57dc12a88a560d70f344629ac79cc497f96e967e97b4c643467747c8075172","examples/tutorial_derive/04_01_enum.rs":"d30abd8570357be26871c06939dee8173d34408250b6bdc3b1e76f1cbc06f888","examples/tutorial_derive/04_02_parse.md":"f191e6c77e6b133f78bd1123cec2b09c8dfe8bb17198d6348e26adade7465daf","examples/tutorial_derive/04_02_parse.rs":"fbb23ef2d98d3cb401cec9dd29d5818e4c189cc9f54fe961a2fbd08632a9634c","examples/tutorial_derive/04_02_validate.md":"c88670017d06261d454818ff18f21a06275f35d564e637c5346ce3b7fca8a02b","examples/tutorial_derive/04_02_validate.rs":"87d9c465f912b69e5839ea87404a221a39421404012c1a7fd6e327b03ceb12f0","examples/tutorial_derive/04_03_relations.md":"5657bbeee193f21a312db682cfa216f1001a94ace024c56a959985feb2e29069","examples/tutorial_derive/04_03_relations.rs":"eb8e737733261d3d1b7f4def7a05c37ba7c1c010357c7de33ee42c8adfdf6dc2","examples/tutorial_derive/04_04_custom.md":"9627d0025c5c063682387d8e00b3fb097114d1431c1ce8808038be34f781576a","examples/tutorial_derive/04_04_custom.rs":"0e745c6dab0881c62190e82e01409b70cf3286dd0983db4a612f1be88fdd1a8d","examples/tutorial_derive/05_01_assert.rs":"653450ff2e528f29b6b31d979fd7da094ea8e74b8b61a4657935c9ac2efbc28e","examples/typed-derive.md":"c22bb8da2e294f1d3725624e0c442713e5f263b10a2ee76a22ffa07f89af735a","examples/typed-derive.rs":"1c88bb1c8cec4e2e7a452552fa52675d96ffd6f201f5384b4e98d0a70fce1e4c","src/_cookbook/cargo_example.rs":"fe7594a5233e9106a159aa1f5d5f0cde0d844356f630d55c78b8ef322327d4e5","src/_cookbook/cargo_example_derive":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/_cookbook/cargo_example_derive.rs":"badf3e931ef5d5b7f5addc4912aca057ba83ee6302c43d7eeecd1661673fd407","src/_cookbook/escaped_positional.rs":"2789d8fea126355805b29e76b52c6cea4982565014087a46e0d48e4ddfbed7ab","src/_cookbook/escaped_positional_derive.rs":"802d0b672f4ed48152235d4a26a64c97fa921b361177bdd3a1a33cbac96f665d","src/_cookbook/git.rs":"372977252a22fc776e3acaa4629e964114ccd6a49b8ef334d2b6646f12e8b5ee","src/_cookbook/git_derive.rs":"4ab7c0197efda06607ca60c2a85ea743aed3494f5fe9e408d935ea0500a345fc","src/_cookbook/mod.rs":"34c53c6273512976676a82dded921f8d99e0312dd3e823ae1549606754625827","src/_cookbook/multicall_busybox.rs":"56176b4fa15e7a39c433706971d4e68aaf26ddc2a5790078b6dbe722ee13efee","src/_cookbook/multicall_hostname.rs":"907f8decf81ea4d4cbf81639ea4cd2f925eda64d4831454a7656369b65522780","src/_cookbook/pacman.rs":"863125b2d3d7931a9e4541c8ab1242b8bfcb421d8b5c604ea681efd805f68da7","src/_cookbook/repl.rs":"1393209b2cc5c203296d57c5a065b764b4318be7855e48baf16de851e250cf90","src/_cookbook/typed_derive.rs":"3d28e78cd0b068b4fcb32a7fea6244de176f2fe75dfcb59e99c33b66a7ae4864","src/_derive/_tutorial.rs":"237d316ad5f9838dc011283e454afce24d47bf2e9c5038ba5402bafeb2959090","src/_derive/mod.rs":"7f1f6b59332044681324f0753dfb51641e52f46dee74a21b8c94a413bc06be02","src/_faq.rs":"06d10de865ae34305fa973db9b00dc31f54e0f63f8fe039805aa371c36a796b9","src/_features.rs":"bbcbf1b256136d20f89e4f8a16ff37b04f07dfee0d2d4f2b013f445467628032","src/_tutorial.rs":"e7c7359b6b6c86cf6e18f4bdc3c90ce440b82bf07ce304ca2e127fb2a04cbf9f","src/bin/stdio-fixture.rs":"e8f10afbfe1857bcf986d2f55be0ca19a50c905d9f650c6e1fd42dbacf219b04","src/builder/action.rs":"beab4d8dca6337dfd64f387ee3198a88a6dcb71ec94f5bbbfe6bb4c0175ab9ee","src/builder/app_settings.rs":"17b094a5c044b2387467706bade1b19b5703bf99fc5081ac9508f410f871a1f2","src/builder/arg.rs":"e7120b60bf72d2572fc1f325b377a32da9ece4d7ac00b4a580a0f6a42c08ea8a","src/builder/arg_group.rs":"263d9c79e03015fe4e2fab4616fc73089be60fb2ec17aa2a06f3d6a24740432c","src/builder/arg_predicate.rs":"8c9fd14780cd42465f32f2e8927b97c06e686d09b5927ba3cd5bbd792af7a13d","src/builder/arg_settings.rs":"b7966dfea529a1be1164ca2d76494b1712cb2f73b024d2a23307dcd473933887","src/builder/command.rs":"57f0076465feb3cf6a0a16610b345fae8dbde8d248e4ef94111a27051c40789b","src/builder/debug_asserts.rs":"d1d5adc82cb8269445b2ef197f1e566f61e7f13d6a24afaad928e45e95aed170","src/builder/macros.rs":"904e42e72c49107ae324f45d5df24fbff13b9c7d4589f1a4ae38594add704434","src/builder/mod.rs":"205367cb5ba5d5ba7894091535ce3a5dd23b35fd436e003196d89523e7705566","src/builder/possible_value.rs":"62268b9da9eec8f4d1904ebfbd3a288fb78cfa71c357efadced28f0378bcfb93","src/builder/regex.rs":"b18891310186ecdcca9bb611833b7188cc80fe72e9fef27b63fa076b880a1acb","src/builder/tests.rs":"995c7d6be608b94c6f392f1356eba0cb8adb9ca661ffeebf7ebe6e8ad01a868c","src/builder/usage_parser.rs":"91d1af89196116aac2c0fb021f42f43f954aa3252df264e19a02a0cf5911d16b","src/builder/value_hint.rs":"0dd974d495c313430898d28b79991a70983c9aa44e88fa9aa1776d3308935438","src/builder/value_parser.rs":"64bb7f4808bdf65f30cb434198038a06db556e5ca045d900da392cc1a3186896","src/derive.rs":"11eaddc27a06229322a6bbce4458cb1424e6a5805c79166cba342c2905093b51","src/error/context.rs":"1dc561c7877d7f9b90f04bb7915744f0b3cc4ac2aa928ae100b2825a97077142","src/error/kind.rs":"3b4f9dfe5be5843cec8380c8f8965dcb9d0beee0aaa02cadf8dcffd400626ede","src/error/mod.rs":"e5b60fee401975d95c460c2567d09e17972eaae336154a8b90d9c806083f63fa","src/lib.rs":"4a197eab3f447c58a266af4f9a787af5c98b18f4612f33d9189cce52f4f9de18","src/macros.rs":"72585e32051a6872bbb29e39f7e9f9a88334a03f39ec3c768984db2f38211001","src/mkeymap.rs":"3565a5bae5d6cdcf8ba41a24eb602c510a14e150c4a6d3085ad72a35778e9c5f","src/output/fmt.rs":"efb741b5854500d946c6c09763ece1badc2b9cd3efa616cb58012039836c2b7f","src/output/help.rs":"ebdd123d6b70279c25af4b08432b547498834853adf99821ff6c6cd65dd87d4e","src/output/mod.rs":"3a61f89a4568e95114a3ab839da8f3c4c92de2a228549308f5d1be076a474917","src/output/usage.rs":"1921d2fa362f111b3f9613fc98eb5e24686483fe112b337855da7eb17b643f71","src/parser/arg_matcher.rs":"0c9ae639ed241e8ff1f62cd9e5eab2de9e5db1be0e86f58d5d94619d6dad05fd","src/parser/error.rs":"51e8fbd7cc73bba78cca50417e9b4fb25e11eefc60ff4b957940176bdb995e5c","src/parser/features/mod.rs":"6ed075e97af56bff22f22ed1ee83ff6479360e05f9d3661a3145f822c242b694","src/parser/features/suggestions.rs":"79127956b2f1adb9d658925e2779ebebfe9ddea434408762fefb60afdb545f47","src/parser/matches/any_value.rs":"7b6e711fe205e8808394c562dd6a260b56ce350cf9298a308ba9727ab012b664","src/parser/matches/arg_matches.rs":"666e3640b5347aba5806fc15b5caa599b171e684ee15d933ddc7f8185a0d2032","src/parser/matches/matched_arg.rs":"fb12eb2afaf631bb60aa8c4e42b0f510a877d35a9eaa07a7afd253280c27c251","src/parser/matches/mod.rs":"1467aa752cb1c79d30e4aeaaa55e10a0bb9dcf6f3980496234251431c79c49e6","src/parser/matches/value_source.rs":"e6a477ae36f2f7155960239a97b7d142eef4eb227c41c9eefea147289547d713","src/parser/mod.rs":"358f46d3b7f43dec2563d4c35bd2536fab2491f28e300a9bcdeaf6ca0513ce12","src/parser/parser.rs":"9e338dfd60aa8bfbcfbbda15c73d4722767a4d2e7b8f8ed3a07c296ddd98762c","src/parser/validator.rs":"30066cb41ab23800231fb6b028cbce57d118570859659ebc67affbe5226f31f9","src/util/color.rs":"63df5e1cda1001b4c536dc0b04e09dd85dae6d317e34e660abbe3c71e17eaa29","src/util/fnv.rs":"82492d91d990f38b62de8b3c3e67f1fad55919117b1f448aa28acf6d21919fd7","src/util/graph.rs":"f35396b6e2a427377dcbbca69b1b98737d89684a3834cfda98cbf8cc70ff9c2f","src/util/id.rs":"fc498c65887385d92a51359a2f72556c2e508ee49b8cac4b3f827512795d690d","src/util/mod.rs":"8d328a15ef06989d0ce5e65cf3b7ec79c083984b25c0b31ba177bdb22df28a10","src/util/str_to_bool.rs":"1ce90b4939a884eeefc73392722bdfcf906e3070c4398e1557c586c10c684cd0"},"package":"23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"} \ No newline at end of file diff --git a/vendor/clap/Cargo.lock b/vendor/clap/Cargo.lock deleted file mode 100644 index 57d007104..000000000 --- a/vendor/clap/Cargo.lock +++ /dev/null @@ -1,746 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bytes" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "3.2.20" -dependencies = [ - "atty", - "backtrace", - "bitflags", - "clap_derive", - "clap_lex", - "humantime", - "indexmap", - "once_cell", - "regex", - "rustversion", - "shlex", - "snapbox", - "static_assertions", - "strsim", - "termcolor", - "terminal_size", - "textwrap", - "trybuild", - "trycmd", - "unicase", - "yaml-rust", -] - -[[package]] -name = "clap_derive" -version = "3.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "combine" -version = "4.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "concolor" -version = "0.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015267563b1df20adccdd00cb05257b1dfbea70a04928e9cf88ffb850c1a40af" -dependencies = [ - "atty", - "bitflags", - "concolor-query", -] - -[[package]] -name = "concolor-query" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449" - -[[package]] -name = "crossbeam-channel" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "once_cell", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "either" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" - -[[package]] -name = "escargot" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" -dependencies = [ - "log", - "once_cell", - "serde", - "serde_json", -] - -[[package]] -name = "gimli" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "humantime-serde" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" -dependencies = [ - "humantime", - "serde", -] - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" - -[[package]] -name = "os_pipe" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c92f2b54f081d635c77e7120862d48db8e91f7f21cef23ab1b4fe9971c59f55" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" - -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustversion" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "shlex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" - -[[package]] -name = "similar" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" - -[[package]] -name = "snapbox" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767a1d5da232b6959cd1bd5c9e8db8a7cce09c3038e89deedb49a549a2aefd93" -dependencies = [ - "concolor", - "normalize-line-endings", - "os_pipe", - "similar", - "snapbox-macros", - "wait-timeout", - "yansi", -] - -[[package]] -name = "snapbox-macros" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" -dependencies = [ - "terminal_size", - "unicode-width", -] - -[[package]] -name = "toml" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f" -dependencies = [ - "combine", - "indexmap", - "itertools", - "serde", -] - -[[package]] -name = "trybuild" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "764b9e244b482a9b81bde596aa37aa6f1347bf8007adab25e59f901b32b4e0a0" -dependencies = [ - "glob", - "once_cell", - "serde", - "serde_derive", - "serde_json", - "termcolor", - "toml", -] - -[[package]] -name = "trycmd" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4185126cc904642173a54c185083f410c86d1202ada6761aacf7c40829f13" -dependencies = [ - "escargot", - "glob", - "humantime", - "humantime-serde", - "rayon", - "serde", - "shlex", - "snapbox", - "toml_edit", -] - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-ident" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/vendor/clap/Cargo.toml b/vendor/clap/Cargo.toml deleted file mode 100644 index 197454c07..000000000 --- a/vendor/clap/Cargo.toml +++ /dev/null @@ -1,471 +0,0 @@ -# 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 = "2021" -rust-version = "1.56.1" -name = "clap" -version = "3.2.20" -include = [ - "build.rs", - "src/**/*", - "Cargo.toml", - "LICENSE*", - "README.md", - "benches/**/*", - "examples/**/*", -] -description = "A simple to use, efficient, and full-featured Command Line Argument Parser" -readme = "README.md" -keywords = [ - "argument", - "cli", - "arg", - "parser", - "parse", -] -categories = ["command-line-interface"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/clap-rs/clap" -resolver = "2" - -[package.metadata.docs.rs] -features = ["unstable-doc"] -rustdoc-args = [ - "--cfg", - "docsrs", -] -cargo-args = [ - "-Zunstable-options", - "-Zrustdoc-scrape-examples=examples", -] - -[package.metadata.playground] -features = ["unstable-doc"] - -[package.metadata.release] -shared-version = true -tag-name = "v{{version}}" - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "Unreleased" -replace = "{{version}}" -min = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = '\.\.\.HEAD' -replace = "...{{tag_name}}" -exactly = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "ReleaseDate" -replace = "{{date}}" -min = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "" -replace = """ - -## [Unreleased] - ReleaseDate -""" -exactly = 1 - -[[package.metadata.release.pre-release-replacements]] -file = "CHANGELOG.md" -search = "" -replace = """ - -[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD""" -exactly = 1 - -[profile.bench] -lto = true -codegen-units = 1 - -[profile.test] -opt-level = 1 - -[lib] -bench = false - -[[example]] -name = "demo" -required-features = ["derive"] - -[[example]] -name = "cargo-example" -required-features = ["cargo"] - -[[example]] -name = "cargo-example-derive" -required-features = ["derive"] - -[[example]] -name = "escaped-positional" -required-features = ["cargo"] - -[[example]] -name = "escaped-positional-derive" -required-features = ["derive"] - -[[example]] -name = "git-derive" -required-features = ["derive"] - -[[example]] -name = "typed-derive" -required-features = ["derive"] - -[[example]] -name = "busybox" -path = "examples/multicall-busybox.rs" - -[[example]] -name = "hostname" -path = "examples/multicall-hostname.rs" - -[[example]] -name = "repl" -path = "examples/repl.rs" - -[[example]] -name = "01_quick" -path = "examples/tutorial_builder/01_quick.rs" -required-features = ["cargo"] - -[[example]] -name = "02_apps" -path = "examples/tutorial_builder/02_apps.rs" - -[[example]] -name = "02_crate" -path = "examples/tutorial_builder/02_crate.rs" -required-features = ["cargo"] - -[[example]] -name = "02_app_settings" -path = "examples/tutorial_builder/02_app_settings.rs" -required-features = ["cargo"] - -[[example]] -name = "03_01_flag_bool" -path = "examples/tutorial_builder/03_01_flag_bool.rs" -required-features = ["cargo"] - -[[example]] -name = "03_01_flag_count" -path = "examples/tutorial_builder/03_01_flag_count.rs" -required-features = ["cargo"] - -[[example]] -name = "03_02_option" -path = "examples/tutorial_builder/03_02_option.rs" -required-features = ["cargo"] - -[[example]] -name = "03_03_positional" -path = "examples/tutorial_builder/03_03_positional.rs" -required-features = ["cargo"] - -[[example]] -name = "03_04_subcommands" -path = "examples/tutorial_builder/03_04_subcommands.rs" -required-features = ["cargo"] - -[[example]] -name = "03_05_default_values" -path = "examples/tutorial_builder/03_05_default_values.rs" -required-features = ["cargo"] - -[[example]] -name = "04_01_possible" -path = "examples/tutorial_builder/04_01_possible.rs" -required-features = ["cargo"] - -[[example]] -name = "04_01_enum" -path = "examples/tutorial_builder/04_01_enum.rs" -required-features = ["cargo"] - -[[example]] -name = "04_02_parse" -path = "examples/tutorial_builder/04_02_parse.rs" -required-features = ["cargo"] - -[[example]] -name = "04_02_validate" -path = "examples/tutorial_builder/04_02_validate.rs" -required-features = ["cargo"] - -[[example]] -name = "04_03_relations" -path = "examples/tutorial_builder/04_03_relations.rs" -required-features = ["cargo"] - -[[example]] -name = "04_04_custom" -path = "examples/tutorial_builder/04_04_custom.rs" -required-features = ["cargo"] - -[[example]] -name = "05_01_assert" -path = "examples/tutorial_builder/05_01_assert.rs" -test = true -required-features = ["cargo"] - -[[example]] -name = "01_quick_derive" -path = "examples/tutorial_derive/01_quick.rs" -required-features = ["derive"] - -[[example]] -name = "02_apps_derive" -path = "examples/tutorial_derive/02_apps.rs" -required-features = ["derive"] - -[[example]] -name = "02_crate_derive" -path = "examples/tutorial_derive/02_crate.rs" -required-features = ["derive"] - -[[example]] -name = "02_app_settings_derive" -path = "examples/tutorial_derive/02_app_settings.rs" -required-features = ["derive"] - -[[example]] -name = "03_01_flag_bool_derive" -path = "examples/tutorial_derive/03_01_flag_bool.rs" -required-features = ["derive"] - -[[example]] -name = "03_01_flag_count_derive" -path = "examples/tutorial_derive/03_01_flag_count.rs" -required-features = ["derive"] - -[[example]] -name = "03_02_option_derive" -path = "examples/tutorial_derive/03_02_option.rs" -required-features = ["derive"] - -[[example]] -name = "03_03_positional_derive" -path = "examples/tutorial_derive/03_03_positional.rs" -required-features = ["derive"] - -[[example]] -name = "03_04_subcommands_derive" -path = "examples/tutorial_derive/03_04_subcommands.rs" -required-features = ["derive"] - -[[example]] -name = "03_04_subcommands_alt_derive" -path = "examples/tutorial_derive/03_04_subcommands_alt.rs" -required-features = ["derive"] - -[[example]] -name = "03_05_default_values_derive" -path = "examples/tutorial_derive/03_05_default_values.rs" -required-features = ["derive"] - -[[example]] -name = "04_01_enum_derive" -path = "examples/tutorial_derive/04_01_enum.rs" -required-features = ["derive"] - -[[example]] -name = "04_02_parse_derive" -path = "examples/tutorial_derive/04_02_parse.rs" -required-features = ["derive"] - -[[example]] -name = "04_02_validate_derive" -path = "examples/tutorial_derive/04_02_validate.rs" -required-features = ["derive"] - -[[example]] -name = "04_03_relations_derive" -path = "examples/tutorial_derive/04_03_relations.rs" -required-features = ["derive"] - -[[example]] -name = "04_04_custom_derive" -path = "examples/tutorial_derive/04_04_custom.rs" -required-features = ["derive"] - -[[example]] -name = "05_01_assert_derive" -path = "examples/tutorial_derive/05_01_assert.rs" -test = true -required-features = ["derive"] - -[[example]] -name = "custom-bool" -path = "examples/derive_ref/custom-bool.rs" -required-features = ["derive"] - -[[example]] -name = "interop_augment_args" -path = "examples/derive_ref/augment_args.rs" -required-features = ["derive"] - -[[example]] -name = "interop_augment_subcommands" -path = "examples/derive_ref/augment_subcommands.rs" -required-features = ["derive"] - -[[example]] -name = "interop_hand_subcommand" -path = "examples/derive_ref/hand_subcommand.rs" -required-features = ["derive"] - -[[example]] -name = "interop_flatten_hand_args" -path = "examples/derive_ref/flatten_hand_args.rs" -required-features = ["derive"] - -[dependencies.atty] -version = "0.2" -optional = true - -[dependencies.backtrace] -version = "0.3" -optional = true - -[dependencies.bitflags] -version = "1.2" - -[dependencies.clap_derive] -version = "=3.2.18" -optional = true - -[dependencies.clap_lex] -version = "0.2.2" - -[dependencies.indexmap] -version = "1.0" - -[dependencies.once_cell] -version = "1.12.0" -optional = true - -[dependencies.regex] -version = "1.0" -optional = true - -[dependencies.strsim] -version = "0.10" -optional = true - -[dependencies.termcolor] -version = "1.1.1" -optional = true - -[dependencies.terminal_size] -version = "0.1.12" -optional = true - -[dependencies.textwrap] -version = "0.15.0" -features = [] -default-features = false - -[dependencies.unicase] -version = "2.6" -optional = true - -[dependencies.yaml-rust] -version = "0.4.1" -optional = true - -[dev-dependencies.humantime] -version = "2" - -[dev-dependencies.regex] -version = "1.0" - -[dev-dependencies.rustversion] -version = "1" - -[dev-dependencies.shlex] -version = "1.1.0" - -[dev-dependencies.snapbox] -version = "0.2.9" - -[dev-dependencies.static_assertions] -version = "1.1.0" - -[dev-dependencies.trybuild] -version = "1.0.18" - -[dev-dependencies.trycmd] -version = "0.13" -features = [ - "color-auto", - "diff", - "examples", -] -default-features = false - -[features] -cargo = ["once_cell"] -color = [ - "atty", - "termcolor", -] -debug = [ - "clap_derive/debug", - "backtrace", -] -default = [ - "std", - "color", - "suggestions", -] -deprecated = ["clap_derive/deprecated"] -derive = [ - "clap_derive", - "once_cell", -] -env = [] -std = ["indexmap/std"] -suggestions = ["strsim"] -unicode = [ - "textwrap/unicode-width", - "unicase", -] -unstable-doc = [ - "derive", - "cargo", - "wrap_help", - "yaml", - "env", - "unicode", - "regex", - "unstable-replace", - "unstable-grouped", -] -unstable-grouped = [] -unstable-replace = [] -unstable-v4 = [ - "clap_derive/unstable-v4", - "deprecated", -] -wrap_help = [ - "terminal_size", - "textwrap/terminal_size", -] -yaml = ["yaml-rust"] diff --git a/vendor/clap/LICENSE-APACHE b/vendor/clap/LICENSE-APACHE deleted file mode 100644 index 261eeb9e9..000000000 --- a/vendor/clap/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - 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 [yyyy] [name of copyright owner] - - 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. diff --git a/vendor/clap/LICENSE-MIT b/vendor/clap/LICENSE-MIT deleted file mode 100644 index 7b05b8453..000000000 --- a/vendor/clap/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2022 Kevin B. Knapp and Clap 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. diff --git a/vendor/clap/README.md b/vendor/clap/README.md deleted file mode 100644 index eea6ba6f0..000000000 --- a/vendor/clap/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# clap - -> **Command Line Argument Parser for Rust** - -[![Crates.io](https://img.shields.io/crates/v/clap?style=flat-square)](https://crates.io/crates/clap) -[![Crates.io](https://img.shields.io/crates/d/clap?style=flat-square)](https://crates.io/crates/clap) -[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](LICENSE-APACHE) -[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE-MIT) -[![Build Status](https://img.shields.io/github/workflow/status/clap-rs/clap/CI/staging?style=flat-square)](https://github.com/clap-rs/clap/actions/workflows/ci.yml?query=branch%3Astaging) -[![Coverage Status](https://img.shields.io/coveralls/github/clap-rs/clap/master?style=flat-square)](https://coveralls.io/github/clap-rs/clap?branch=master) -[![Contributors](https://img.shields.io/github/contributors/clap-rs/clap?style=flat-square)](https://github.com/clap-rs/clap/graphs/contributors) - -Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). - -## About - -Create your command-line parser, with all of the bells and whistles, declaratively or procedurally. - -For more details, see: -- [docs.rs](https://docs.rs/clap/latest/clap/) -- [examples](examples/) - -## Sponsors - - -### Gold - -[![](https://opencollective.com/clap/tiers/gold.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) - - -### Silver - -[![](https://opencollective.com/clap/tiers/silver.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) - - -### Bronze - -[![](https://opencollective.com/clap/tiers/bronze.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) - - -### Backer - -[![](https://opencollective.com/clap/tiers/backer.svg?avatarHeight=36&width=600)](https://opencollective.com/clap) diff --git a/vendor/clap/examples/cargo-example-derive.md b/vendor/clap/examples/cargo-example-derive.md deleted file mode 100644 index 2c7a11b88..000000000 --- a/vendor/clap/examples/cargo-example-derive.md +++ /dev/null @@ -1,43 +0,0 @@ -For more on creating a custom subcommand, see [the cargo -book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands). -The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in -mimicking cargo's interface. - -The help looks like: -```console -$ cargo-example-derive --help -cargo - -USAGE: - cargo - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - example-derive A simple to use, efficient, and full-featured Command Line Argument Parser - help Print this message or the help of the given subcommand(s) - -$ cargo-example-derive example-derive --help -cargo-example-derive [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - cargo example-derive [OPTIONS] - -OPTIONS: - -h, --help Print help information - --manifest-path - -V, --version Print version information - -``` - -Then to directly invoke the command, run: -```console -$ cargo-example-derive example-derive -None - -$ cargo-example-derive example-derive --manifest-path Cargo.toml -Some("Cargo.toml") - -``` diff --git a/vendor/clap/examples/cargo-example-derive.rs b/vendor/clap/examples/cargo-example-derive.rs deleted file mode 100644 index f0aad29c7..000000000 --- a/vendor/clap/examples/cargo-example-derive.rs +++ /dev/null @@ -1,20 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] // requires `derive` feature -#[clap(name = "cargo")] -#[clap(bin_name = "cargo")] -enum Cargo { - ExampleDerive(ExampleDerive), -} - -#[derive(clap::Args)] -#[clap(author, version, about, long_about = None)] -struct ExampleDerive { - #[clap(long, value_parser)] - manifest_path: Option, -} - -fn main() { - let Cargo::ExampleDerive(args) = Cargo::parse(); - println!("{:?}", args.manifest_path); -} diff --git a/vendor/clap/examples/cargo-example.md b/vendor/clap/examples/cargo-example.md deleted file mode 100644 index 6fb6a3c4d..000000000 --- a/vendor/clap/examples/cargo-example.md +++ /dev/null @@ -1,43 +0,0 @@ -For more on creating a custom subcommand, see [the cargo -book](https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands). -The crate [`clap-cargo`](https://github.com/crate-ci/clap-cargo) can help in -mimicking cargo's interface. - -The help looks like: -```console -$ cargo-example --help -cargo - -USAGE: - cargo - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - example A simple to use, efficient, and full-featured Command Line Argument Parser - help Print this message or the help of the given subcommand(s) - -$ cargo-example example --help -cargo-example [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - cargo example [OPTIONS] - -OPTIONS: - -h, --help Print help information - --manifest-path - -V, --version Print version information - -``` - -Then to directly invoke the command, run: -```console -$ cargo-example example -None - -$ cargo-example example --manifest-path Cargo.toml -Some("Cargo.toml") - -``` diff --git a/vendor/clap/examples/cargo-example.rs b/vendor/clap/examples/cargo-example.rs deleted file mode 100644 index d9a909f4f..000000000 --- a/vendor/clap/examples/cargo-example.rs +++ /dev/null @@ -1,19 +0,0 @@ -fn main() { - let cmd = clap::Command::new("cargo") - .bin_name("cargo") - .subcommand_required(true) - .subcommand( - clap::command!("example").arg( - clap::arg!(--"manifest-path" ) - .required(false) - .value_parser(clap::value_parser!(std::path::PathBuf)), - ), - ); - let matches = cmd.get_matches(); - let matches = match matches.subcommand() { - Some(("example", matches)) => matches, - _ => unreachable!("clap should ensure we don't get here"), - }; - let manifest_path = matches.get_one::("manifest-path"); - println!("{:?}", manifest_path); -} diff --git a/vendor/clap/examples/demo.md b/vendor/clap/examples/demo.md deleted file mode 100644 index 93ee49c37..000000000 --- a/vendor/clap/examples/demo.md +++ /dev/null @@ -1,19 +0,0 @@ -```console -$ demo --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - demo[EXE] [OPTIONS] --name - -OPTIONS: - -c, --count Number of times to greet [default: 1] - -h, --help Print help information - -n, --name Name of the person to greet - -V, --version Print version information - -$ demo --name Me -Hello Me! - -``` -*(version number and `.exe` extension on windows replaced by placeholders)* diff --git a/vendor/clap/examples/demo.rs b/vendor/clap/examples/demo.rs deleted file mode 100644 index a7cecfb0c..000000000 --- a/vendor/clap/examples/demo.rs +++ /dev/null @@ -1,22 +0,0 @@ -use clap::Parser; - -/// Simple program to greet a person -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] -struct Args { - /// Name of the person to greet - #[clap(short, long, value_parser)] - name: String, - - /// Number of times to greet - #[clap(short, long, value_parser, default_value_t = 1)] - count: u8, -} - -fn main() { - let args = Args::parse(); - - for _ in 0..args.count { - println!("Hello {}!", args.name) - } -} diff --git a/vendor/clap/examples/derive_ref/augment_args.rs b/vendor/clap/examples/derive_ref/augment_args.rs deleted file mode 100644 index 310556914..000000000 --- a/vendor/clap/examples/derive_ref/augment_args.rs +++ /dev/null @@ -1,27 +0,0 @@ -use clap::{arg, Args, Command, FromArgMatches as _}; - -#[derive(Args, Debug)] -struct DerivedArgs { - #[clap(short, long, action)] - derived: bool, -} - -fn main() { - let cli = Command::new("CLI").arg(arg!(-b - -built).action(clap::ArgAction::SetTrue)); - // Augment built args with derived args - let cli = DerivedArgs::augment_args(cli); - - let matches = cli.get_matches(); - println!("Value of built: {:?}", matches.get_flag("built")); - println!( - "Value of derived via ArgMatches: {:?}", - matches.get_flag("derived") - ); - - // Since DerivedArgs implements FromArgMatches, we can extract it from the unstructured ArgMatches. - // This is the main benefit of using derived arguments. - let derived_matches = DerivedArgs::from_arg_matches(&matches) - .map_err(|err| err.exit()) - .unwrap(); - println!("Value of derived: {:#?}", derived_matches); -} diff --git a/vendor/clap/examples/derive_ref/augment_subcommands.rs b/vendor/clap/examples/derive_ref/augment_subcommands.rs deleted file mode 100644 index 199da98b4..000000000 --- a/vendor/clap/examples/derive_ref/augment_subcommands.rs +++ /dev/null @@ -1,21 +0,0 @@ -use clap::{Command, FromArgMatches as _, Parser, Subcommand as _}; - -#[derive(Parser, Debug)] -enum Subcommands { - Derived { - #[clap(short, long, action)] - derived_flag: bool, - }, -} - -fn main() { - let cli = Command::new("Built CLI"); - // Augment with derived subcommands - let cli = Subcommands::augment_subcommands(cli); - - let matches = cli.get_matches(); - let derived_subcommands = Subcommands::from_arg_matches(&matches) - .map_err(|err| err.exit()) - .unwrap(); - println!("Derived subcommands: {:#?}", derived_subcommands); -} diff --git a/vendor/clap/examples/derive_ref/custom-bool.md b/vendor/clap/examples/derive_ref/custom-bool.md deleted file mode 100644 index 619f9ba8e..000000000 --- a/vendor/clap/examples/derive_ref/custom-bool.md +++ /dev/null @@ -1,47 +0,0 @@ -*Jump to [source](custom-bool.rs)* - -Example of overriding the magic `bool` behavior - -```console -$ custom-bool --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - custom-bool[EXE] [OPTIONS] --foo - -ARGS: - [possible values: true, false] - -OPTIONS: - --bar [default: false] - --foo [possible values: true, false] - -h, --help Print help information - -V, --version Print version information - -$ custom-bool -? failed -error: The following required arguments were not provided: - --foo - - -USAGE: - custom-bool[EXE] [OPTIONS] --foo - -For more information try --help - -$ custom-bool --foo true false -[examples/derive_ref/custom-bool.rs:31] opt = Opt { - foo: true, - bar: false, - boom: false, -} - -$ custom-bool --foo true --bar true false -[examples/derive_ref/custom-bool.rs:31] opt = Opt { - foo: true, - bar: true, - boom: false, -} - -``` diff --git a/vendor/clap/examples/derive_ref/custom-bool.rs b/vendor/clap/examples/derive_ref/custom-bool.rs deleted file mode 100644 index d3c321e72..000000000 --- a/vendor/clap/examples/derive_ref/custom-bool.rs +++ /dev/null @@ -1,32 +0,0 @@ -use clap::Parser; - -#[derive(Parser, Debug, PartialEq)] -#[clap(author, version, about, long_about = None)] -struct Opt { - // Default parser for `Set` is FromStr::from_str. - // `impl FromStr for bool` parses `true` or `false` so this - // works as expected. - #[clap(long, action = clap::ArgAction::Set)] - foo: bool, - - // Of course, this could be done with an explicit parser function. - #[clap(long, action = clap::ArgAction::Set, value_parser = true_or_false, default_value_t)] - bar: bool, - - // `bool` can be positional only with explicit `action` annotation - #[clap(action = clap::ArgAction::Set)] - boom: bool, -} - -fn true_or_false(s: &str) -> Result { - match s { - "true" => Ok(true), - "false" => Ok(false), - _ => Err("expected `true` or `false`"), - } -} - -fn main() { - let opt = Opt::parse(); - dbg!(opt); -} diff --git a/vendor/clap/examples/derive_ref/flatten_hand_args.rs b/vendor/clap/examples/derive_ref/flatten_hand_args.rs deleted file mode 100644 index c10e0b29f..000000000 --- a/vendor/clap/examples/derive_ref/flatten_hand_args.rs +++ /dev/null @@ -1,81 +0,0 @@ -use clap::error::Error; -use clap::{Arg, ArgAction, ArgMatches, Args, Command, FromArgMatches, Parser}; - -#[derive(Debug)] -struct CliArgs { - foo: bool, - bar: bool, - quuz: Option, -} - -impl FromArgMatches for CliArgs { - fn from_arg_matches(matches: &ArgMatches) -> Result { - let mut matches = matches.clone(); - Self::from_arg_matches_mut(&mut matches) - } - fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { - Ok(Self { - foo: matches.get_flag("foo"), - bar: matches.get_flag("bar"), - quuz: matches.remove_one::("quuz"), - }) - } - fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { - let mut matches = matches.clone(); - self.update_from_arg_matches_mut(&mut matches) - } - fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { - self.foo |= matches.get_flag("foo"); - self.bar |= matches.get_flag("bar"); - if let Some(quuz) = matches.remove_one::("quuz") { - self.quuz = Some(quuz); - } - Ok(()) - } -} - -impl Args for CliArgs { - fn augment_args(cmd: Command<'_>) -> Command<'_> { - cmd.arg( - Arg::new("foo") - .short('f') - .long("foo") - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new("bar") - .short('b') - .long("bar") - .action(ArgAction::SetTrue), - ) - .arg(Arg::new("quuz").short('q').long("quuz").takes_value(true)) - } - fn augment_args_for_update(cmd: Command<'_>) -> Command<'_> { - cmd.arg( - Arg::new("foo") - .short('f') - .long("foo") - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new("bar") - .short('b') - .long("bar") - .action(ArgAction::SetTrue), - ) - .arg(Arg::new("quuz").short('q').long("quuz").takes_value(true)) - } -} - -#[derive(Parser, Debug)] -struct Cli { - #[clap(short, long, action)] - top_level: bool, - #[clap(flatten)] - more_args: CliArgs, -} - -fn main() { - let args = Cli::parse(); - println!("{:#?}", args); -} diff --git a/vendor/clap/examples/derive_ref/hand_subcommand.rs b/vendor/clap/examples/derive_ref/hand_subcommand.rs deleted file mode 100644 index e9423bdc0..000000000 --- a/vendor/clap/examples/derive_ref/hand_subcommand.rs +++ /dev/null @@ -1,81 +0,0 @@ -use clap::error::{Error, ErrorKind}; -use clap::{ArgMatches, Args as _, Command, FromArgMatches, Parser, Subcommand}; - -#[derive(Parser, Debug)] -struct AddArgs { - #[clap(value_parser)] - name: Vec, -} -#[derive(Parser, Debug)] -struct RemoveArgs { - #[clap(short, long, action)] - force: bool, - #[clap(value_parser)] - name: Vec, -} - -#[derive(Debug)] -enum CliSub { - Add(AddArgs), - Remove(RemoveArgs), -} - -impl FromArgMatches for CliSub { - fn from_arg_matches(matches: &ArgMatches) -> Result { - match matches.subcommand() { - Some(("add", args)) => Ok(Self::Add(AddArgs::from_arg_matches(args)?)), - Some(("remove", args)) => Ok(Self::Remove(RemoveArgs::from_arg_matches(args)?)), - Some((_, _)) => Err(Error::raw( - ErrorKind::UnrecognizedSubcommand, - "Valid subcommands are `add` and `remove`", - )), - None => Err(Error::raw( - ErrorKind::MissingSubcommand, - "Valid subcommands are `add` and `remove`", - )), - } - } - fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { - match matches.subcommand() { - Some(("add", args)) => *self = Self::Add(AddArgs::from_arg_matches(args)?), - Some(("remove", args)) => *self = Self::Remove(RemoveArgs::from_arg_matches(args)?), - Some((_, _)) => { - return Err(Error::raw( - ErrorKind::UnrecognizedSubcommand, - "Valid subcommands are `add` and `remove`", - )) - } - None => (), - }; - Ok(()) - } -} - -impl Subcommand for CliSub { - fn augment_subcommands(cmd: Command<'_>) -> Command<'_> { - cmd.subcommand(AddArgs::augment_args(Command::new("add"))) - .subcommand(RemoveArgs::augment_args(Command::new("remove"))) - .subcommand_required(true) - } - fn augment_subcommands_for_update(cmd: Command<'_>) -> Command<'_> { - cmd.subcommand(AddArgs::augment_args(Command::new("add"))) - .subcommand(RemoveArgs::augment_args(Command::new("remove"))) - .subcommand_required(true) - } - fn has_subcommand(name: &str) -> bool { - matches!(name, "add" | "remove") - } -} - -#[derive(Parser, Debug)] -struct Cli { - #[clap(short, long, action)] - top_level: bool, - #[clap(subcommand)] - subcommand: CliSub, -} - -fn main() { - let args = Cli::parse(); - println!("{:#?}", args); -} diff --git a/vendor/clap/examples/derive_ref/interop_tests.md b/vendor/clap/examples/derive_ref/interop_tests.md deleted file mode 100644 index 746fe1878..000000000 --- a/vendor/clap/examples/derive_ref/interop_tests.md +++ /dev/null @@ -1,256 +0,0 @@ -Following are tests for the interop examples in this directory. - -## Augment Args - -```console -$ interop_augment_args -Value of built: false -Value of derived via ArgMatches: false -Value of derived: DerivedArgs { - derived: false, -} - -``` - -```console -$ interop_augment_args -b --derived -Value of built: true -Value of derived via ArgMatches: true -Value of derived: DerivedArgs { - derived: true, -} - -``` - -```console -$ interop_augment_args -d --built -Value of built: true -Value of derived via ArgMatches: true -Value of derived: DerivedArgs { - derived: true, -} - -``` - -```console -$ interop_augment_args --unknown -? failed -error: Found argument '--unknown' which wasn't expected, or isn't valid in this context - - If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` - -USAGE: - interop_augment_args[EXE] [OPTIONS] - -For more information try --help - -``` - -## Augment Subcommands - -```console -$ interop_augment_subcommands -? failed -error: A subcommand is required but one was not provided. -``` - -```console -$ interop_augment_subcommands derived -Derived subcommands: Derived { - derived_flag: false, -} - -``` - -```console -$ interop_augment_subcommands derived --derived-flag -Derived subcommands: Derived { - derived_flag: true, -} - -``` - -```console -$ interop_augment_subcommands derived --unknown -? failed -error: Found argument '--unknown' which wasn't expected, or isn't valid in this context - - If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` - -USAGE: - interop_augment_subcommands[EXE] derived [OPTIONS] - -For more information try --help - -``` - -```console -$ interop_augment_subcommands unknown -? failed -error: Found argument 'unknown' which wasn't expected, or isn't valid in this context - -USAGE: - interop_augment_subcommands[EXE] [SUBCOMMAND] - -For more information try --help - -``` - -## Hand-Implemented Subcommand - -```console -$ interop_hand_subcommand -? failed -error: 'interop_hand_subcommand[EXE]' requires a subcommand but one was not provided - -USAGE: - interop_hand_subcommand[EXE] [OPTIONS] - -For more information try --help - -``` - -```console -$ interop_hand_subcommand add -Cli { - top_level: false, - subcommand: Add( - AddArgs { - name: [], - }, - ), -} - -``` - -```console -$ interop_hand_subcommand add a b c -Cli { - top_level: false, - subcommand: Add( - AddArgs { - name: [ - "a", - "b", - "c", - ], - }, - ), -} - -``` - -```console -$ interop_hand_subcommand add --unknown -? failed -error: Found argument '--unknown' which wasn't expected, or isn't valid in this context - - If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` - -USAGE: - interop_hand_subcommand[EXE] add [NAME]... - -For more information try --help - -``` - -```console -$ interop_hand_subcommand remove -Cli { - top_level: false, - subcommand: Remove( - RemoveArgs { - force: false, - name: [], - }, - ), -} - -``` - -```console -$ interop_hand_subcommand remove --force a b c -Cli { - top_level: false, - subcommand: Remove( - RemoveArgs { - force: true, - name: [ - "a", - "b", - "c", - ], - }, - ), -} - -``` - -```console -$ interop_hand_subcommand unknown -? failed -error: Found argument 'unknown' which wasn't expected, or isn't valid in this context - -USAGE: - interop_hand_subcommand[EXE] [OPTIONS] - -For more information try --help - -``` - -## Flatten Hand-Implemented Args - -```console -$ interop_flatten_hand_args -Cli { - top_level: false, - more_args: CliArgs { - foo: false, - bar: false, - quuz: None, - }, -} - -``` - -```console -$ interop_flatten_hand_args -f --bar -Cli { - top_level: false, - more_args: CliArgs { - foo: true, - bar: true, - quuz: None, - }, -} - -``` - -```console -$ interop_flatten_hand_args --quuz abc -Cli { - top_level: false, - more_args: CliArgs { - foo: false, - bar: false, - quuz: Some( - "abc", - ), - }, -} - -``` - -```console -$ interop_flatten_hand_args --unknown -? failed -error: Found argument '--unknown' which wasn't expected, or isn't valid in this context - - If you tried to supply `--unknown` as a value rather than a flag, use `-- --unknown` - -USAGE: - interop_flatten_hand_args[EXE] [OPTIONS] - -For more information try --help - -``` diff --git a/vendor/clap/examples/escaped-positional-derive.md b/vendor/clap/examples/escaped-positional-derive.md deleted file mode 100644 index fa39a2c03..000000000 --- a/vendor/clap/examples/escaped-positional-derive.md +++ /dev/null @@ -1,63 +0,0 @@ -**This requires enabling the [`derive` feature flag][crate::_features].** - -You can use `--` to escape further arguments. - -Let's see what this looks like in the help: -```console -$ escaped-positional-derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - escaped-positional-derive[EXE] [OPTIONS] [-- ...] - -ARGS: - ... - -OPTIONS: - -f - -h, --help Print help information - -p - -V, --version Print version information - -``` - -Here is a baseline without any arguments: -```console -$ escaped-positional-derive --f used: false --p's value: None -'slops' values: [] - -``` - -Notice that we can't pass positional arguments before `--`: -```console -$ escaped-positional-derive foo bar -? failed -error: Found argument 'foo' which wasn't expected, or isn't valid in this context - -USAGE: - escaped-positional-derive[EXE] [OPTIONS] [-- ...] - -For more information try --help - -``` - -But you can after: -```console -$ escaped-positional-derive -f -p=bob -- sloppy slop slop --f used: true --p's value: Some("bob") -'slops' values: ["sloppy", "slop", "slop"] - -``` - -As mentioned, the parser will directly pass everything through: -```console -$ escaped-positional-derive -- -f -p=bob sloppy slop slop --f used: false --p's value: None -'slops' values: ["-f", "-p=bob", "sloppy", "slop", "slop"] - -``` diff --git a/vendor/clap/examples/escaped-positional-derive.rs b/vendor/clap/examples/escaped-positional-derive.rs deleted file mode 100644 index fd8fde4ed..000000000 --- a/vendor/clap/examples/escaped-positional-derive.rs +++ /dev/null @@ -1,25 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] // requires `derive` feature -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(short = 'f', action)] - eff: bool, - - #[clap(short = 'p', value_name = "PEAR", value_parser)] - pea: Option, - - #[clap(last = true, value_parser)] - slop: Vec, -} - -fn main() { - let args = Cli::parse(); - - // This is what will happen with `myprog -f -p=bob -- sloppy slop slop`... - println!("-f used: {:?}", args.eff); // -f used: true - println!("-p's value: {:?}", args.pea); // -p's value: Some("bob") - println!("'slops' values: {:?}", args.slop); // 'slops' values: Some(["sloppy", "slop", "slop"]) - - // Continued program logic goes here... -} diff --git a/vendor/clap/examples/escaped-positional.md b/vendor/clap/examples/escaped-positional.md deleted file mode 100644 index 987b26139..000000000 --- a/vendor/clap/examples/escaped-positional.md +++ /dev/null @@ -1,63 +0,0 @@ -**This requires enabling the [`cargo` feature flag][crate::_features].** - -You can use `--` to escape further arguments. - -Let's see what this looks like in the help: -```console -$ escaped-positional --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - escaped-positional[EXE] [OPTIONS] [-- ...] - -ARGS: - ... - -OPTIONS: - -f - -h, --help Print help information - -p - -V, --version Print version information - -``` - -Here is a baseline without any arguments: -```console -$ escaped-positional --f used: false --p's value: None -'slops' values: [] - -``` - -Notice that we can't pass positional arguments before `--`: -```console -$ escaped-positional foo bar -? failed -error: Found argument 'foo' which wasn't expected, or isn't valid in this context - -USAGE: - escaped-positional[EXE] [OPTIONS] [-- ...] - -For more information try --help - -``` - -But you can after: -```console -$ escaped-positional -f -p=bob -- sloppy slop slop --f used: true --p's value: Some("bob") -'slops' values: ["sloppy", "slop", "slop"] - -``` - -As mentioned, the parser will directly pass everything through: -```console -$ escaped-positional -- -f -p=bob sloppy slop slop --f used: false --p's value: None -'slops' values: ["-f", "-p=bob", "sloppy", "slop", "slop"] - -``` diff --git a/vendor/clap/examples/escaped-positional.rs b/vendor/clap/examples/escaped-positional.rs deleted file mode 100644 index fdcb930fb..000000000 --- a/vendor/clap/examples/escaped-positional.rs +++ /dev/null @@ -1,36 +0,0 @@ -use clap::{arg, command, value_parser, ArgAction}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg(arg!(eff: -f).action(ArgAction::SetTrue)) - .arg( - arg!(pea: -p ) - .required(false) - .value_parser(value_parser!(String)), - ) - .arg( - // Indicates that `slop` is only accessible after `--`. - arg!(slop: [SLOP]) - .multiple_values(true) - .last(true) - .value_parser(value_parser!(String)), - ) - .get_matches(); - - // This is what will happen with `myprog -f -p=bob -- sloppy slop slop`... - - // -f used: true - println!("-f used: {:?}", matches.get_flag("eff")); - // -p's value: Some("bob") - println!("-p's value: {:?}", matches.get_one::("pea")); - // 'slops' values: Some(["sloppy", "slop", "slop"]) - println!( - "'slops' values: {:?}", - matches - .get_many::("slop") - .map(|vals| vals.collect::>()) - .unwrap_or_default() - ); - - // Continued program logic goes here... -} diff --git a/vendor/clap/examples/git-derive.md b/vendor/clap/examples/git-derive.md deleted file mode 100644 index aa1ca6d9d..000000000 --- a/vendor/clap/examples/git-derive.md +++ /dev/null @@ -1,138 +0,0 @@ -**This requires enabling the [`derive` feature flag][crate::_features].** - -Git is an example of several common subcommand patterns. - -Help: -```console -$ git-derive -? failed -git -A fictional versioning CLI - -USAGE: - git-derive[EXE] - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - add adds things - clone Clones repos - help Print this message or the help of the given subcommand(s) - push pushes things - stash - -$ git-derive help -git -A fictional versioning CLI - -USAGE: - git-derive[EXE] - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - add adds things - clone Clones repos - help Print this message or the help of the given subcommand(s) - push pushes things - stash - -$ git-derive help add -git-derive[EXE]-add -adds things - -USAGE: - git-derive[EXE] add ... - -ARGS: - ... Stuff to add - -OPTIONS: - -h, --help Print help information - -``` - -A basic argument: -```console -$ git-derive add -? failed -git-derive[EXE]-add -adds things - -USAGE: - git-derive[EXE] add ... - -ARGS: - ... Stuff to add - -OPTIONS: - -h, --help Print help information - -$ git-derive add Cargo.toml Cargo.lock -Adding ["Cargo.toml", "Cargo.lock"] - -``` - -Default subcommand: -```console -$ git-derive stash -h -git-derive[EXE]-stash - -USAGE: - git-derive[EXE] stash [OPTIONS] - git-derive[EXE] stash - -OPTIONS: - -h, --help Print help information - -m, --message - -SUBCOMMANDS: - apply - help Print this message or the help of the given subcommand(s) - pop - push - -$ git-derive stash push -h -git-derive[EXE]-stash-push - -USAGE: - git-derive[EXE] stash push [OPTIONS] - -OPTIONS: - -h, --help Print help information - -m, --message - -$ git-derive stash pop -h -git-derive[EXE]-stash-pop - -USAGE: - git-derive[EXE] stash pop [STASH] - -ARGS: - - -OPTIONS: - -h, --help Print help information - -$ git-derive stash -m "Prototype" -Pushing StashPush { message: Some("Prototype") } - -$ git-derive stash pop -Popping None - -$ git-derive stash push -m "Prototype" -Pushing StashPush { message: Some("Prototype") } - -$ git-derive stash pop -Popping None - -``` - -External subcommands: -```console -$ git-derive custom-tool arg1 --foo bar -Calling out to "custom-tool" with ["arg1", "--foo", "bar"] - -``` diff --git a/vendor/clap/examples/git-derive.rs b/vendor/clap/examples/git-derive.rs deleted file mode 100644 index ac500ddad..000000000 --- a/vendor/clap/examples/git-derive.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::ffi::OsString; -use std::path::PathBuf; - -use clap::{Args, Parser, Subcommand}; - -/// A fictional versioning CLI -#[derive(Debug, Parser)] // requires `derive` feature -#[clap(name = "git")] -#[clap(about = "A fictional versioning CLI", long_about = None)] -struct Cli { - #[clap(subcommand)] - command: Commands, -} - -#[derive(Debug, Subcommand)] -enum Commands { - /// Clones repos - #[clap(arg_required_else_help = true)] - Clone { - /// The remote to clone - #[clap(value_parser)] - remote: String, - }, - /// pushes things - #[clap(arg_required_else_help = true)] - Push { - /// The remote to target - #[clap(value_parser)] - remote: String, - }, - /// adds things - #[clap(arg_required_else_help = true)] - Add { - /// Stuff to add - #[clap(required = true, value_parser)] - path: Vec, - }, - Stash(Stash), - #[clap(external_subcommand)] - External(Vec), -} - -#[derive(Debug, Args)] -#[clap(args_conflicts_with_subcommands = true)] -struct Stash { - #[clap(subcommand)] - command: Option, - - #[clap(flatten)] - push: StashPush, -} - -#[derive(Debug, Subcommand)] -enum StashCommands { - Push(StashPush), - Pop { - #[clap(value_parser)] - stash: Option, - }, - Apply { - #[clap(value_parser)] - stash: Option, - }, -} - -#[derive(Debug, Args)] -struct StashPush { - #[clap(short, long, value_parser)] - message: Option, -} - -fn main() { - let args = Cli::parse(); - - match args.command { - Commands::Clone { remote } => { - println!("Cloning {}", remote); - } - Commands::Push { remote } => { - println!("Pushing to {}", remote); - } - Commands::Add { path } => { - println!("Adding {:?}", path); - } - Commands::Stash(stash) => { - let stash_cmd = stash.command.unwrap_or(StashCommands::Push(stash.push)); - match stash_cmd { - StashCommands::Push(push) => { - println!("Pushing {:?}", push); - } - StashCommands::Pop { stash } => { - println!("Popping {:?}", stash); - } - StashCommands::Apply { stash } => { - println!("Applying {:?}", stash); - } - } - } - Commands::External(args) => { - println!("Calling out to {:?} with {:?}", &args[0], &args[1..]); - } - } - - // Continued program logic goes here... -} diff --git a/vendor/clap/examples/git.md b/vendor/clap/examples/git.md deleted file mode 100644 index 9e413415a..000000000 --- a/vendor/clap/examples/git.md +++ /dev/null @@ -1,136 +0,0 @@ -Git is an example of several common subcommand patterns. - -Help: -```console -$ git -? failed -git -A fictional versioning CLI - -USAGE: - git[EXE] - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - add adds things - clone Clones repos - help Print this message or the help of the given subcommand(s) - push pushes things - stash - -$ git help -git -A fictional versioning CLI - -USAGE: - git[EXE] - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - add adds things - clone Clones repos - help Print this message or the help of the given subcommand(s) - push pushes things - stash - -$ git help add -git[EXE]-add -adds things - -USAGE: - git[EXE] add ... - -ARGS: - ... Stuff to add - -OPTIONS: - -h, --help Print help information - -``` - -A basic argument: -```console -$ git add -? failed -git[EXE]-add -adds things - -USAGE: - git[EXE] add ... - -ARGS: - ... Stuff to add - -OPTIONS: - -h, --help Print help information - -$ git add Cargo.toml Cargo.lock -Adding ["Cargo.toml", "Cargo.lock"] - -``` - -Default subcommand: -```console -$ git stash -h -git[EXE]-stash - -USAGE: - git[EXE] stash [OPTIONS] - git[EXE] stash - -OPTIONS: - -h, --help Print help information - -m, --message - -SUBCOMMANDS: - apply - help Print this message or the help of the given subcommand(s) - pop - push - -$ git stash push -h -git[EXE]-stash-push - -USAGE: - git[EXE] stash push [OPTIONS] - -OPTIONS: - -h, --help Print help information - -m, --message - -$ git stash pop -h -git[EXE]-stash-pop - -USAGE: - git[EXE] stash pop [STASH] - -ARGS: - - -OPTIONS: - -h, --help Print help information - -$ git stash -m "Prototype" -Pushing Some("Prototype") - -$ git stash pop -Popping None - -$ git stash push -m "Prototype" -Pushing Some("Prototype") - -$ git stash pop -Popping None - -``` - -External subcommands: -```console -$ git custom-tool arg1 --foo bar -Calling out to "custom-tool" with ["arg1", "--foo", "bar"] - -``` diff --git a/vendor/clap/examples/git.rs b/vendor/clap/examples/git.rs deleted file mode 100644 index e56f427a6..000000000 --- a/vendor/clap/examples/git.rs +++ /dev/null @@ -1,101 +0,0 @@ -use std::ffi::OsString; -use std::path::PathBuf; - -use clap::{arg, Command}; - -fn cli() -> Command<'static> { - Command::new("git") - .about("A fictional versioning CLI") - .subcommand_required(true) - .arg_required_else_help(true) - .allow_external_subcommands(true) - .allow_invalid_utf8_for_external_subcommands(true) - .subcommand( - Command::new("clone") - .about("Clones repos") - .arg(arg!( "The remote to clone")) - .arg_required_else_help(true), - ) - .subcommand( - Command::new("push") - .about("pushes things") - .arg(arg!( "The remote to target")) - .arg_required_else_help(true), - ) - .subcommand( - Command::new("add") - .about("adds things") - .arg_required_else_help(true) - .arg(arg!( ... "Stuff to add").value_parser(clap::value_parser!(PathBuf))), - ) - .subcommand( - Command::new("stash") - .args_conflicts_with_subcommands(true) - .args(push_args()) - .subcommand(Command::new("push").args(push_args())) - .subcommand(Command::new("pop").arg(arg!([STASH]))) - .subcommand(Command::new("apply").arg(arg!([STASH]))), - ) -} - -fn push_args() -> Vec> { - vec![arg!(-m --message ).required(false)] -} - -fn main() { - let matches = cli().get_matches(); - - match matches.subcommand() { - Some(("clone", sub_matches)) => { - println!( - "Cloning {}", - sub_matches.get_one::("REMOTE").expect("required") - ); - } - Some(("push", sub_matches)) => { - println!( - "Pushing to {}", - sub_matches.get_one::("REMOTE").expect("required") - ); - } - Some(("add", sub_matches)) => { - let paths = sub_matches - .get_many::("PATH") - .into_iter() - .flatten() - .collect::>(); - println!("Adding {:?}", paths); - } - Some(("stash", sub_matches)) => { - let stash_command = sub_matches.subcommand().unwrap_or(("push", sub_matches)); - match stash_command { - ("apply", sub_matches) => { - let stash = sub_matches.get_one::("STASH"); - println!("Applying {:?}", stash); - } - ("pop", sub_matches) => { - let stash = sub_matches.get_one::("STASH"); - println!("Popping {:?}", stash); - } - ("push", sub_matches) => { - let message = sub_matches.get_one::("message"); - println!("Pushing {:?}", message); - } - (name, _) => { - unreachable!("Unsupported subcommand `{}`", name) - } - } - } - Some((ext, sub_matches)) => { - let args = sub_matches - .get_many::("") - .into_iter() - .flatten() - .collect::>(); - println!("Calling out to {:?} with {:?}", ext, args); - } - _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!() - } - - // Continued program logic goes here... -} diff --git a/vendor/clap/examples/multicall-busybox.md b/vendor/clap/examples/multicall-busybox.md deleted file mode 100644 index 5ca2cad5b..000000000 --- a/vendor/clap/examples/multicall-busybox.md +++ /dev/null @@ -1,42 +0,0 @@ -See the documentation for [`Command::multicall`][crate::App::multicall] for rationale. - -This example omits every command except true and false, -which are the most trivial to implement, -```console -$ busybox true -? 0 - -$ busybox false -? 1 - -``` -*Note: without the links setup, we can't demonstrate the multicall behavior* - -But includes the `--install` option as an example of why it can be useful -for the main program to take arguments that aren't applet subcommands. -```console -$ busybox --install -? failed -... - -``` - -Though users must pass something: -```console -$ busybox -? failed -busybox - -USAGE: - busybox [OPTIONS] [APPLET] - -OPTIONS: - -h, --help Print help information - --install Install hardlinks for all subcommands in path - -APPLETS: - false does nothing unsuccessfully - help Print this message or the help of the given subcommand(s) - true does nothing successfully - -``` diff --git a/vendor/clap/examples/multicall-busybox.rs b/vendor/clap/examples/multicall-busybox.rs deleted file mode 100644 index 2e7f976c1..000000000 --- a/vendor/clap/examples/multicall-busybox.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::path::PathBuf; -use std::process::exit; - -use clap::{value_parser, Arg, Command}; - -fn applet_commands() -> [Command<'static>; 2] { - [ - Command::new("true").about("does nothing successfully"), - Command::new("false").about("does nothing unsuccessfully"), - ] -} - -fn main() { - let cmd = Command::new(env!("CARGO_CRATE_NAME")) - .multicall(true) - .subcommand( - Command::new("busybox") - .arg_required_else_help(true) - .subcommand_value_name("APPLET") - .subcommand_help_heading("APPLETS") - .arg( - Arg::new("install") - .long("install") - .help("Install hardlinks for all subcommands in path") - .exclusive(true) - .takes_value(true) - .default_missing_value("/usr/local/bin") - .value_parser(value_parser!(PathBuf)) - .use_value_delimiter(false), - ) - .subcommands(applet_commands()), - ) - .subcommands(applet_commands()); - - let matches = cmd.get_matches(); - let mut subcommand = matches.subcommand(); - if let Some(("busybox", cmd)) = subcommand { - if cmd.contains_id("install") { - unimplemented!("Make hardlinks to the executable here"); - } - subcommand = cmd.subcommand(); - } - match subcommand { - Some(("false", _)) => exit(1), - Some(("true", _)) => exit(0), - _ => unreachable!("parser should ensure only valid subcommand names are used"), - } -} diff --git a/vendor/clap/examples/multicall-hostname.md b/vendor/clap/examples/multicall-hostname.md deleted file mode 100644 index d22b85fba..000000000 --- a/vendor/clap/examples/multicall-hostname.md +++ /dev/null @@ -1,10 +0,0 @@ -See the documentation for [`Command::multicall`][crate::App::multicall] for rationale. - -This example omits the implementation of displaying address config - -```console -$ hostname -www - -``` -*Note: without the links setup, we can't demonstrate the multicall behavior* diff --git a/vendor/clap/examples/multicall-hostname.rs b/vendor/clap/examples/multicall-hostname.rs deleted file mode 100644 index b57680a5c..000000000 --- a/vendor/clap/examples/multicall-hostname.rs +++ /dev/null @@ -1,17 +0,0 @@ -use clap::Command; - -fn main() { - let cmd = Command::new(env!("CARGO_CRATE_NAME")) - .multicall(true) - .arg_required_else_help(true) - .subcommand_value_name("APPLET") - .subcommand_help_heading("APPLETS") - .subcommand(Command::new("hostname").about("show hostname part of FQDN")) - .subcommand(Command::new("dnsdomainname").about("show domain name part of FQDN")); - - match cmd.get_matches().subcommand_name() { - Some("hostname") => println!("www"), - Some("dnsdomainname") => println!("example.com"), - _ => unreachable!("parser should ensure only valid subcommand names are used"), - } -} diff --git a/vendor/clap/examples/pacman.md b/vendor/clap/examples/pacman.md deleted file mode 100644 index b8ddd09d9..000000000 --- a/vendor/clap/examples/pacman.md +++ /dev/null @@ -1,85 +0,0 @@ -[`pacman`](https://wiki.archlinux.org/index.php/pacman) defines subcommands via flags. - -Here, `-S` is a short flag subcommand: -```console -$ pacman -S package -Installing package... - -``` - -Here `--sync` is a long flag subcommand: -```console -$ pacman --sync package -Installing package... - -``` - -Now the short flag subcommand (`-S`) with a long flag: -```console -$ pacman -S --search name -Searching for name... - -``` - -And the various forms of short flags that work: -```console -$ pacman -S -s name -Searching for name... - -$ pacman -Ss name -Searching for name... - -``` -*(users can "stack" short subcommands with short flags or with other short flag subcommands)* - -In the help, this looks like: -```console -$ pacman -h -pacman 5.2.1 -Pacman Development Team -package manager utility - -USAGE: - pacman[EXE] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - help Print this message or the help of the given subcommand(s) - query -Q --query Query the package database. - sync -S --sync Synchronize packages. - -$ pacman -S -h -pacman[EXE]-sync -Synchronize packages. - -USAGE: - pacman[EXE] {sync|--sync|-S} [OPTIONS] [--] [package]... - -ARGS: - ... packages - -OPTIONS: - -h, --help Print help information - -i, --info view package information - -s, --search ... search remote repositories for matching strings - -``` - -And errors: -```console -$ pacman -S -s foo -i bar -? failed -error: The argument '--search ...' cannot be used with '--info' - -USAGE: - pacman[EXE] {sync|--sync|-S} --search ... ... - -For more information try --help - -``` - -**NOTE:** Keep in mind that subcommands, flags, and long flags are *case sensitive*: `-Q` and `-q` are different flags/subcommands. For example, you can have both `-Q` subcommand and `-q` flag, and they will be properly disambiguated. -Let's make a quick program to illustrate. diff --git a/vendor/clap/examples/pacman.rs b/vendor/clap/examples/pacman.rs deleted file mode 100644 index aee7cd892..000000000 --- a/vendor/clap/examples/pacman.rs +++ /dev/null @@ -1,111 +0,0 @@ -use clap::{Arg, ArgAction, Command}; - -fn main() { - let matches = Command::new("pacman") - .about("package manager utility") - .version("5.2.1") - .subcommand_required(true) - .arg_required_else_help(true) - .author("Pacman Development Team") - // Query subcommand - // - // Only a few of its arguments are implemented below. - .subcommand( - Command::new("query") - .short_flag('Q') - .long_flag("query") - .about("Query the package database.") - .arg( - Arg::new("search") - .short('s') - .long("search") - .help("search locally installed packages for matching strings") - .conflicts_with("info") - .takes_value(true) - .multiple_values(true), - ) - .arg( - Arg::new("info") - .long("info") - .short('i') - .conflicts_with("search") - .help("view package information") - .takes_value(true) - .multiple_values(true), - ), - ) - // Sync subcommand - // - // Only a few of its arguments are implemented below. - .subcommand( - Command::new("sync") - .short_flag('S') - .long_flag("sync") - .about("Synchronize packages.") - .arg( - Arg::new("search") - .short('s') - .long("search") - .conflicts_with("info") - .takes_value(true) - .multiple_values(true) - .help("search remote repositories for matching strings"), - ) - .arg( - Arg::new("info") - .long("info") - .conflicts_with("search") - .short('i') - .action(ArgAction::SetTrue) - .help("view package information"), - ) - .arg( - Arg::new("package") - .help("packages") - .required_unless_present("search") - .takes_value(true) - .multiple_values(true), - ), - ) - .get_matches(); - - match matches.subcommand() { - Some(("sync", sync_matches)) => { - if sync_matches.contains_id("search") { - let packages: Vec<_> = sync_matches - .get_many::("search") - .expect("contains_id") - .map(|s| s.as_str()) - .collect(); - let values = packages.join(", "); - println!("Searching for {}...", values); - return; - } - - let packages: Vec<_> = sync_matches - .get_many::("package") - .expect("is present") - .map(|s| s.as_str()) - .collect(); - let values = packages.join(", "); - - if sync_matches.get_flag("info") { - println!("Retrieving info for {}...", values); - } else { - println!("Installing {}...", values); - } - } - Some(("query", query_matches)) => { - if let Some(packages) = query_matches.get_many::("info") { - let comma_sep = packages.map(|s| s.as_str()).collect::>().join(", "); - println!("Retrieving info for {}...", comma_sep); - } else if let Some(queries) = query_matches.get_many::("search") { - let comma_sep = queries.map(|s| s.as_str()).collect::>().join(", "); - println!("Searching Locally for {}...", comma_sep); - } else { - println!("Displaying all locally installed packages..."); - } - } - _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable - } -} diff --git a/vendor/clap/examples/repl.rs b/vendor/clap/examples/repl.rs deleted file mode 100644 index c509adee6..000000000 --- a/vendor/clap/examples/repl.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::io::Write; - -use clap::Command; - -fn main() -> Result<(), String> { - loop { - let line = readline()?; - let line = line.trim(); - if line.is_empty() { - continue; - } - - match respond(line) { - Ok(quit) => { - if quit { - break; - } - } - Err(err) => { - write!(std::io::stdout(), "{}", err).map_err(|e| e.to_string())?; - std::io::stdout().flush().map_err(|e| e.to_string())?; - } - } - } - - Ok(()) -} - -fn respond(line: &str) -> Result { - let args = shlex::split(line).ok_or("error: Invalid quoting")?; - let matches = cli() - .try_get_matches_from(&args) - .map_err(|e| e.to_string())?; - match matches.subcommand() { - Some(("ping", _matches)) => { - write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?; - std::io::stdout().flush().map_err(|e| e.to_string())?; - } - Some(("quit", _matches)) => { - write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?; - std::io::stdout().flush().map_err(|e| e.to_string())?; - return Ok(true); - } - Some((name, _matches)) => unimplemented!("{}", name), - None => unreachable!("subcommand required"), - } - - Ok(false) -} - -fn cli() -> Command<'static> { - // strip out usage - const PARSER_TEMPLATE: &str = "\ - {all-args} - "; - // strip out name/version - const APPLET_TEMPLATE: &str = "\ - {about-with-newline}\n\ - {usage-heading}\n {usage}\n\ - \n\ - {all-args}{after-help}\ - "; - - Command::new("repl") - .multicall(true) - .arg_required_else_help(true) - .subcommand_required(true) - .subcommand_value_name("APPLET") - .subcommand_help_heading("APPLETS") - .help_template(PARSER_TEMPLATE) - .subcommand( - Command::new("ping") - .about("Get a response") - .help_template(APPLET_TEMPLATE), - ) - .subcommand( - Command::new("quit") - .alias("exit") - .about("Quit the REPL") - .help_template(APPLET_TEMPLATE), - ) -} - -fn readline() -> Result { - write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?; - std::io::stdout().flush().map_err(|e| e.to_string())?; - let mut buffer = String::new(); - std::io::stdin() - .read_line(&mut buffer) - .map_err(|e| e.to_string())?; - Ok(buffer) -} diff --git a/vendor/clap/examples/tutorial_builder/01_quick.md b/vendor/clap/examples/tutorial_builder/01_quick.md deleted file mode 100644 index 4a9e3fca1..000000000 --- a/vendor/clap/examples/tutorial_builder/01_quick.md +++ /dev/null @@ -1,37 +0,0 @@ -```console -$ 01_quick --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 01_quick[EXE] [OPTIONS] [name] [SUBCOMMAND] - -ARGS: - Optional name to operate on - -OPTIONS: - -c, --config Sets a custom config file - -d, --debug Turn debugging information on - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - help Print this message or the help of the given subcommand(s) - test does testing things - -``` - -By default, the program does nothing: -```console -$ 01_quick -Debug mode is off - -``` - -But you can mix and match the various features -```console -$ 01_quick -dd test -Debug mode is on -Not printing testing lists... - -``` diff --git a/vendor/clap/examples/tutorial_builder/01_quick.rs b/vendor/clap/examples/tutorial_builder/01_quick.rs deleted file mode 100644 index 393d6aeae..000000000 --- a/vendor/clap/examples/tutorial_builder/01_quick.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::path::PathBuf; - -use clap::{arg, command, value_parser, ArgAction, Command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg(arg!([name] "Optional name to operate on")) - .arg( - arg!( - -c --config "Sets a custom config file" - ) - // We don't have syntax yet for optional options, so manually calling `required` - .required(false) - .value_parser(value_parser!(PathBuf)), - ) - .arg( - arg!( - -d --debug "Turn debugging information on" - ) - .action(ArgAction::Count), - ) - .subcommand( - Command::new("test") - .about("does testing things") - .arg(arg!(-l --list "lists test values").action(ArgAction::SetTrue)), - ) - .get_matches(); - - // You can check the value provided by positional arguments, or option arguments - if let Some(name) = matches.get_one::("name") { - println!("Value for name: {}", name); - } - - if let Some(config_path) = matches.get_one::("config") { - println!("Value for config: {}", config_path.display()); - } - - // You can see how many times a particular flag or argument occurred - // Note, only flags can have multiple occurrences - match matches - .get_one::("debug") - .expect("Count's are defaulted") - { - 0 => println!("Debug mode is off"), - 1 => println!("Debug mode is kind of on"), - 2 => println!("Debug mode is on"), - _ => println!("Don't be crazy"), - } - - // You can check for the existence of subcommands, and if found use their - // matches just as you would the top level cmd - if let Some(matches) = matches.subcommand_matches("test") { - // "$ myapp test" was run - if *matches.get_one::("list").expect("defaulted by clap") { - // "$ myapp test -l" was run - println!("Printing testing lists..."); - } else { - println!("Not printing testing lists..."); - } - } - - // Continued program logic goes here... -} diff --git a/vendor/clap/examples/tutorial_builder/02_app_settings.md b/vendor/clap/examples/tutorial_builder/02_app_settings.md deleted file mode 100644 index 247843bcf..000000000 --- a/vendor/clap/examples/tutorial_builder/02_app_settings.md +++ /dev/null @@ -1,19 +0,0 @@ -```console -$ 02_app_settings --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 02_app_settings[EXE] --two --one - -OPTIONS: - --two - --one - -h, --help Print help information - -V, --version Print version information - -$ 02_app_settings --one -1 --one -3 --two 10 -two: "10" -one: "-3" - -``` diff --git a/vendor/clap/examples/tutorial_builder/02_app_settings.rs b/vendor/clap/examples/tutorial_builder/02_app_settings.rs deleted file mode 100644 index 5f374d7f0..000000000 --- a/vendor/clap/examples/tutorial_builder/02_app_settings.rs +++ /dev/null @@ -1,19 +0,0 @@ -use clap::{arg, command, AppSettings, ArgAction}; - -fn main() { - let matches = command!() // requires `cargo` feature - .global_setting(AppSettings::DeriveDisplayOrder) - .allow_negative_numbers(true) - .arg(arg!(--two ).action(ArgAction::Set)) - .arg(arg!(--one ).action(ArgAction::Set)) - .get_matches(); - - println!( - "two: {:?}", - matches.get_one::("two").expect("required") - ); - println!( - "one: {:?}", - matches.get_one::("one").expect("required") - ); -} diff --git a/vendor/clap/examples/tutorial_builder/02_apps.md b/vendor/clap/examples/tutorial_builder/02_apps.md deleted file mode 100644 index 8504b5f52..000000000 --- a/vendor/clap/examples/tutorial_builder/02_apps.md +++ /dev/null @@ -1,19 +0,0 @@ -```console -$ 02_apps --help -MyApp 1.0 -Kevin K. -Does awesome things - -USAGE: - 02_apps[EXE] --two --one - -OPTIONS: - -h, --help Print help information - --one - --two - -V, --version Print version information - -$ 02_apps --version -MyApp 1.0 - -``` diff --git a/vendor/clap/examples/tutorial_builder/02_apps.rs b/vendor/clap/examples/tutorial_builder/02_apps.rs deleted file mode 100644 index db9da18f9..000000000 --- a/vendor/clap/examples/tutorial_builder/02_apps.rs +++ /dev/null @@ -1,20 +0,0 @@ -use clap::{arg, Command}; - -fn main() { - let matches = Command::new("MyApp") - .version("1.0") - .author("Kevin K. ") - .about("Does awesome things") - .arg(arg!(--two )) - .arg(arg!(--one )) - .get_matches(); - - println!( - "two: {:?}", - matches.get_one::("two").expect("required") - ); - println!( - "one: {:?}", - matches.get_one::("one").expect("required") - ); -} diff --git a/vendor/clap/examples/tutorial_builder/02_crate.md b/vendor/clap/examples/tutorial_builder/02_crate.md deleted file mode 100644 index f76e0d608..000000000 --- a/vendor/clap/examples/tutorial_builder/02_crate.md +++ /dev/null @@ -1,18 +0,0 @@ -```console -$ 02_crate --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 02_crate[EXE] --two --one - -OPTIONS: - -h, --help Print help information - --one - --two - -V, --version Print version information - -$ 02_crate --version -clap [..] - -``` diff --git a/vendor/clap/examples/tutorial_builder/02_crate.rs b/vendor/clap/examples/tutorial_builder/02_crate.rs deleted file mode 100644 index 8a1722fd3..000000000 --- a/vendor/clap/examples/tutorial_builder/02_crate.rs +++ /dev/null @@ -1,18 +0,0 @@ -use clap::{arg, command}; - -fn main() { - // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml` - let matches = command!() - .arg(arg!(--two )) - .arg(arg!(--one )) - .get_matches(); - - println!( - "two: {:?}", - matches.get_one::("two").expect("required") - ); - println!( - "one: {:?}", - matches.get_one::("one").expect("required") - ); -} diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.md b/vendor/clap/examples/tutorial_builder/03_01_flag_bool.md deleted file mode 100644 index b0ee2a126..000000000 --- a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.md +++ /dev/null @@ -1,23 +0,0 @@ -```console -$ 03_01_flag_bool --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_01_flag_bool[EXE] [OPTIONS] - -OPTIONS: - -h, --help Print help information - -v, --verbose - -V, --version Print version information - -$ 03_01_flag_bool -verbose: false - -$ 03_01_flag_bool --verbose -verbose: true - -$ 03_01_flag_bool --verbose --verbose -verbose: true - -``` diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs b/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs deleted file mode 100644 index 03f2f1756..000000000 --- a/vendor/clap/examples/tutorial_builder/03_01_flag_bool.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::{command, Arg, ArgAction}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg( - Arg::new("verbose") - .short('v') - .long("verbose") - .action(ArgAction::SetTrue), - ) - .get_matches(); - - println!("verbose: {:?}", matches.get_flag("verbose")); -} diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_count.md b/vendor/clap/examples/tutorial_builder/03_01_flag_count.md deleted file mode 100644 index ca4bcd6eb..000000000 --- a/vendor/clap/examples/tutorial_builder/03_01_flag_count.md +++ /dev/null @@ -1,23 +0,0 @@ -```console -$ 03_01_flag_count --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_01_flag_count[EXE] [OPTIONS] - -OPTIONS: - -h, --help Print help information - -v, --verbose - -V, --version Print version information - -$ 03_01_flag_count -verbose: 0 - -$ 03_01_flag_count --verbose -verbose: 1 - -$ 03_01_flag_count --verbose --verbose -verbose: 2 - -``` diff --git a/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs b/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs deleted file mode 100644 index 7f23649d6..000000000 --- a/vendor/clap/examples/tutorial_builder/03_01_flag_count.rs +++ /dev/null @@ -1,9 +0,0 @@ -use clap::{arg, command, ArgAction}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg(arg!(-v - -verbose).action(ArgAction::Count)) - .get_matches(); - - println!("verbose: {:?}", matches.get_count("verbose")); -} diff --git a/vendor/clap/examples/tutorial_builder/03_02_option.md b/vendor/clap/examples/tutorial_builder/03_02_option.md deleted file mode 100644 index 6198bcc73..000000000 --- a/vendor/clap/examples/tutorial_builder/03_02_option.md +++ /dev/null @@ -1,32 +0,0 @@ -```console -$ 03_02_option --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_02_option[EXE] [OPTIONS] - -OPTIONS: - -h, --help Print help information - -n, --name - -V, --version Print version information - -$ 03_02_option -name: None - -$ 03_02_option --name bob -name: Some("bob") - -$ 03_02_option --name=bob -name: Some("bob") - -$ 03_02_option -n bob -name: Some("bob") - -$ 03_02_option -n=bob -name: Some("bob") - -$ 03_02_option -nbob -name: Some("bob") - -``` diff --git a/vendor/clap/examples/tutorial_builder/03_02_option.rs b/vendor/clap/examples/tutorial_builder/03_02_option.rs deleted file mode 100644 index 188244566..000000000 --- a/vendor/clap/examples/tutorial_builder/03_02_option.rs +++ /dev/null @@ -1,9 +0,0 @@ -use clap::{arg, command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg(arg!(-n --name ).required(false)) - .get_matches(); - - println!("name: {:?}", matches.get_one::("name")); -} diff --git a/vendor/clap/examples/tutorial_builder/03_03_positional.md b/vendor/clap/examples/tutorial_builder/03_03_positional.md deleted file mode 100644 index a3d7b8cf3..000000000 --- a/vendor/clap/examples/tutorial_builder/03_03_positional.md +++ /dev/null @@ -1,22 +0,0 @@ -```console -$ 03_03_positional --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_03_positional[EXE] [NAME] - -ARGS: - - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 03_03_positional -NAME: None - -$ 03_03_positional bob -NAME: Some("bob") - -``` diff --git a/vendor/clap/examples/tutorial_builder/03_03_positional.rs b/vendor/clap/examples/tutorial_builder/03_03_positional.rs deleted file mode 100644 index 0c3a5f037..000000000 --- a/vendor/clap/examples/tutorial_builder/03_03_positional.rs +++ /dev/null @@ -1,9 +0,0 @@ -use clap::{arg, command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg(arg!([NAME])) - .get_matches(); - - println!("NAME: {:?}", matches.get_one::("NAME")); -} diff --git a/vendor/clap/examples/tutorial_builder/03_04_subcommands.md b/vendor/clap/examples/tutorial_builder/03_04_subcommands.md deleted file mode 100644 index 8f9efa911..000000000 --- a/vendor/clap/examples/tutorial_builder/03_04_subcommands.md +++ /dev/null @@ -1,64 +0,0 @@ -```console -$ 03_04_subcommands help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_04_subcommands[EXE] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - add Adds files to myapp - help Print this message or the help of the given subcommand(s) - -$ 03_04_subcommands help add -03_04_subcommands[EXE]-add [..] -Adds files to myapp - -USAGE: - 03_04_subcommands[EXE] add [NAME] - -ARGS: - - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 03_04_subcommands add bob -'myapp add' was used, name is: Some("bob") - -``` - -Because we set [`Command::arg_required_else_help`][crate::Command::arg_required_else_help]: -```console -$ 03_04_subcommands -? failed -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_04_subcommands[EXE] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - add Adds files to myapp - help Print this message or the help of the given subcommand(s) - -``` - -Because we set [`Command::propagate_version`][crate::Command::propagate_version]: -```console -$ 03_04_subcommands --version -clap [..] - -$ 03_04_subcommands add --version -03_04_subcommands[EXE]-add [..] - -``` diff --git a/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs b/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs deleted file mode 100644 index fbe23809e..000000000 --- a/vendor/clap/examples/tutorial_builder/03_04_subcommands.rs +++ /dev/null @@ -1,22 +0,0 @@ -use clap::{arg, command, Command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .propagate_version(true) - .subcommand_required(true) - .arg_required_else_help(true) - .subcommand( - Command::new("add") - .about("Adds files to myapp") - .arg(arg!([NAME])), - ) - .get_matches(); - - match matches.subcommand() { - Some(("add", sub_matches)) => println!( - "'myapp add' was used, name is: {:?}", - sub_matches.get_one::("NAME") - ), - _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"), - } -} diff --git a/vendor/clap/examples/tutorial_builder/03_05_default_values.md b/vendor/clap/examples/tutorial_builder/03_05_default_values.md deleted file mode 100644 index 7b6c0307d..000000000 --- a/vendor/clap/examples/tutorial_builder/03_05_default_values.md +++ /dev/null @@ -1,22 +0,0 @@ -```console -$ 03_05_default_values --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_05_default_values[EXE] [NAME] - -ARGS: - [default: alice] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 03_05_default_values -NAME: "alice" - -$ 03_05_default_values bob -NAME: "bob" - -``` diff --git a/vendor/clap/examples/tutorial_builder/03_05_default_values.rs b/vendor/clap/examples/tutorial_builder/03_05_default_values.rs deleted file mode 100644 index cb3e3831f..000000000 --- a/vendor/clap/examples/tutorial_builder/03_05_default_values.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::{arg, command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg(arg!([NAME]).default_value("alice")) - .get_matches(); - - println!( - "NAME: {:?}", - matches - .get_one::("NAME") - .expect("default ensures there is always a value") - ); -} diff --git a/vendor/clap/examples/tutorial_builder/04_01_enum.md b/vendor/clap/examples/tutorial_builder/04_01_enum.md deleted file mode 100644 index 282b1e613..000000000 --- a/vendor/clap/examples/tutorial_builder/04_01_enum.md +++ /dev/null @@ -1,29 +0,0 @@ -```console -$ 04_01_enum --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_01_enum[EXE] - -ARGS: - What mode to run the program in [possible values: fast, slow] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_01_enum fast -Hare - -$ 04_01_enum slow -Tortoise - -$ 04_01_enum medium -? failed -error: "medium" isn't a valid value for '' - [possible values: fast, slow] - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_builder/04_01_enum.rs b/vendor/clap/examples/tutorial_builder/04_01_enum.rs deleted file mode 100644 index e8cf70f5c..000000000 --- a/vendor/clap/examples/tutorial_builder/04_01_enum.rs +++ /dev/null @@ -1,66 +0,0 @@ -use clap::{arg, builder::PossibleValue, command, value_parser, ValueEnum}; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -enum Mode { - Fast, - Slow, -} - -// Can also be derived] with feature flag `derive` -impl ValueEnum for Mode { - fn value_variants<'a>() -> &'a [Self] { - &[Mode::Fast, Mode::Slow] - } - - fn to_possible_value<'a>(&self) -> Option> { - Some(match self { - Mode::Fast => PossibleValue::new("fast"), - Mode::Slow => PossibleValue::new("slow"), - }) - } -} - -impl std::fmt::Display for Mode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.to_possible_value() - .expect("no values are skipped") - .get_name() - .fmt(f) - } -} - -impl std::str::FromStr for Mode { - type Err = String; - - fn from_str(s: &str) -> Result { - for variant in Self::value_variants() { - if variant.to_possible_value().unwrap().matches(s, false) { - return Ok(*variant); - } - } - Err(format!("Invalid variant: {}", s)) - } -} - -fn main() { - let matches = command!() // requires `cargo` feature - .arg( - arg!() - .help("What mode to run the program in") - .value_parser(value_parser!(Mode)), - ) - .get_matches(); - - // Note, it's safe to call unwrap() because the arg is required - match matches - .get_one::("MODE") - .expect("'MODE' is required and parsing will fail if its missing") - { - Mode::Fast => { - println!("Hare"); - } - Mode::Slow => { - println!("Tortoise"); - } - } -} diff --git a/vendor/clap/examples/tutorial_builder/04_01_possible.md b/vendor/clap/examples/tutorial_builder/04_01_possible.md deleted file mode 100644 index 2909bfb17..000000000 --- a/vendor/clap/examples/tutorial_builder/04_01_possible.md +++ /dev/null @@ -1,29 +0,0 @@ -```console -$ 04_01_possible --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_01_possible[EXE] - -ARGS: - What mode to run the program in [possible values: fast, slow] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_01_possible fast -Hare - -$ 04_01_possible slow -Tortoise - -$ 04_01_possible medium -? failed -error: "medium" isn't a valid value for '' - [possible values: fast, slow] - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_builder/04_01_possible.rs b/vendor/clap/examples/tutorial_builder/04_01_possible.rs deleted file mode 100644 index 3da7aca74..000000000 --- a/vendor/clap/examples/tutorial_builder/04_01_possible.rs +++ /dev/null @@ -1,26 +0,0 @@ -use clap::{arg, command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg( - arg!() - .help("What mode to run the program in") - .value_parser(["fast", "slow"]), - ) - .get_matches(); - - // Note, it's safe to call unwrap() because the arg is required - match matches - .get_one::("MODE") - .expect("'MODE' is required and parsing will fail if its missing") - .as_str() - { - "fast" => { - println!("Hare"); - } - "slow" => { - println!("Tortoise"); - } - _ => unreachable!(), - } -} diff --git a/vendor/clap/examples/tutorial_builder/04_02_parse.md b/vendor/clap/examples/tutorial_builder/04_02_parse.md deleted file mode 100644 index 605bf4b59..000000000 --- a/vendor/clap/examples/tutorial_builder/04_02_parse.md +++ /dev/null @@ -1,31 +0,0 @@ -```console -$ 04_02_parse --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_02_parse[EXE] - -ARGS: - Network port to use - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_02_parse 22 -PORT = 22 - -$ 04_02_parse foobar -? failed -error: Invalid value "foobar" for '': invalid digit found in string - -For more information try --help - -$ 04_02_parse_derive 0 -? failed -error: Invalid value "0" for '': 0 is not in 1..=65535 - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_builder/04_02_parse.rs b/vendor/clap/examples/tutorial_builder/04_02_parse.rs deleted file mode 100644 index 13f41a18e..000000000 --- a/vendor/clap/examples/tutorial_builder/04_02_parse.rs +++ /dev/null @@ -1,17 +0,0 @@ -use clap::{arg, command, value_parser}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg( - arg!() - .help("Network port to use") - .value_parser(value_parser!(u16).range(1..)), - ) - .get_matches(); - - // Note, it's safe to call unwrap() because the arg is required - let port: u16 = *matches - .get_one::("PORT") - .expect("'PORT' is required and parsing will fail if its missing"); - println!("PORT = {}", port); -} diff --git a/vendor/clap/examples/tutorial_builder/04_02_validate.md b/vendor/clap/examples/tutorial_builder/04_02_validate.md deleted file mode 100644 index a317a8eb7..000000000 --- a/vendor/clap/examples/tutorial_builder/04_02_validate.md +++ /dev/null @@ -1,31 +0,0 @@ -```console -$ 04_02_validate --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_02_validate[EXE] - -ARGS: - Network port to use - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_02_validate 22 -PORT = 22 - -$ 04_02_validate foobar -? failed -error: Invalid value "foobar" for '': `foobar` isn't a port number - -For more information try --help - -$ 04_02_validate 0 -? failed -error: Invalid value "0" for '': Port not in range 1-65535 - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_builder/04_02_validate.rs b/vendor/clap/examples/tutorial_builder/04_02_validate.rs deleted file mode 100644 index ea2f32e67..000000000 --- a/vendor/clap/examples/tutorial_builder/04_02_validate.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::ops::RangeInclusive; - -use clap::{arg, command}; - -fn main() { - let matches = command!() // requires `cargo` feature - .arg( - arg!() - .help("Network port to use") - .value_parser(port_in_range), - ) - .get_matches(); - - // Note, it's safe to call unwrap() because the arg is required - let port: u16 = *matches - .get_one::("PORT") - .expect("'PORT' is required and parsing will fail if its missing"); - println!("PORT = {}", port); -} - -const PORT_RANGE: RangeInclusive = 1..=65535; - -fn port_in_range(s: &str) -> Result { - let port: usize = s - .parse() - .map_err(|_| format!("`{}` isn't a port number", s))?; - if PORT_RANGE.contains(&port) { - Ok(port as u16) - } else { - Err(format!( - "Port not in range {}-{}", - PORT_RANGE.start(), - PORT_RANGE.end() - )) - } -} diff --git a/vendor/clap/examples/tutorial_builder/04_03_relations.md b/vendor/clap/examples/tutorial_builder/04_03_relations.md deleted file mode 100644 index 3ea336363..000000000 --- a/vendor/clap/examples/tutorial_builder/04_03_relations.md +++ /dev/null @@ -1,58 +0,0 @@ -```console -$ 04_03_relations --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_03_relations[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] - -ARGS: - some regular input - -OPTIONS: - -c - -h, --help Print help information - --major auto inc major - --minor auto inc minor - --patch auto inc patch - --set-ver set version manually - --spec-in some special input argument - -V, --version Print version information - -$ 04_03_relations -? failed -error: The following required arguments were not provided: - <--set-ver |--major|--minor|--patch> - -USAGE: - 04_03_relations[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] - -For more information try --help - -$ 04_03_relations --major -Version: 2.2.3 - -$ 04_03_relations --major --minor -? failed -error: The argument '--major' cannot be used with '--minor' - -USAGE: - 04_03_relations[EXE] <--set-ver |--major|--minor|--patch> - -For more information try --help - -$ 04_03_relations --major -c config.toml -? failed -error: The following required arguments were not provided: - > - -USAGE: - 04_03_relations[EXE] -c <--set-ver |--major|--minor|--patch> > - -For more information try --help - -$ 04_03_relations --major -c config.toml --spec-in input.txt -Version: 2.2.3 -Doing work using input input.txt and config config.toml - -``` diff --git a/vendor/clap/examples/tutorial_builder/04_03_relations.rs b/vendor/clap/examples/tutorial_builder/04_03_relations.rs deleted file mode 100644 index 8e26d3ea9..000000000 --- a/vendor/clap/examples/tutorial_builder/04_03_relations.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::path::PathBuf; - -use clap::{arg, command, value_parser, ArgAction, ArgGroup}; - -fn main() { - // Create application like normal - let matches = command!() // requires `cargo` feature - // Add the version arguments - .arg(arg!(--"set-ver" "set version manually").required(false)) - .arg(arg!(--major "auto inc major").action(ArgAction::SetTrue)) - .arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue)) - .arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue)) - // Create a group, make it required, and add the above arguments - .group( - ArgGroup::new("vers") - .required(true) - .args(&["set-ver", "major", "minor", "patch"]), - ) - // Arguments can also be added to a group individually, these two arguments - // are part of the "input" group which is not required - .arg( - arg!([INPUT_FILE] "some regular input") - .value_parser(value_parser!(PathBuf)) - .group("input"), - ) - .arg( - arg!(--"spec-in" "some special input argument") - .required(false) - .value_parser(value_parser!(PathBuf)) - .group("input"), - ) - // Now let's assume we have a -c [config] argument which requires one of - // (but **not** both) the "input" arguments - .arg( - arg!(config: -c ) - .required(false) - .value_parser(value_parser!(PathBuf)) - .requires("input"), - ) - .get_matches(); - - // Let's assume the old version 1.2.3 - let mut major = 1; - let mut minor = 2; - let mut patch = 3; - - // See if --set-ver was used to set the version manually - let version = if let Some(ver) = matches.get_one::("set-ver") { - ver.to_owned() - } else { - // Increment the one requested (in a real program, we'd reset the lower numbers) - let (maj, min, pat) = ( - matches.get_flag("major"), - matches.get_flag("minor"), - matches.get_flag("patch"), - ); - match (maj, min, pat) { - (true, _, _) => major += 1, - (_, true, _) => minor += 1, - (_, _, true) => patch += 1, - _ => unreachable!(), - }; - format!("{}.{}.{}", major, minor, patch) - }; - - println!("Version: {}", version); - - // Check for usage of -c - if matches.contains_id("config") { - let input = matches - .get_one::("INPUT_FILE") - .unwrap_or_else(|| matches.get_one::("spec-in").unwrap()) - .display(); - println!( - "Doing work using input {} and config {}", - input, - matches.get_one::("config").unwrap().display() - ); - } -} diff --git a/vendor/clap/examples/tutorial_builder/04_04_custom.md b/vendor/clap/examples/tutorial_builder/04_04_custom.md deleted file mode 100644 index 26a3df1ab..000000000 --- a/vendor/clap/examples/tutorial_builder/04_04_custom.md +++ /dev/null @@ -1,57 +0,0 @@ -```console -$ 04_04_custom --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] - -ARGS: - some regular input - -OPTIONS: - -c - -h, --help Print help information - --major auto inc major - --minor auto inc minor - --patch auto inc patch - --set-ver set version manually - --spec-in some special input argument - -V, --version Print version information - -$ 04_04_custom -? failed -error: Can only modify one version field - -USAGE: - 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] - -For more information try --help - -$ 04_04_custom --major -Version: 2.2.3 - -$ 04_04_custom --major --minor -? failed -error: Can only modify one version field - -USAGE: - 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] - -For more information try --help - -$ 04_04_custom --major -c config.toml -? failed -Version: 2.2.3 -error: INPUT_FILE or --spec-in is required when using --config - -USAGE: - 04_04_custom[EXE] [OPTIONS] [INPUT_FILE] - -For more information try --help - -$ 04_04_custom --major -c config.toml --spec-in input.txt -Version: 2.2.3 -Doing work using input input.txt and config config.toml - -``` diff --git a/vendor/clap/examples/tutorial_builder/04_04_custom.rs b/vendor/clap/examples/tutorial_builder/04_04_custom.rs deleted file mode 100644 index fb40b2fc4..000000000 --- a/vendor/clap/examples/tutorial_builder/04_04_custom.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::path::PathBuf; - -use clap::{arg, command, value_parser, ArgAction, ErrorKind}; - -fn main() { - // Create application like normal - let mut cmd = command!() // requires `cargo` feature - // Add the version arguments - .arg(arg!(--"set-ver" "set version manually").required(false)) - .arg(arg!(--major "auto inc major").action(ArgAction::SetTrue)) - .arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue)) - .arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue)) - // Arguments can also be added to a group individually, these two arguments - // are part of the "input" group which is not required - .arg(arg!([INPUT_FILE] "some regular input").value_parser(value_parser!(PathBuf))) - .arg( - arg!(--"spec-in" "some special input argument") - .required(false) - .value_parser(value_parser!(PathBuf)), - ) - // Now let's assume we have a -c [config] argument which requires one of - // (but **not** both) the "input" arguments - .arg( - arg!(config: -c ) - .required(false) - .value_parser(value_parser!(PathBuf)), - ); - let matches = cmd.get_matches_mut(); - - // Let's assume the old version 1.2.3 - let mut major = 1; - let mut minor = 2; - let mut patch = 3; - - // See if --set-ver was used to set the version manually - let version = if let Some(ver) = matches.get_one::("set-ver") { - if matches.get_flag("major") || matches.get_flag("minor") || matches.get_flag("patch") { - cmd.error( - ErrorKind::ArgumentConflict, - "Can't do relative and absolute version change", - ) - .exit(); - } - ver.to_string() - } else { - // Increment the one requested (in a real program, we'd reset the lower numbers) - let (maj, min, pat) = ( - matches.get_flag("major"), - matches.get_flag("minor"), - matches.get_flag("patch"), - ); - match (maj, min, pat) { - (true, false, false) => major += 1, - (false, true, false) => minor += 1, - (false, false, true) => patch += 1, - _ => { - cmd.error( - ErrorKind::ArgumentConflict, - "Can only modify one version field", - ) - .exit(); - } - }; - format!("{}.{}.{}", major, minor, patch) - }; - - println!("Version: {}", version); - - // Check for usage of -c - if matches.contains_id("config") { - let input = matches - .get_one::("INPUT_FILE") - .or_else(|| matches.get_one::("spec-in")) - .unwrap_or_else(|| { - cmd.error( - ErrorKind::MissingRequiredArgument, - "INPUT_FILE or --spec-in is required when using --config", - ) - .exit() - }) - .display(); - println!( - "Doing work using input {} and config {}", - input, - matches.get_one::("config").unwrap().display() - ); - } -} diff --git a/vendor/clap/examples/tutorial_builder/05_01_assert.rs b/vendor/clap/examples/tutorial_builder/05_01_assert.rs deleted file mode 100644 index 4b9254230..000000000 --- a/vendor/clap/examples/tutorial_builder/05_01_assert.rs +++ /dev/null @@ -1,25 +0,0 @@ -use clap::{arg, command, value_parser}; - -fn main() { - let matches = cmd().get_matches(); - - // Note, it's safe to call unwrap() because the arg is required - let port: usize = *matches - .get_one::("PORT") - .expect("'PORT' is required and parsing will fail if its missing"); - println!("PORT = {}", port); -} - -fn cmd() -> clap::Command<'static> { - command!() // requires `cargo` feature - .arg( - arg!() - .help("Network port to use") - .value_parser(value_parser!(usize)), - ) -} - -#[test] -fn verify_cmd() { - cmd().debug_assert(); -} diff --git a/vendor/clap/examples/tutorial_derive/01_quick.md b/vendor/clap/examples/tutorial_derive/01_quick.md deleted file mode 100644 index 6f70d2cce..000000000 --- a/vendor/clap/examples/tutorial_derive/01_quick.md +++ /dev/null @@ -1,37 +0,0 @@ -```console -$ 01_quick_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 01_quick_derive[EXE] [OPTIONS] [NAME] [SUBCOMMAND] - -ARGS: - Optional name to operate on - -OPTIONS: - -c, --config Sets a custom config file - -d, --debug Turn debugging information on - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - help Print this message or the help of the given subcommand(s) - test does testing things - -``` - -By default, the program does nothing: -```console -$ 01_quick_derive -Debug mode is off - -``` - -But you can mix and match the various features -```console -$ 01_quick_derive -dd test -Debug mode is on -Not printing testing lists... - -``` diff --git a/vendor/clap/examples/tutorial_derive/01_quick.rs b/vendor/clap/examples/tutorial_derive/01_quick.rs deleted file mode 100644 index 2c2031061..000000000 --- a/vendor/clap/examples/tutorial_derive/01_quick.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::path::PathBuf; - -use clap::{Parser, Subcommand}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - /// Optional name to operate on - #[clap(value_parser)] - name: Option, - - /// Sets a custom config file - #[clap(short, long, value_parser, value_name = "FILE")] - config: Option, - - /// Turn debugging information on - #[clap(short, long, action = clap::ArgAction::Count)] - debug: u8, - - #[clap(subcommand)] - command: Option, -} - -#[derive(Subcommand)] -enum Commands { - /// does testing things - Test { - /// lists test values - #[clap(short, long, action)] - list: bool, - }, -} - -fn main() { - let cli = Cli::parse(); - - // You can check the value provided by positional arguments, or option arguments - if let Some(name) = cli.name.as_deref() { - println!("Value for name: {}", name); - } - - if let Some(config_path) = cli.config.as_deref() { - println!("Value for config: {}", config_path.display()); - } - - // You can see how many times a particular flag or argument occurred - // Note, only flags can have multiple occurrences - match cli.debug { - 0 => println!("Debug mode is off"), - 1 => println!("Debug mode is kind of on"), - 2 => println!("Debug mode is on"), - _ => println!("Don't be crazy"), - } - - // You can check for the existence of subcommands, and if found use their - // matches just as you would the top level cmd - match &cli.command { - Some(Commands::Test { list }) => { - if *list { - println!("Printing testing lists..."); - } else { - println!("Not printing testing lists..."); - } - } - None => {} - } - - // Continued program logic goes here... -} diff --git a/vendor/clap/examples/tutorial_derive/02_app_settings.md b/vendor/clap/examples/tutorial_derive/02_app_settings.md deleted file mode 100644 index ee16c66df..000000000 --- a/vendor/clap/examples/tutorial_derive/02_app_settings.md +++ /dev/null @@ -1,19 +0,0 @@ -```console -$ 02_app_settings_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 02_app_settings_derive[EXE] --two --one - -OPTIONS: - --two - --one - -h, --help Print help information - -V, --version Print version information - -$ 02_app_settings_derive --one -1 --one -3 --two 10 -two: "10" -one: "-3" - -``` diff --git a/vendor/clap/examples/tutorial_derive/02_app_settings.rs b/vendor/clap/examples/tutorial_derive/02_app_settings.rs deleted file mode 100644 index 6a06929bb..000000000 --- a/vendor/clap/examples/tutorial_derive/02_app_settings.rs +++ /dev/null @@ -1,19 +0,0 @@ -use clap::{AppSettings, Parser}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -#[clap(allow_negative_numbers = true)] -#[clap(global_setting(AppSettings::DeriveDisplayOrder))] -struct Cli { - #[clap(long, value_parser)] - two: String, - #[clap(long, value_parser)] - one: String, -} - -fn main() { - let cli = Cli::parse(); - - println!("two: {:?}", cli.two); - println!("one: {:?}", cli.one); -} diff --git a/vendor/clap/examples/tutorial_derive/02_apps.md b/vendor/clap/examples/tutorial_derive/02_apps.md deleted file mode 100644 index 0141581c4..000000000 --- a/vendor/clap/examples/tutorial_derive/02_apps.md +++ /dev/null @@ -1,19 +0,0 @@ -```console -$ 02_apps_derive --help -MyApp 1.0 -Kevin K. -Does awesome things - -USAGE: - 02_apps_derive[EXE] --two --one - -OPTIONS: - -h, --help Print help information - --one - --two - -V, --version Print version information - -$ 02_apps_derive --version -MyApp 1.0 - -``` diff --git a/vendor/clap/examples/tutorial_derive/02_apps.rs b/vendor/clap/examples/tutorial_derive/02_apps.rs deleted file mode 100644 index b97ce1eed..000000000 --- a/vendor/clap/examples/tutorial_derive/02_apps.rs +++ /dev/null @@ -1,20 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(name = "MyApp")] -#[clap(author = "Kevin K. ")] -#[clap(version = "1.0")] -#[clap(about = "Does awesome things", long_about = None)] -struct Cli { - #[clap(long, value_parser)] - two: String, - #[clap(long, value_parser)] - one: String, -} - -fn main() { - let cli = Cli::parse(); - - println!("two: {:?}", cli.two); - println!("one: {:?}", cli.one); -} diff --git a/vendor/clap/examples/tutorial_derive/02_crate.md b/vendor/clap/examples/tutorial_derive/02_crate.md deleted file mode 100644 index 92c820758..000000000 --- a/vendor/clap/examples/tutorial_derive/02_crate.md +++ /dev/null @@ -1,18 +0,0 @@ -```console -$ 02_crate_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 02_crate_derive[EXE] --two --one - -OPTIONS: - -h, --help Print help information - --one - --two - -V, --version Print version information - -$ 02_crate_derive --version -clap [..] - -``` diff --git a/vendor/clap/examples/tutorial_derive/02_crate.rs b/vendor/clap/examples/tutorial_derive/02_crate.rs deleted file mode 100644 index 5576f998c..000000000 --- a/vendor/clap/examples/tutorial_derive/02_crate.rs +++ /dev/null @@ -1,17 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] // Read from `Cargo.toml` -struct Cli { - #[clap(long, value_parser)] - two: String, - #[clap(long, value_parser)] - one: String, -} - -fn main() { - let cli = Cli::parse(); - - println!("two: {:?}", cli.two); - println!("one: {:?}", cli.one); -} diff --git a/vendor/clap/examples/tutorial_derive/03_01_flag_bool.md b/vendor/clap/examples/tutorial_derive/03_01_flag_bool.md deleted file mode 100644 index 0baaa10ca..000000000 --- a/vendor/clap/examples/tutorial_derive/03_01_flag_bool.md +++ /dev/null @@ -1,23 +0,0 @@ -```console -$ 03_01_flag_bool_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_01_flag_bool_derive[EXE] [OPTIONS] - -OPTIONS: - -h, --help Print help information - -v, --verbose - -V, --version Print version information - -$ 03_01_flag_bool_derive -verbose: false - -$ 03_01_flag_bool_derive --verbose -verbose: true - -$ 03_01_flag_bool_derive --verbose --verbose -verbose: true - -``` diff --git a/vendor/clap/examples/tutorial_derive/03_01_flag_bool.rs b/vendor/clap/examples/tutorial_derive/03_01_flag_bool.rs deleted file mode 100644 index de677d8c6..000000000 --- a/vendor/clap/examples/tutorial_derive/03_01_flag_bool.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(short, long, action)] - verbose: bool, -} - -fn main() { - let cli = Cli::parse(); - - println!("verbose: {:?}", cli.verbose); -} diff --git a/vendor/clap/examples/tutorial_derive/03_01_flag_count.md b/vendor/clap/examples/tutorial_derive/03_01_flag_count.md deleted file mode 100644 index 3d5a53084..000000000 --- a/vendor/clap/examples/tutorial_derive/03_01_flag_count.md +++ /dev/null @@ -1,23 +0,0 @@ -```console -$ 03_01_flag_count_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_01_flag_count_derive[EXE] [OPTIONS] - -OPTIONS: - -h, --help Print help information - -v, --verbose - -V, --version Print version information - -$ 03_01_flag_count_derive -verbose: 0 - -$ 03_01_flag_count_derive --verbose -verbose: 1 - -$ 03_01_flag_count_derive --verbose --verbose -verbose: 2 - -``` diff --git a/vendor/clap/examples/tutorial_derive/03_01_flag_count.rs b/vendor/clap/examples/tutorial_derive/03_01_flag_count.rs deleted file mode 100644 index 680f7f5e5..000000000 --- a/vendor/clap/examples/tutorial_derive/03_01_flag_count.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(short, long, action = clap::ArgAction::Count)] - verbose: u8, -} - -fn main() { - let cli = Cli::parse(); - - println!("verbose: {:?}", cli.verbose); -} diff --git a/vendor/clap/examples/tutorial_derive/03_02_option.md b/vendor/clap/examples/tutorial_derive/03_02_option.md deleted file mode 100644 index 84ff7fa74..000000000 --- a/vendor/clap/examples/tutorial_derive/03_02_option.md +++ /dev/null @@ -1,32 +0,0 @@ -```console -$ 03_02_option_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_02_option_derive[EXE] [OPTIONS] - -OPTIONS: - -h, --help Print help information - -n, --name - -V, --version Print version information - -$ 03_02_option_derive -name: None - -$ 03_02_option_derive --name bob -name: Some("bob") - -$ 03_02_option_derive --name=bob -name: Some("bob") - -$ 03_02_option_derive -n bob -name: Some("bob") - -$ 03_02_option_derive -n=bob -name: Some("bob") - -$ 03_02_option_derive -nbob -name: Some("bob") - -``` diff --git a/vendor/clap/examples/tutorial_derive/03_02_option.rs b/vendor/clap/examples/tutorial_derive/03_02_option.rs deleted file mode 100644 index 75b67afe7..000000000 --- a/vendor/clap/examples/tutorial_derive/03_02_option.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(short, long, value_parser)] - name: Option, -} - -fn main() { - let cli = Cli::parse(); - - println!("name: {:?}", cli.name.as_deref()); -} diff --git a/vendor/clap/examples/tutorial_derive/03_03_positional.md b/vendor/clap/examples/tutorial_derive/03_03_positional.md deleted file mode 100644 index 7281fe3ff..000000000 --- a/vendor/clap/examples/tutorial_derive/03_03_positional.md +++ /dev/null @@ -1,22 +0,0 @@ -```console -$ 03_03_positional_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_03_positional_derive[EXE] [NAME] - -ARGS: - - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 03_03_positional_derive -name: None - -$ 03_03_positional_derive bob -name: Some("bob") - -``` diff --git a/vendor/clap/examples/tutorial_derive/03_03_positional.rs b/vendor/clap/examples/tutorial_derive/03_03_positional.rs deleted file mode 100644 index 7478951f1..000000000 --- a/vendor/clap/examples/tutorial_derive/03_03_positional.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(value_parser)] - name: Option, -} - -fn main() { - let cli = Cli::parse(); - - println!("name: {:?}", cli.name.as_deref()); -} diff --git a/vendor/clap/examples/tutorial_derive/03_04_subcommands.md b/vendor/clap/examples/tutorial_derive/03_04_subcommands.md deleted file mode 100644 index 02f96e3d3..000000000 --- a/vendor/clap/examples/tutorial_derive/03_04_subcommands.md +++ /dev/null @@ -1,64 +0,0 @@ -```console -$ 03_04_subcommands_derive help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_04_subcommands_derive[EXE] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - add Adds files to myapp - help Print this message or the help of the given subcommand(s) - -$ 03_04_subcommands_derive help add -03_04_subcommands_derive[EXE]-add [..] -Adds files to myapp - -USAGE: - 03_04_subcommands_derive[EXE] add [NAME] - -ARGS: - - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 03_04_subcommands_derive add bob -'myapp add' was used, name is: Some("bob") - -``` - -Because we used `command: Commands` instead of `command: Option`: -```console -$ 03_04_subcommands_derive -? failed -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_04_subcommands_derive[EXE] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -SUBCOMMANDS: - add Adds files to myapp - help Print this message or the help of the given subcommand(s) - -``` - -Because we added `#[clap(propagate_version = true)]`: -```console -$ 03_04_subcommands_derive --version -clap [..] - -$ 03_04_subcommands_derive add --version -03_04_subcommands_derive[EXE]-add [..] - -``` diff --git a/vendor/clap/examples/tutorial_derive/03_04_subcommands.rs b/vendor/clap/examples/tutorial_derive/03_04_subcommands.rs deleted file mode 100644 index 62a45a97e..000000000 --- a/vendor/clap/examples/tutorial_derive/03_04_subcommands.rs +++ /dev/null @@ -1,30 +0,0 @@ -use clap::{Parser, Subcommand}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -#[clap(propagate_version = true)] -struct Cli { - #[clap(subcommand)] - command: Commands, -} - -#[derive(Subcommand)] -enum Commands { - /// Adds files to myapp - Add { - #[clap(value_parser)] - name: Option, - }, -} - -fn main() { - let cli = Cli::parse(); - - // You can check for the existence of subcommands, and if found use their - // matches just as you would the top level cmd - match &cli.command { - Commands::Add { name } => { - println!("'myapp add' was used, name is: {:?}", name) - } - } -} diff --git a/vendor/clap/examples/tutorial_derive/03_04_subcommands_alt.rs b/vendor/clap/examples/tutorial_derive/03_04_subcommands_alt.rs deleted file mode 100644 index b6124936c..000000000 --- a/vendor/clap/examples/tutorial_derive/03_04_subcommands_alt.rs +++ /dev/null @@ -1,33 +0,0 @@ -use clap::{Args, Parser, Subcommand}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -#[clap(propagate_version = true)] -struct Cli { - #[clap(subcommand)] - command: Commands, -} - -#[derive(Subcommand)] -enum Commands { - /// Adds files to myapp - Add(Add), -} - -#[derive(Args)] -struct Add { - #[clap(value_parser)] - name: Option, -} - -fn main() { - let cli = Cli::parse(); - - // You can check for the existence of subcommands, and if found use their - // matches just as you would the top level cmd - match &cli.command { - Commands::Add(name) => { - println!("'myapp add' was used, name is: {:?}", name.name) - } - } -} diff --git a/vendor/clap/examples/tutorial_derive/03_05_default_values.md b/vendor/clap/examples/tutorial_derive/03_05_default_values.md deleted file mode 100644 index f7315e736..000000000 --- a/vendor/clap/examples/tutorial_derive/03_05_default_values.md +++ /dev/null @@ -1,22 +0,0 @@ -```console -$ 03_05_default_values_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 03_05_default_values_derive[EXE] [NAME] - -ARGS: - [default: alice] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 03_05_default_values_derive -name: "alice" - -$ 03_05_default_values_derive bob -name: "bob" - -``` diff --git a/vendor/clap/examples/tutorial_derive/03_05_default_values.rs b/vendor/clap/examples/tutorial_derive/03_05_default_values.rs deleted file mode 100644 index 10a1ec808..000000000 --- a/vendor/clap/examples/tutorial_derive/03_05_default_values.rs +++ /dev/null @@ -1,14 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(default_value_t = String::from("alice"), value_parser)] - name: String, -} - -fn main() { - let cli = Cli::parse(); - - println!("name: {:?}", cli.name); -} diff --git a/vendor/clap/examples/tutorial_derive/04_01_enum.md b/vendor/clap/examples/tutorial_derive/04_01_enum.md deleted file mode 100644 index 2523af924..000000000 --- a/vendor/clap/examples/tutorial_derive/04_01_enum.md +++ /dev/null @@ -1,29 +0,0 @@ -```console -$ 04_01_enum_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_01_enum_derive[EXE] - -ARGS: - What mode to run the program in [possible values: fast, slow] - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_01_enum_derive fast -Hare - -$ 04_01_enum_derive slow -Tortoise - -$ 04_01_enum_derive medium -? failed -error: "medium" isn't a valid value for '' - [possible values: fast, slow] - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_derive/04_01_enum.rs b/vendor/clap/examples/tutorial_derive/04_01_enum.rs deleted file mode 100644 index 1ac984288..000000000 --- a/vendor/clap/examples/tutorial_derive/04_01_enum.rs +++ /dev/null @@ -1,28 +0,0 @@ -use clap::{Parser, ValueEnum}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - /// What mode to run the program in - #[clap(arg_enum, value_parser)] - mode: Mode, -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] -enum Mode { - Fast, - Slow, -} - -fn main() { - let cli = Cli::parse(); - - match cli.mode { - Mode::Fast => { - println!("Hare"); - } - Mode::Slow => { - println!("Tortoise"); - } - } -} diff --git a/vendor/clap/examples/tutorial_derive/04_02_parse.md b/vendor/clap/examples/tutorial_derive/04_02_parse.md deleted file mode 100644 index 6079ef193..000000000 --- a/vendor/clap/examples/tutorial_derive/04_02_parse.md +++ /dev/null @@ -1,31 +0,0 @@ -```console -$ 04_02_parse_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_02_parse_derive[EXE] - -ARGS: - Network port to use - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_02_parse_derive 22 -PORT = 22 - -$ 04_02_parse_derive foobar -? failed -error: Invalid value "foobar" for '': invalid digit found in string - -For more information try --help - -$ 04_02_parse_derive 0 -? failed -error: Invalid value "0" for '': 0 is not in 1..=65535 - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_derive/04_02_parse.rs b/vendor/clap/examples/tutorial_derive/04_02_parse.rs deleted file mode 100644 index 6336a9cf1..000000000 --- a/vendor/clap/examples/tutorial_derive/04_02_parse.rs +++ /dev/null @@ -1,15 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - /// Network port to use - #[clap(value_parser = clap::value_parser!(u16).range(1..))] - port: u16, -} - -fn main() { - let cli = Cli::parse(); - - println!("PORT = {}", cli.port); -} diff --git a/vendor/clap/examples/tutorial_derive/04_02_validate.md b/vendor/clap/examples/tutorial_derive/04_02_validate.md deleted file mode 100644 index cc43440ef..000000000 --- a/vendor/clap/examples/tutorial_derive/04_02_validate.md +++ /dev/null @@ -1,31 +0,0 @@ -```console -$ 04_02_validate_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_02_validate_derive[EXE] - -ARGS: - Network port to use - -OPTIONS: - -h, --help Print help information - -V, --version Print version information - -$ 04_02_validate_derive 22 -PORT = 22 - -$ 04_02_validate_derive foobar -? failed -error: Invalid value "foobar" for '': `foobar` isn't a port number - -For more information try --help - -$ 04_02_validate_derive 0 -? failed -error: Invalid value "0" for '': Port not in range 1-65535 - -For more information try --help - -``` diff --git a/vendor/clap/examples/tutorial_derive/04_02_validate.rs b/vendor/clap/examples/tutorial_derive/04_02_validate.rs deleted file mode 100644 index 7dac79c9f..000000000 --- a/vendor/clap/examples/tutorial_derive/04_02_validate.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::ops::RangeInclusive; - -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - /// Network port to use - #[clap(value_parser = port_in_range)] - port: u16, -} - -fn main() { - let cli = Cli::parse(); - - println!("PORT = {}", cli.port); -} - -const PORT_RANGE: RangeInclusive = 1..=65535; - -fn port_in_range(s: &str) -> Result { - let port: usize = s - .parse() - .map_err(|_| format!("`{}` isn't a port number", s))?; - if PORT_RANGE.contains(&port) { - Ok(port as u16) - } else { - Err(format!( - "Port not in range {}-{}", - PORT_RANGE.start(), - PORT_RANGE.end() - )) - } -} diff --git a/vendor/clap/examples/tutorial_derive/04_03_relations.md b/vendor/clap/examples/tutorial_derive/04_03_relations.md deleted file mode 100644 index 4f5703d82..000000000 --- a/vendor/clap/examples/tutorial_derive/04_03_relations.md +++ /dev/null @@ -1,58 +0,0 @@ -```console -$ 04_03_relations_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_03_relations_derive[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] - -ARGS: - some regular input - -OPTIONS: - -c - -h, --help Print help information - --major auto inc major - --minor auto inc minor - --patch auto inc patch - --set-ver set version manually - --spec-in some special input argument - -V, --version Print version information - -$ 04_03_relations_derive -? failed -error: The following required arguments were not provided: - <--set-ver |--major|--minor|--patch> - -USAGE: - 04_03_relations_derive[EXE] [OPTIONS] <--set-ver |--major|--minor|--patch> [INPUT_FILE] - -For more information try --help - -$ 04_03_relations_derive --major -Version: 2.2.3 - -$ 04_03_relations_derive --major --minor -? failed -error: The argument '--major' cannot be used with '--minor' - -USAGE: - 04_03_relations_derive[EXE] <--set-ver |--major|--minor|--patch> - -For more information try --help - -$ 04_03_relations_derive --major -c config.toml -? failed -error: The following required arguments were not provided: - > - -USAGE: - 04_03_relations_derive[EXE] -c <--set-ver |--major|--minor|--patch> > - -For more information try --help - -$ 04_03_relations_derive --major -c config.toml --spec-in input.txt -Version: 2.2.3 -Doing work using input input.txt and config config.toml - -``` diff --git a/vendor/clap/examples/tutorial_derive/04_03_relations.rs b/vendor/clap/examples/tutorial_derive/04_03_relations.rs deleted file mode 100644 index 37efe95e3..000000000 --- a/vendor/clap/examples/tutorial_derive/04_03_relations.rs +++ /dev/null @@ -1,72 +0,0 @@ -use clap::{ArgGroup, Parser}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -#[clap(group( - ArgGroup::new("vers") - .required(true) - .args(&["set-ver", "major", "minor", "patch"]), - ))] -struct Cli { - /// set version manually - #[clap(long, value_name = "VER", value_parser)] - set_ver: Option, - - /// auto inc major - #[clap(long, action)] - major: bool, - - /// auto inc minor - #[clap(long, action)] - minor: bool, - - /// auto inc patch - #[clap(long, action)] - patch: bool, - - /// some regular input - #[clap(group = "input", value_parser)] - input_file: Option, - - /// some special input argument - #[clap(long, group = "input", value_parser)] - spec_in: Option, - - #[clap(short, requires = "input", value_parser)] - config: Option, -} - -fn main() { - let cli = Cli::parse(); - - // Let's assume the old version 1.2.3 - let mut major = 1; - let mut minor = 2; - let mut patch = 3; - - // See if --set_ver was used to set the version manually - let version = if let Some(ver) = cli.set_ver.as_deref() { - ver.to_string() - } else { - // Increment the one requested (in a real program, we'd reset the lower numbers) - let (maj, min, pat) = (cli.major, cli.minor, cli.patch); - match (maj, min, pat) { - (true, _, _) => major += 1, - (_, true, _) => minor += 1, - (_, _, true) => patch += 1, - _ => unreachable!(), - }; - format!("{}.{}.{}", major, minor, patch) - }; - - println!("Version: {}", version); - - // Check for usage of -c - if let Some(config) = cli.config.as_deref() { - let input = cli - .input_file - .as_deref() - .unwrap_or_else(|| cli.spec_in.as_deref().unwrap()); - println!("Doing work using input {} and config {}", input, config); - } -} diff --git a/vendor/clap/examples/tutorial_derive/04_04_custom.md b/vendor/clap/examples/tutorial_derive/04_04_custom.md deleted file mode 100644 index 0f19bfe31..000000000 --- a/vendor/clap/examples/tutorial_derive/04_04_custom.md +++ /dev/null @@ -1,57 +0,0 @@ -```console -$ 04_04_custom_derive --help -clap [..] -A simple to use, efficient, and full-featured Command Line Argument Parser - -USAGE: - 04_04_custom_derive[EXE] [OPTIONS] [INPUT_FILE] - -ARGS: - some regular input - -OPTIONS: - -c - -h, --help Print help information - --major auto inc major - --minor auto inc minor - --patch auto inc patch - --set-ver set version manually - --spec-in some special input argument - -V, --version Print version information - -$ 04_04_custom_derive -? failed -error: Can only modify one version field - -USAGE: - clap [OPTIONS] [INPUT_FILE] - -For more information try --help - -$ 04_04_custom_derive --major -Version: 2.2.3 - -$ 04_04_custom_derive --major --minor -? failed -error: Can only modify one version field - -USAGE: - clap [OPTIONS] [INPUT_FILE] - -For more information try --help - -$ 04_04_custom_derive --major -c config.toml -? failed -Version: 2.2.3 -error: INPUT_FILE or --spec-in is required when using --config - -USAGE: - clap [OPTIONS] [INPUT_FILE] - -For more information try --help - -$ 04_04_custom_derive --major -c config.toml --spec-in input.txt -Version: 2.2.3 -Doing work using input input.txt and config config.toml - -``` diff --git a/vendor/clap/examples/tutorial_derive/04_04_custom.rs b/vendor/clap/examples/tutorial_derive/04_04_custom.rs deleted file mode 100644 index 454d489c1..000000000 --- a/vendor/clap/examples/tutorial_derive/04_04_custom.rs +++ /dev/null @@ -1,93 +0,0 @@ -use clap::{CommandFactory, ErrorKind, Parser}; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - /// set version manually - #[clap(long, value_name = "VER", value_parser)] - set_ver: Option, - - /// auto inc major - #[clap(long, action)] - major: bool, - - /// auto inc minor - #[clap(long, action)] - minor: bool, - - /// auto inc patch - #[clap(long, action)] - patch: bool, - - /// some regular input - #[clap(value_parser)] - input_file: Option, - - /// some special input argument - #[clap(long, value_parser)] - spec_in: Option, - - #[clap(short, value_parser)] - config: Option, -} - -fn main() { - let cli = Cli::parse(); - - // Let's assume the old version 1.2.3 - let mut major = 1; - let mut minor = 2; - let mut patch = 3; - - // See if --set-ver was used to set the version manually - let version = if let Some(ver) = cli.set_ver.as_deref() { - if cli.major || cli.minor || cli.patch { - let mut cmd = Cli::command(); - cmd.error( - ErrorKind::ArgumentConflict, - "Can't do relative and absolute version change", - ) - .exit(); - } - ver.to_string() - } else { - // Increment the one requested (in a real program, we'd reset the lower numbers) - let (maj, min, pat) = (cli.major, cli.minor, cli.patch); - match (maj, min, pat) { - (true, false, false) => major += 1, - (false, true, false) => minor += 1, - (false, false, true) => patch += 1, - _ => { - let mut cmd = Cli::command(); - cmd.error( - ErrorKind::ArgumentConflict, - "Can only modify one version field", - ) - .exit(); - } - }; - format!("{}.{}.{}", major, minor, patch) - }; - - println!("Version: {}", version); - - // Check for usage of -c - if let Some(config) = cli.config.as_deref() { - // todo: remove `#[allow(clippy::or_fun_call)]` lint when MSRV is bumped. - #[allow(clippy::or_fun_call)] - let input = cli - .input_file - .as_deref() - // 'or' is preferred to 'or_else' here since `Option::as_deref` is 'const' - .or(cli.spec_in.as_deref()) - .unwrap_or_else(|| { - let mut cmd = Cli::command(); - cmd.error( - ErrorKind::MissingRequiredArgument, - "INPUT_FILE or --spec-in is required when using --config", - ) - .exit() - }); - println!("Doing work using input {} and config {}", input, config); - } -} diff --git a/vendor/clap/examples/tutorial_derive/05_01_assert.rs b/vendor/clap/examples/tutorial_derive/05_01_assert.rs deleted file mode 100644 index 66dca727f..000000000 --- a/vendor/clap/examples/tutorial_derive/05_01_assert.rs +++ /dev/null @@ -1,21 +0,0 @@ -use clap::Parser; - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - /// Network port to use - #[clap(value_parser)] - port: u16, -} - -fn main() { - let cli = Cli::parse(); - - println!("PORT = {}", cli.port); -} - -#[test] -fn verify_cli() { - use clap::CommandFactory; - Cli::command().debug_assert() -} diff --git a/vendor/clap/examples/typed-derive.md b/vendor/clap/examples/typed-derive.md deleted file mode 100644 index 9c7615c63..000000000 --- a/vendor/clap/examples/typed-derive.md +++ /dev/null @@ -1,84 +0,0 @@ -**This requires enabling the [`derive` feature flag][crate::_features].** - -Help: -```console -$ typed-derive --help -clap - -USAGE: - typed-derive[EXE] [OPTIONS] - -OPTIONS: - --bind Handle IP addresses - -D Hand-written parser for tuples - -h, --help Print help information - -I