cmdkit-macros 0.2.1

Procedural macros for cmdkit command strategy generation.
Documentation
use std::{
    env,
    path::PathBuf,
    time::{SystemTime, UNIX_EPOCH},
};

use cmdkit::{CliCore, Command, StrategyError};
use cmdkit_macros::strategy;

#[strategy]
fn simple_cli_strategy(
    _options: Vec<cmdkit::Switch>,
    _arguments: Vec<cmdkit::Argument>,
    _subcommands: Vec<String>,
) -> Result<(), StrategyError> {
    Ok(())
}

#[test]
fn cli_attribute_generates_execute_shaped_strategy_wrapper() {
    let core = CliCore::new();
    core.register(Command::new(
        "simple",
        "simple cli strategy",
        SimpleCliStrategy::new(),
    ));

    let args = vec![
        "app".to_string(),
        "simple".to_string(),
        "--extra".to_string(),
    ];
    assert!(core.try_run_from_args(&args).is_ok());
}

#[test]
fn strategy_attribute_generated_type_uses_upper_camel_name() {
    let _instance = SimpleCliStrategy::new();
}

#[strategy]
fn create_directory(
    _options: Vec<cmdkit::Switch>,
    arguments: Vec<cmdkit::Argument>,
    _subcommands: Vec<String>,
) -> Result<(), StrategyError> {
    let path = arguments
        .iter()
        .find(|argument| argument.name == "path")
        .and_then(|argument| argument.value.as_deref())
        .ok_or_else(|| StrategyError::invalid_arguments("missing path"))?;

    std::fs::create_dir(std::path::Path::new(path))
        .map_err(|e| StrategyError::execution(format!("Failed to create directory: {e}")))
}

#[test]
fn test_command_suit() {
    let unique = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("system time should be after unix epoch")
        .as_nanos();
    let dir_path: PathBuf = env::temp_dir().join(format!("cli-core-create-{unique}"));

    let core = CliCore::new();
    core.register(Command::new(
        "create",
        "Create a directory",
        CreateDirectory::new(),
    ));

    let args = vec![
        "app".to_string(),
        "create".to_string(),
        "--path".to_string(),
        dir_path.to_string_lossy().into_owned(),
    ];

    assert!(core.try_run_from_args(&args).is_ok());
    assert!(dir_path.exists());
    std::fs::remove_dir(&dir_path).expect("Failed to clean up test directory");
}