CodeSampleX

Пример

clap 4.6.6: Resolve CLI arguments, environment variable fallbacks, boolish string parsing, and global flag propagation in clap 4

Проверенный пример — cargo clap 4.6.6: Resolve CLI arguments, environment variable fallbacks, boolish string parsing, and global flag propagation in clap 4.…

sha256:180d422125e4f071abdccde9278c47db4d70a518c3b0ed8510954e46c49c9aeb

Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла. Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди. MIT-0

Свидетельства выполнения

Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.

Основа свидетельства
Подписанный контракт пройден
Квитанции проверки
3
Ключи подписи, собравшие его
2
Заявленная среда rust linux x64 rust rust cargo

Среды запусков проверки

Окружение Контракт Этапы Запуск
rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1
2026-08-16
rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1
2026-08-18
rust 1 · linux alpine/x64 · docker ed25519:c1973797be207ac4 FAIL compile:SKIPPED · contract:FAIL · load:SKIPPED · resolve:PASS
CONTAINER_RUN · cargo@1rust:1-alpine@sha256:a10e64dd139b…
2026-09-08

Кейс

HOW
Цель
Resolve CLI arguments, environment variable fallbacks, boolish string parsing, and global flag propagation in clap 4
Пакеты
Символы
  • Parser::try_parse_from
  • ArgAction::SetTrue
  • ArgAction::Set
  • BoolishValueParser
  • ArgMatches::get_flag
  • ArgMatches::get_one
  • ErrorKind::InvalidValue
  • ErrorKind::ValueValidation
  • ErrorKind::UnknownArgument
Окружение
rust
Создан
2026-08-16T08:09:44Z

Контракт

  1. assert default values populate when environment variables and CLI arguments are omitted
  2. assert environment variable fallbacks populate fields when CLI flags are absent
  3. assert CLI options take strict precedence over environment variables
  4. assert empty string environment variable for integer fails with ValueValidation instead of falling back to default
  5. assert empty string environment variable for Option<String> resolves to Some("") rather than None
  6. assert default derive bool with env uses strict bool::from_str, rejecting 1, 0, yes, and no with InvalidValue
  7. assert BoolishValueParser resolves truthy and falsy strings including 1, 0, yes, no, on, off to boolean values
  8. assert global flags propagate across subcommands while non-global options placed after subcommands fail with UnknownArgument
  9. assert get_flag returns false for omitted SetTrue flag and panics when called on ArgAction::Set argument

Файлы

  • Cargo.lock
  • Cargo.toml
  • NOTES.md
  • csx.json
  • src/lib.rs
  • tests/contract.rs

Скачать артефакт с исходным кодом (tar.gz)

Исходный код

Cargo.lock
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4

[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
 "anstyle",
 "anstyle-parse",
 "anstyle-query",
 "anstyle-wincon",
 "colorchoice",
 "is_terminal_polyfill",
 "utf8parse",
]

