robotrt-cli 0.1.0-beta.1

RobotRT modular robotics runtime and middleware components.
use super::*;

pub(super) fn parse_cli_options(args: &[String]) -> Result<CliOrchestrateOptions, String> {
    let max_parallel_override = match option_value(args, "--max-parallel") {
        Some(raw) => {
            let value = raw
                .parse::<usize>()
                .map_err(|err| format!("invalid value for --max-parallel: {raw} ({err})"))?;
            Some(value)
        }
        None => None,
    };

    Ok(CliOrchestrateOptions {
        config_path: option_value(args, "--file")
            .map(PathBuf::from)
            .unwrap_or_else(|| PathBuf::from(DEFAULT_ORCHESTRATION_CONFIG_PATH)),
        profile: option_value(args, "--profile"),
        overlay_files: parse_overlay_files(args),
        json: has_flag(args, "--json"),
        target_task: option_value(args, "--task"),
        group: option_value(args, "--group"),
        dry_run: has_flag(args, "--dry-run"),
        continue_on_error: has_flag(args, "--continue-on-error"),
        max_parallel_override,
        state_file: option_value(args, "--state-file")
            .map(PathBuf::from)
            .unwrap_or_else(|| PathBuf::from(DEFAULT_RUNTIME_STATE_FILE)),
        prune: has_flag(args, "--prune"),
    })
}

fn parse_overlay_files(args: &[String]) -> Vec<PathBuf> {
    let mut overlays = Vec::new();
    let mut idx = 0usize;
    while idx + 1 < args.len() {
        if args[idx] == "--overlay" {
            for part in args[idx + 1].split(',') {
                let trimmed = part.trim();
                if !trimmed.is_empty() {
                    overlays.push(PathBuf::from(trimmed));
                }
            }
            idx += 2;
            continue;
        }
        idx += 1;
    }
    overlays
}