clap_fmt 0.1.1

Serialize a clap arg parser into the command-line arguments.
Documentation
use clap::Parser;
use clap_fmt::FmtArgs;
use serde::Serialize;

#[derive(Parser, Debug, Serialize)]
struct CliWithMultipleValues {
    #[arg(short = 'I', long = "include", action = clap::ArgAction::Append)]
    include_paths: Vec<String>,

    #[arg(short = 'D', long = "define", action = clap::ArgAction::Append)]
    defines: Vec<String>,

    #[arg(long, num_args = 1..)]
    features: Vec<String>,

    #[arg(long, value_delimiter = ',')]
    tags: Vec<String>,
}

#[test]
fn test_multiple_values_append() {
    let cli = CliWithMultipleValues {
        include_paths: vec!["/usr/include".to_string(), "/usr/local/include".to_string()],
        defines: vec!["DEBUG".to_string(), "FEATURE_X=1".to_string()],
        features: vec!["async".to_string(), "tls".to_string()],
        tags: vec!["important".to_string(), "urgent".to_string()],
    };

    let result = cli.to_args();
    assert_eq!(
        result,
        vec![
            "--include",
            "/usr/include",
            "--include",
            "/usr/local/include",
            "--define",
            "DEBUG",
            "--define",
            "FEATURE_X=1",
            "--features",
            "async",
            "--features",
            "tls",
            "--tags",
            "important",
            "--tags",
            "urgent"
        ]
    );
}

#[test]
fn test_multiple_occurrences() {
    #[derive(Parser, Debug, Serialize)]
    struct CliWithOccurrences {
        #[arg(short = 'c', long, action = clap::ArgAction::Append)]
        config: Vec<String>,

        #[arg(short = 'e', long, action = clap::ArgAction::Append)]
        exclude: Vec<String>,
    }

    let cli = CliWithOccurrences {
        config: vec!["config1.toml".to_string(), "config2.toml".to_string()],
        exclude: vec![
            "*.tmp".to_string(),
            "*.bak".to_string(),
            "*.swp".to_string(),
        ],
    };

    let result = cli.to_args();
    assert_eq!(
        result,
        vec![
            "--config",
            "config1.toml",
            "--config",
            "config2.toml",
            "--exclude",
            "*.tmp",
            "--exclude",
            "*.bak",
            "--exclude",
            "*.swp"
        ]
    );
}

#[test]
fn test_trailing_varargs() {
    #[derive(Parser, Debug, Serialize)]
    struct CliWithTrailing {
        #[arg(long)]
        flag: bool,

        #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
        args: Vec<String>,
    }

    let cli = CliWithTrailing {
        flag: true,
        args: vec![
            "--not-a-flag".to_string(),
            "-x".to_string(),
            "file.txt".to_string(),
        ],
    };

    let result = cli.to_args();
    assert_eq!(result, vec!["--flag", "--not-a-flag", "-x", "file.txt"]);
}