ansible-rs 1.1.0

A Rust wrapper library for Ansible command-line tools (Linux/Unix only)
Documentation
//! Low-level command configuration utilities.
//!
//! This module provides the [`CommandConfig`] struct for managing command-line
//! arguments and environment variables for Ansible command execution.

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fmt::Display;

/// Configuration for command execution including arguments and environment variables.
///
/// The `CommandConfig` struct provides a centralized way to manage command-line
/// arguments and environment variables that are passed to Ansible commands.
/// It's used internally by all the main Ansible wrapper structs.
///
/// # Examples
///
/// ## Basic Usage
///
/// ```rust
/// use ansible::command_config::CommandConfig;
///
/// let mut config = CommandConfig::default();
/// config
///     .arg("--verbose")
///     .arg("--check")
///     .add_env("ANSIBLE_HOST_KEY_CHECKING", "False");
///
/// assert_eq!(config.get_args().len(), 2);
/// assert!(config.get_envs().contains_key("ANSIBLE_HOST_KEY_CHECKING"));
/// ```
///
/// ## Environment Variable Management
///
/// ```rust
/// use ansible::command_config::CommandConfig;
///
/// let mut config = CommandConfig::default();
/// config
///     .set_system_envs()
///     .filter_envs(["HOME", "PATH", "USER"]);
///
/// // Only HOME, PATH, and USER environment variables are retained
/// assert!(config.get_envs().len() <= 3);
/// ```
#[derive(Default, Debug, Clone)]
pub struct CommandConfig {
    pub(crate) args: Vec<String>,
    pub(crate) envs: HashMap<String, String>,
}

impl CommandConfig {
    /// Set environment variables from the current system environment
    pub fn set_system_envs(&mut self) -> &mut Self {
        self.envs = std::env::vars().collect();
        self
    }

    /// Add a single environment variable
    pub fn add_env(&mut self, key: impl Into<String>, value: impl Into<String>) -> &mut Self {
        self.envs.insert(key.into(), value.into());
        self
    }

    /// Filter environment variables to only include specified keys
    pub fn filter_envs<T, S>(&mut self, iter: T) -> &mut Self
    where
        T: IntoIterator<Item = S>,
        S: AsRef<OsStr> + Display,
    {
        let filtered_envs: HashMap<String, String> = iter
            .into_iter()
            .filter_map(|env| {
                let key = env.to_string();
                self.envs.get(&key).map(|val| (key, val.clone()))
            })
            .collect();
        self.envs = filtered_envs;
        self
    }

    /// Add a single command argument
    pub fn arg<S: AsRef<OsStr> + Display>(&mut self, arg: S) -> &mut Self {
        self.args.push(arg.to_string());
        self
    }

    /// Add multiple command arguments
    pub fn args<T, S>(&mut self, args: T) -> &mut Self
    where
        T: IntoIterator<Item = S>,
        S: AsRef<OsStr> + Display,
    {
        self.args.extend(args.into_iter().map(|arg| arg.to_string()));
        self
    }

    /// Clear all arguments
    pub fn clear_args(&mut self) -> &mut Self {
        self.args.clear();
        self
    }

    /// Clear all environment variables
    pub fn clear_envs(&mut self) -> &mut Self {
        self.envs.clear();
        self
    }

    /// Get a reference to the arguments
    pub fn get_args(&self) -> &[String] {
        &self.args
    }

    /// Get a reference to the environment variables
    pub fn get_envs(&self) -> &HashMap<String, String> {
        &self.envs
    }
}