[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"

[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
 "utf8parse",
]

[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
 "windows-sys",
]

[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
 "anstyle",
 "once_cell_polyfill",
 "windows-sys",
]

[[package]]
name = "clap"
version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca"
dependencies = [
 "clap_builder",
 "clap_derive",
]

[[package]]
name = "clap_builder"
version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889"
dependencies = [
 "anstream",
 "anstyle",
 "clap_lex",
 "strsim",
]

[[package]]
name = "clap_derive"
version = "4.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
dependencies = [
 "heck",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"

[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"

[[package]]
name = "csx-sample-clap-env-config"
version = "1.0.0"
dependencies = [
 "clap",
]

[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"

[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"

[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"

[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"

[[package]]
name = "syn"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-ident",
]

[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"

[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"

[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"

[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
 "windows-link",
]
Cargo.toml
[package]
name = "csx-sample-clap-env-config"
version = "1.0.0"
edition = "2021"
license = "MIT-0"

[dependencies]
clap = { version = "4.6.6", features = ["derive", "env"] }
NOTES.md
# Notes

## Prior Solution Found
- `search_known_solution` returned sample `sha256:6e0aceb749a7c19cc2aa7a185f5f9cac427fedb08e50c9afc51b0c69de42d116` ("Define and test a clap 4 derive CLI across the #[clap] to #[command] and #[arg] attribute split, checking outcomes with try_parse_from and ErrorKind instead of a process"), which demonstrated the macro attribute migration from clap 3 to 4, `try_parse_from`, and `ValueEnum`.

## What a Model Would Have Written Instead
- A model writes `#[arg(long, env = "...")]` expecting it to work out of the box without the `"env"` cargo feature, assumes standard shell/CI environment conventions like `DEBUG=1` or `DEBUG=0` will automatically parse into `bool` fields, assumes empty environment variables (`PORT=""`) will silently fall back to `default_value_t`, assumes root command options automatically apply across subcommands without `global = true`, and calls `matches.get_flag()` indiscriminately on `ArgAction::Set` arguments.

## How the Wrong Version Fails
- It fails at compile time with `no method named 'env' found for struct 'Arg'` when the `"env"` cargo feature is missing; it fails loudly at runtime with `ErrorKind::InvalidValue` when POSIX/shell boolean values like `"1"` or `"0"` are passed via environment variables to default `bool` fields; it fails loudly with `ErrorKind::ValueValidation` on empty environment strings instead of falling back to default values; it fails with `ErrorKind::UnknownArgument` when non-global options are placed after subcommands; and calling `matches.get_flag()` on an `ArgAction::Set` argument panics immediately at runtime with a definition mismatch.
csx.json
{"case":{"caseId":"case:sha256:8d843fe7d74b0a6a747d85a18c1540dc2879daf26573abdd32c13e499ca91c66","contract":["assert default values populate when environment variables and CLI arguments are omitted","assert environment variable fallbacks populate fields when CLI flags are absent","assert CLI options take strict precedence over environment variables","assert empty string environment variable for integer fails with ValueValidation instead of falling back to default","assert empty string environment variable for Option\u003cString\u003e resolves to Some(\"\") rather than None","assert default derive bool with env uses strict bool::from_str, rejecting 1, 0, yes, and no with InvalidValue","assert BoolishValueParser resolves truthy and falsy strings including 1, 0, yes, no, on, off to boolean values","assert global flags propagate across subcommands while non-global options placed after subcommands fail with UnknownArgument","assert get_flag returns false for omitted SetTrue flag and panics when called on ArgAction::Set argument"],"goal":"Resolve CLI arguments, environment variable fallbacks, boolish string parsing, and global flag propagation in clap 4","kind":"HOW","packages":["pkg:cargo/clap@4.6.6"],"schemaVersion":1,"symbols":["Parser::try_parse_from","ArgAction::SetTrue","ArgAction::Set","BoolishValueParser","ArgMatches::get_flag","ArgMatches::get_one","ErrorKind::InvalidValue","ErrorKind::ValueValidation","ErrorKind::UnknownArgument"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/clap@4.6.6"],"schemaVersion":1,"symbols":["Parser::try_parse_from","ArgAction::SetTrue","ArgAction::Set","BoolishValueParser","ArgMatches::get_flag","ArgMatches::get_one","ErrorKind::InvalidValue","ErrorKind::ValueValidation","ErrorKind::UnknownArgument"],"verifierAdapter":"cargo@1"}
src/lib.rs
use clap::builder::BoolishValueParser;
use clap::{Arg, ArgAction, Command, Parser, Subcommand};

/// Configuration CLI demonstrating environment variable fallbacks,
/// strict boolean parsing, and default value precedence.
#[derive(Parser, Debug, PartialEq)]
#[command(name = "server")]
pub struct ServerCli {
    /// Server bind host with environment variable fallback.
    #[arg(long, env = "APP_HOST", default_value = "127.0.0.1")]
    pub host: String,

    /// Server listen port with environment variable fallback.
    #[arg(long, env = "APP_PORT", default_value_t = 8080)]
    pub port: u16,

    /// Standard boolean flag using clap's default bool parser (strict bool::from_str).
    /// Accepts only "true" and "false" from env; rejects "1", "0", "yes", "no".
    #[arg(long, env = "APP_DEBUG")]
    pub debug: bool,

    /// Flexible boolean flag using BoolishValueParser.
    /// Accepts "true", "false", "1", "0", "yes", "no", "t", "f", "on", "off".
    #[arg(long, env = "APP_VERBOSE", value_parser = BoolishValueParser::new())]
    pub verbose: bool,

    /// Optional string token with environment variable fallback.
    #[arg(long, env = "APP_TOKEN")]
    pub token: Option<String>,
}

/// Root CLI demonstrating global flag propagation across subcommands.
#[derive(Parser, Debug, PartialEq)]
#[command(name = "app")]
pub struct RootCli {
    /// Global flag: available to root and all subcommands regardless of position.
    #[arg(short, long, global = true)]
    pub quiet: bool,

    /// Non-global option: only accepted before the subcommand.
    #[arg(short, long)]
    pub config: Option<String>,

    #[command(subcommand)]
    pub command: Option<SubCommands>,
}

#[derive(Subcommand, Debug, PartialEq)]
pub enum SubCommands {
    /// Start worker process.
    Start {
        #[arg(long, default_value_t = 1)]
        workers: u32,
    },
}

/// Creates a builder Command demonstrating ArgAction::SetTrue vs ArgAction::Set.
pub fn create_builder_cmd() -> Command {
    Command::new("builder-app")
        .arg(
            Arg::new("flag")
                .long("flag")
                .action(ArgAction::SetTrue),
        )
        .arg(
            Arg::new("param")
                .long("param")
                .value_parser(clap::value_parser!(String))
                .action(ArgAction::Set),
        )
}
tests/contract.rs
use clap::error::ErrorKind;
use clap::Parser;
use csx_sample_clap_env_config::{create_builder_cmd, RootCli, ServerCli, SubCommands};
use std::env;
use std::panic::AssertUnwindSafe;
use std::sync::Mutex;

// Global lock to serialize environment variable mutations across tests
static ENV_MUTEX: Mutex<()> = Mutex::new(());

fn clean_env() {
    env::remove_var("APP_HOST");
    env::remove_var("APP_PORT");
    env::remove_var("APP_DEBUG");
    env::remove_var("APP_VERBOSE");
    env::remove_var("APP_TOKEN");
}

#[test]
fn test_default_values_when_env_unset() {
    let _lock = ENV_MUTEX.lock().unwrap();
    clean_env();

    let cli = ServerCli::try_parse_from(["server"]).expect("minimal invocation parses defaults");
    assert_eq!(cli.host, "127.0.0.1", "host should take default string");
    assert_eq!(cli.port, 8080, "port should take default_value_t integer");
    assert_eq!(cli.debug, false, "debug flag should default to false");
    assert_eq!(cli.verbose, false, "verbose flag should default to false");
    assert_eq!(cli.token, None, "token should default to None");
}

#[test]
fn test_env_var_fallback_and_cli_precedence() {
    let _lock = ENV_MUTEX.lock().unwrap();
    clean_env();

    env::set_var("APP_HOST", "192.0.2.1");
    env::set_var("APP_PORT", "9000");
    env::set_var("APP_TOKEN", "secret-token");

    // Environment variables take precedence over default values
    let cli = ServerCli::try_parse_from(["server"]).expect("parses from env");
    assert_eq!(cli.host, "192.0.2.1", "host should resolve from APP_HOST");
    assert_eq!(cli.port, 9000, "port should resolve from APP_PORT");
    assert_eq!(cli.token.as_deref(), Some("secret-token"), "token should resolve from APP_TOKEN");

    // CLI options take strict precedence over environment variables
    let cli_override = ServerCli::try_parse_from([
        "server",
        "--host",
        "198.51.100.1",
        "--port",
        "3000",
        "--token",
        "cli-token",
    ])
    .expect("cli override parses");
    assert_eq!(cli_override.host, "198.51.100.1", "CLI flag overrides APP_HOST");
    assert_eq!(cli_override.port, 3000, "CLI flag overrides APP_PORT");
    assert_eq!(cli_override.token.as_deref(), Some("cli-token"), "CLI flag overrides APP_TOKEN");

    clean_env();
}

#[test]
fn test_empty_env_var_trap() {
    let _lock = ENV_MUTEX.lock().unwrap();
    clean_env();

    // Trap: An empty env var for typed integers fails with ValueValidation
    // instead of silently falling back to default_value_t.
    env::set_var("APP_PORT", "");
    let err = ServerCli::try_parse_from(["server"]).unwrap_err();
    assert_eq!(
        err.kind(),
        ErrorKind::ValueValidation,
        "empty env string for integer must fail with ValueValidation, not silently use default"
    );

    // Trap: An empty env var for Option<String> parses as Some(""), not None.
    clean_env();
    env::set_var("APP_TOKEN", "");
    let cli = ServerCli::try_parse_from(["server"]).expect("parses empty string token");
    assert_eq!(
        cli.token,
        Some("".to_string()),
        "empty env var for Option<String> yields Some(\"\"), not None"
    );

    clean_env();
}

#[test]
fn test_strict_bool_env_trap() {
    let _lock = ENV_MUTEX.lock().unwrap();
    clean_env();

    // Default derive bool uses bool::from_str, accepting only literal "true" and "false"
    env::set_var("APP_DEBUG", "true");
    let cli_true = ServerCli::try_parse_from(["server"]).unwrap();
    assert_eq!(cli_true.debug, true, "APP_DEBUG='true' resolves to true");

    env::set_var("APP_DEBUG", "false");
    let cli_false = ServerCli::try_parse_from(["server"]).unwrap();
    assert_eq!(cli_false.debug, false, "APP_DEBUG='false' resolves to false");

    // Trap: Common shell/POSIX boolean conventions ("1", "0", "yes", "no") fail with InvalidValue
    for invalid_bool in ["1", "0", "yes", "no", "on", "off", ""] {
        env::set_var("APP_DEBUG", invalid_bool);
        let err = ServerCli::try_parse_from(["server"]).unwrap_err();
        assert_eq!(
            err.kind(),
            ErrorKind::InvalidValue,
            "APP_DEBUG='{invalid_bool}' must fail with InvalidValue under default bool parser"
        );
    }

    clean_env();
}

#[test]
fn test_boolish_value_parser_flexibility() {
    let _lock = ENV_MUTEX.lock().unwrap();
    clean_env();

    // BoolishValueParser accepts truthy strings: "true", "1", "yes", "on", "t"
    for truthy in ["true", "1", "yes", "on", "t"] {
        env::set_var("APP_VERBOSE", truthy);
        let cli = ServerCli::try_parse_from(["server"]).unwrap();
        assert_eq!(cli.verbose, true, "APP_VERBOSE='{truthy}' should parse to true");
    }

    // BoolishValueParser accepts falsy strings: "false", "0", "no", "off", "f"
    for falsy in ["false", "0", "no", "off", "f"] {
        env::set_var("APP_VERBOSE", falsy);
        let cli = ServerCli::try_parse_from(["server"]).unwrap();
        assert_eq!(cli.verbose, false, "APP_VERBOSE='{falsy}' should parse to false");
    }

    // Unrecognized string fails with ValueValidation
    env::set_var("APP_VERBOSE", "not_a_bool");
    let err = ServerCli::try_parse_from(["server"]).unwrap_err();
    assert_eq!(
        err.kind(),
        ErrorKind::ValueValidation,
        "invalid string with BoolishValueParser fails with ValueValidation"
    );

    clean_env();
}

#[test]
fn test_global_flag_propagation_across_subcommands() {
    let _lock = ENV_MUTEX.lock().unwrap();
    clean_env();

    // Global flag (--quiet) passed AFTER subcommand succeeds
    let cli_after = RootCli::try_parse_from(["app", "start", "--workers", "4", "--quiet"])
        .expect("global flag after subcommand must be accepted");
    assert_eq!(cli_after.quiet, true);
    assert_eq!(cli_after.command, Some(SubCommands::Start { workers: 4 }));

    // Global flag (--quiet) passed BEFORE subcommand succeeds
    let cli_before = RootCli::try_parse_from(["app", "--quiet", "start", "--workers", "2"])
        .expect("global flag before subcommand must be accepted");
    assert_eq!(cli_before.quiet, true);
    assert_eq!(cli_before.command, Some(SubCommands::Start { workers: 2 }));

    // Non-global flag (--config) passed BEFORE subcommand succeeds
    let cli_config_before =
        RootCli::try_parse_from(["app", "--config", "config.toml", "start"]).unwrap();
    assert_eq!(cli_config_before.config.as_deref(), Some("config.toml"));

    // Trap: Non-global flag (--config) passed AFTER subcommand fails with UnknownArgument
    let err = RootCli::try_parse_from(["app", "start", "--config", "config.toml"]).unwrap_err();
    assert_eq!(
        err.kind(),
        ErrorKind::UnknownArgument,
        "non-global option placed after subcommand must be rejected with UnknownArgument"
    );
}

#[test]
fn test_builder_get_flag_vs_get_one_contract() {
    let cmd = create_builder_cmd();

    // When SetTrue flag is omitted: get_flag returns false, get_one::<bool> returns Some(&false)
    let matches_omitted = cmd
        .clone()
        .try_get_matches_from(["builder-app"])
        .expect("builder matches without flag");
    assert_eq!(
        matches_omitted.get_flag("flag"),
        false,
        "get_flag returns false for omitted SetTrue flag"
    );
    assert_eq!(
        matches_omitted.get_one::<bool>("flag"),
        Some(&false),
        "get_one::<bool> returns Some(&false) when SetTrue flag is omitted"
    );

    // Matching a present SetTrue flag
    let matches_present = cmd
        .clone()
        .try_get_matches_from(["builder-app", "--flag"])
        .expect("builder matches flag");
    assert_eq!(
        matches_present.get_flag("flag"),
        true,
        "get_flag returns true for matched SetTrue flag"
    );
    assert_eq!(
        matches_present.get_one::<bool>("flag"),
        Some(&true),
        "get_one::<bool> returns Some(&true) when flag was present"
    );

    // Matching an ArgAction::Set argument: omitted returns None
    assert_eq!(
        matches_omitted.get_one::<String>("param"),
        None,
        "omitted ArgAction::Set argument returns None"
    );

    // Matching an ArgAction::Set argument: present returns Some
    let matches_param = cmd
        .clone()
        .try_get_matches_from(["builder-app", "--param", "hello"])
        .expect("builder matches param");
    assert_eq!(
        matches_param.get_one::<String>("param").map(String::as_str),
        Some("hello"),
        "get_one retrieves value for ArgAction::Set"
    );

    // Trap: Calling get_flag on an ArgAction::Set argument panics with definition mismatch
    let panic_res = std::panic::catch_unwind(AssertUnwindSafe(|| {
        matches_param.get_flag("param");
    }));
    assert!(
        panic_res.is_err(),
        "calling get_flag on ArgAction::Set argument must panic with mismatch"
    );
}

Исходный сидер

csx-seed