use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DeploymentGrade {
Dev,
Poc,
Preview,
#[default]
Prod,
}
impl DeploymentGrade {
pub fn is_dev(&self) -> bool {
matches!(self, DeploymentGrade::Dev)
}
pub fn experimental_features_enabled(&self) -> bool {
matches!(self, DeploymentGrade::Dev)
}
pub fn from_env() -> Self {
if let Ok(grade) = std::env::var("DEPLOYMENT_GRADE") {
return grade.parse().unwrap_or_default();
}
let dev_mode = std::env::var("DEV_MODE")
.map(|v| v == "true" || v == "1")
.unwrap_or(false);
if dev_mode {
DeploymentGrade::Dev
} else {
DeploymentGrade::Prod
}
}
}
impl fmt::Display for DeploymentGrade {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DeploymentGrade::Dev => write!(f, "dev"),
DeploymentGrade::Poc => write!(f, "poc"),
DeploymentGrade::Preview => write!(f, "preview"),
DeploymentGrade::Prod => write!(f, "prod"),
}
}
}
impl FromStr for DeploymentGrade {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"dev" | "development" => Ok(DeploymentGrade::Dev),
"poc" => Ok(DeploymentGrade::Poc),
"preview" | "staging" => Ok(DeploymentGrade::Preview),
"prod" | "production" => Ok(DeploymentGrade::Prod),
_ => Err(format!(
"Unknown deployment grade: '{}'. Valid values: dev, poc, preview, prod",
s
)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_grades() {
assert_eq!(
"dev".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Dev
);
assert_eq!(
"development".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Dev
);
assert_eq!(
"poc".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Poc
);
assert_eq!(
"preview".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Preview
);
assert_eq!(
"staging".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Preview
);
assert_eq!(
"prod".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Prod
);
assert_eq!(
"production".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Prod
);
}
#[test]
fn test_case_insensitive() {
assert_eq!(
"DEV".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Dev
);
assert_eq!(
"PROD".parse::<DeploymentGrade>().unwrap(),
DeploymentGrade::Prod
);
}
#[test]
fn test_default() {
assert_eq!(DeploymentGrade::default(), DeploymentGrade::Prod);
}
#[test]
fn test_experimental_features() {
assert!(DeploymentGrade::Dev.experimental_features_enabled());
assert!(!DeploymentGrade::Poc.experimental_features_enabled());
assert!(!DeploymentGrade::Preview.experimental_features_enabled());
assert!(!DeploymentGrade::Prod.experimental_features_enabled());
}
#[test]
fn test_display() {
assert_eq!(DeploymentGrade::Dev.to_string(), "dev");
assert_eq!(DeploymentGrade::Poc.to_string(), "poc");
assert_eq!(DeploymentGrade::Preview.to_string(), "preview");
assert_eq!(DeploymentGrade::Prod.to_string(), "prod");
}
}