use std::{ fmt::{self, Display}, str::FromStr, }; use exun::RawUnexpected; use parking_lot::RwLock; use serde::Deserialize; use thiserror::Error; use url::Url; static ENVIRONMENT: RwLock = RwLock::new(Environment::Local); #[derive(Debug, Clone, Deserialize)] pub struct Config { pub id: Box, pub url: Url, } pub fn get_config() -> Result { let env = get_environment(); let path = format!("static/config/{env}.toml"); let string = std::fs::read_to_string(path)?; let config = toml::from_str(&string)?; Ok(config) } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Environment { Local, Dev, Staging, Production, } impl Display for Environment { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Local => f.write_str("local"), Self::Dev => f.write_str("dev"), Self::Staging => f.write_str("staging"), Self::Production => f.write_str("prod"), } } } #[derive(Debug, Clone, Error)] #[error("Expected one of the following environments: local, dev, staging, prod. Found {string}")] pub struct ParseEnvironmentError { string: Box, } impl FromStr for Environment { type Err = ParseEnvironmentError; fn from_str(s: &str) -> Result { match s { "local" => Ok(Self::Local), "dev" => Ok(Self::Dev), "staging" => Ok(Self::Staging), "prod" => Ok(Self::Production), _ => Err(ParseEnvironmentError { string: s.into() }), } } } pub fn set_environment(env: Environment) { let mut env_ptr = ENVIRONMENT.write(); *env_ptr = env; } fn get_environment() -> Environment { ENVIRONMENT.read().clone() }