ipcez 0.1.0

Rust library for ipcez.
Documentation
//! Target (local vs remote) detection from the `target` environment variable.
//!
//! Single responsibility: detect whether the process to communicate with is local or remote.

use std::env;
use std::error::Error;
use std::fmt;

/// Whether the process to communicate with is local or on a remote server.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TargetKind {
    Local,
    Remote,
}

/// Error when detecting target from the `target` environment variable.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TargetDetectionError {
    /// The `target` environment variable was not set.
    NotFound,
    /// The `target` environment variable had an invalid value.
    InvalidValue(String),
}

impl fmt::Display for TargetDetectionError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TargetDetectionError::NotFound => {
                write!(f, "environment variable \"target\" was not found")
            }
            TargetDetectionError::InvalidValue(v) => {
                write!(
                    f,
                    "environment variable \"target\" had invalid value \"{}\"; expected \"local\" or \"remote\"",
                    v
                )
            }
        }
    }
}

impl Error for TargetDetectionError {}

/// Detects whether the target process is local or remote by reading the `target` environment variable.
///
/// Expects the variable to be set to `"local"` or `"remote"` (case-insensitive).
/// Returns an error if the variable is missing or has any other value.
pub fn detect_target_from_env() -> Result<TargetKind, TargetDetectionError> {
    let raw = env::var("target").map_err(|_| TargetDetectionError::NotFound)?;
    let value = raw.trim().to_lowercase();
    match value.as_str() {
        "local" => Ok(TargetKind::Local),
        "remote" => Ok(TargetKind::Remote),
        _ => Err(TargetDetectionError::InvalidValue(raw)),
    }
}