use confroid::{ConfroidError, from_pairs};
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Mode {
Standalone,
Cluster,
}
impl FromStr for Mode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() {
"standalone" => Ok(Mode::Standalone),
"cluster" => Ok(Mode::Cluster),
other => Err(format!("unknown mode `{other}`")),
}
}
}
impl fmt::Display for Mode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Mode::Standalone => "standalone",
Mode::Cluster => "cluster",
})
}
}
confroid::from_str_scalar!(Mode);
#[derive(confroid::Config, Debug)]
struct Config {
mode: Mode,
#[confroid(default = Mode::Standalone)]
fallback: Mode,
maybe: Option<Mode>,
tags: Vec<Mode>,
}
#[test]
fn reads_enum_fields() {
let config: Config = from_pairs([
("MODE", "cluster"),
("FALLBACK", "cluster"),
("MAYBE", "standalone"),
("TAGS__0", "standalone"),
("TAGS__1", "cluster"),
])
.unwrap();
assert_eq!(config.mode, Mode::Cluster);
assert_eq!(config.fallback, Mode::Cluster);
assert_eq!(config.maybe, Some(Mode::Standalone));
assert_eq!(config.tags, vec![Mode::Standalone, Mode::Cluster]);
}
#[test]
fn case_insensitive_via_from_str() {
let config: Config = from_pairs([("MODE", "CLUSTER"), ("TAGS__0", "Standalone")]).unwrap();
assert_eq!(config.mode, Mode::Cluster);
assert_eq!(config.tags, vec![Mode::Standalone]);
}
#[test]
fn default_applies_when_unset() {
let config: Config = from_pairs([("MODE", "standalone"), ("TAGS__0", "cluster")]).unwrap();
assert_eq!(config.fallback, Mode::Standalone);
assert_eq!(config.maybe, None);
}
#[test]
fn invalid_enum_value_errors() {
let err =
from_pairs::<Config, _, _, _>([("MODE", "bogus"), ("TAGS__0", "cluster")]).unwrap_err();
match err {
ConfroidError::EnvVarInvalid { field, value, .. } => {
assert_eq!(field, "mode");
assert_eq!(value, "bogus");
}
other => panic!("expected EnvVarInvalid, got {other:?}"),
}
}
#[test]
fn missing_required_enum_errors() {
let err = from_pairs::<Config, _, _, _>([("TAGS__0", "cluster")]).unwrap_err();
assert_eq!(
err,
ConfroidError::EnvVarNotFound {
var_name: "MODE".to_string(),
field: "mode".to_string(),
}
);
}