mecha10-core 0.9.0

Mecha10 core runtime and foundational types
Documentation
//! Environment Variable Secret Backend

use super::SecretBackend;
use crate::{Mecha10Error, Result};

pub struct EnvironmentBackend {
    prefix: String,
}

impl EnvironmentBackend {
    /// Create a new environment backend with a prefix
    ///
    /// The prefix will be prepended to all secret keys when reading from
    /// environment variables. Keys are automatically uppercased.
    pub fn new(prefix: &str) -> Self {
        Self {
            prefix: prefix.to_string(),
        }
    }

    /// Create backend with default prefix "MECHA10_SECRET"
    #[allow(clippy::should_implement_trait)]
    pub fn default() -> Self {
        Self::new("MECHA10_SECRET")
    }

    fn make_env_key(&self, key: &str) -> String {
        format!("{}_{}", self.prefix, key.to_uppercase())
    }
}

#[async_trait::async_trait]
impl SecretBackend for EnvironmentBackend {
    async fn get(&self, key: &str) -> Result<String> {
        let env_key = self.make_env_key(key);
        std::env::var(&env_key).map_err(|_| {
            Mecha10Error::Configuration(format!(
                "Secret '{}' not found in environment variable '{}'",
                key, env_key
            ))
        })
    }

    async fn list(&self) -> Result<Vec<String>> {
        let prefix_with_underscore = format!("{}_", self.prefix);
        let keys: Vec<String> = std::env::vars()
            .filter_map(|(k, _)| k.strip_prefix(&prefix_with_underscore).map(|s| s.to_lowercase()))
            .collect();
        Ok(keys)
    }
}