pub(crate) fn usize_knob(var: &str, default: usize, min: usize) -> usize {
parse_usize_knob(var, std::env::var(var).ok(), default, min)
}
pub(crate) fn usize_override(var: &str, min: usize) -> Option<usize> {
parse_usize_override(var, std::env::var(var).ok(), min)
}
pub(crate) fn parse_usize_knob(
var: &str,
raw: Option<String>,
default: usize,
min: usize,
) -> usize {
parse_usize_override(var, raw, min).unwrap_or(default)
}
pub(crate) fn parse_usize_override(var: &str, raw: Option<String>, min: usize) -> Option<usize> {
let raw = raw?;
match raw.trim().parse::<usize>() {
Ok(n) if n >= min => Some(n),
Ok(n) => {
eprintln!("warning: {var}={n} is below the minimum of {min}; ignoring it.");
None
}
Err(_) => {
eprintln!("warning: {var}={raw:?} is not a count; ignoring it.");
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_count_knob_falls_back_on_anything_it_cannot_use() {
let parse = |raw: &str| parse_usize_knob("PRISM_TEST", Some(raw.into()), 7, 1);
assert_eq!(parse("4"), 4);
assert_eq!(parse(" 4 "), 4);
assert_eq!(parse("abc"), 7, "unparseable falls back");
assert_eq!(parse("-1"), 7, "negative falls back");
assert_eq!(parse("0"), 7, "below the minimum falls back");
assert_eq!(parse(""), 7, "empty falls back");
assert_eq!(parse_usize_knob("PRISM_TEST", None, 7, 1), 7);
}
#[test]
fn a_count_override_is_absent_when_it_cannot_be_used() {
let parse = |raw: &str| parse_usize_override("PRISM_TEST", Some(raw.into()), 0);
assert_eq!(parse("20"), Some(20));
assert_eq!(parse("0"), Some(0), "the minimum itself is accepted");
assert_eq!(parse("abc"), None, "unparseable is absent, not zero");
assert_eq!(parse("2e1"), None);
assert_eq!(parse_usize_override("PRISM_TEST", None, 0), None);
}
}