sinan 0.1.0

A Boilerplate for Rapid Axum Web Service Deployment.
Documentation
use std::env;
use std::str::FromStr;

use dotenvy::dotenv;
use eyre::Context;
use serde::{Deserialize, Serialize};

use crate::contracts::Facade;
use crate::facades::Container;

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub enum Environment {
    #[serde(rename = "production")]
    Production,
    #[serde(rename = "development")]
    Development,
    #[serde(rename = "test")]
    Test,
    Any(String),
}

impl Facade for Environment {
    fn new(container: &Container) -> Self {
        dotenv().ok();

        env::var("APP_ENV")
            .unwrap_or("development".to_owned())
            .into()
    }
}

impl Environment {
    pub fn get(&self, key: &str) -> eyre::Result<String> {
        let val = env::var(key).wrap_err_with(|| format!("Failed to load {}", key))?;

        Ok(val)
    }
}

impl From<String> for Environment {
    fn from(value: String) -> Self {
        Self::from_str(&value).unwrap_or(Self::Any(value))
    }
}

impl FromStr for Environment {
    type Err = &'static str;

    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        match s {
            "production" => Ok(Self::Production),
            "development" => Ok(Self::Development),
            "test" => Ok(Self::Test),
            s => Ok(Self::Any(s.to_string())),
        }
    }
}

impl std::fmt::Display for Environment {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Any(s) => s.fmt(f),
            _ => serde_variant::to_variant_name(self)
                .expect("only enum supported")
                .fmt(f),
        }
    }
}