envx-secure 0.1.0

A CLI for .env file management: diff, audit, and encrypt
use anyhow::{bail, Context, Result};
use indexmap::IndexMap;
use std::path::Path;

pub fn parse(path: &Path) -> Result<IndexMap<String, String>> {
    let content = std::fs::read_to_string(path)
        .with_context(|| format!("failed to read {}", path.display()))?;

    let mut map = IndexMap::new();

    for (lineno, line) in content.lines().enumerate() {
        let line = line.trim();

        if line.is_empty() || line.starts_with('#') {
            continue;
        }

        let eq = line.find('=').with_context(|| {
            format!(
                "{}:{}: malformed line (expected KEY=VALUE): {:?}",
                path.display(),
                lineno + 1,
                line
            )
        })?;

        let key = line[..eq].trim().to_string();
        let raw_val = line[eq + 1..].trim();

        if key.is_empty() {
            bail!(
                "{}:{}: empty key in line: {:?}",
                path.display(),
                lineno + 1,
                line
            );
        }

        let value = strip_quotes(raw_val);
        map.insert(key, value.to_string());
    }

    Ok(map)
}

fn strip_quotes(s: &str) -> &str {
    if (s.starts_with('"') && s.ends_with('"')) || (s.starts_with('\'') && s.ends_with('\'')) {
        &s[1..s.len() - 1]
    } else {
        s
    }
}