infraqueue-lib 0.1.0

Core library for INFRAQUEUE
Documentation
use std::env;
use std::fs;
use std::path::Path;

/// Read an environment variable as u64 with a default fallback.
/// Returns `default` if the var is missing or cannot be parsed.
pub fn env_u64(name: &str, default: u64) -> u64 {
    env::var(name)
        .ok()
        .and_then(|v| v.parse::<u64>().ok())
        .unwrap_or(default)
}

/// Read an environment variable as u32 with a default fallback.
/// Returns `default` if the var is missing or cannot be parsed.
pub fn env_u32(name: &str, default: u32) -> u32 {
    env::var(name)
        .ok()
        .and_then(|v| v.parse::<u32>().ok())
        .unwrap_or(default)
}

/// Read an environment variable as f64 with a default fallback.
/// Returns `default` if the var is missing or cannot be parsed.
pub fn env_f64(name: &str, default: f64) -> f64 {
    env::var(name)
        .ok()
        .and_then(|v| v.parse::<f64>().ok())
        .unwrap_or(default)
}

/// Read a configuration value from either a direct environment variable `NAME`
/// or from a file path specified via `NAME_FILE`. If both are set, `NAME` takes precedence.
/// Returns `Some(value)` if found, otherwise `None`.
pub fn env_var_or_file(name: &str) -> Option<String> {
    if let Ok(v) = env::var(name) {
        if !v.is_empty() {
            return Some(v);
        }
    }
    let file_key = format!("{}_FILE", name);
    if let Ok(path) = env::var(&file_key) {
        if !path.is_empty() {
            let p = Path::new(&path);
            if let Ok(bytes) = fs::read(p) {
                let mut s = String::from_utf8_lossy(&bytes).to_string();
                // Trim common trailing newlines
                while s.ends_with('\n') || s.ends_with('\r') {
                    s.pop();
                }
                if !s.is_empty() {
                    return Some(s);
                }
            }
        }
    }
    None
}

/// Same as `env_var_or_file`, but returns an error message when not found.
pub fn env_var_or_file_required(name: &str) -> Result<String, String> {
    env_var_or_file(name)
        .ok_or_else(|| format!("{} is required (set {} or {}_FILE)", name, name, name))
}