pub fn expand(value: &str) -> String {
let mut output = String::with_capacity(value.len());
let mut rest = value;
while let Some(start) = rest.find("${") {
output.push_str(&rest[..start]);
let tail = &rest[start + 2..];
let Some(end) = tail.find('}') else {
output.push_str(&rest[start..]);
return output;
};
output.push_str(&std::env::var(&tail[..end]).unwrap_or_default());
rest = &tail[end + 1..];
}
output.push_str(rest);
output
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn expands_defined_variables_and_keeps_the_rest() {
unsafe { std::env::set_var("PRUX_UTILS_ENV_TEST_VALUE", "value") };
assert_eq!(expand("a-${PRUX_UTILS_ENV_TEST_VALUE}-b"), "a-value-b");
assert_eq!(
expand("${PRUX_UTILS_ENV_TEST_VALUE}${PRUX_UTILS_ENV_TEST_VALUE}"),
"valuevalue"
);
assert_eq!(expand("x${PRUX_UTILS_ENV_TEST_MISSING}y"), "xy");
assert_eq!(expand("tail ${unclosed"), "tail ${unclosed");
assert_eq!(expand("no variables here"), "no variables here");
assert_eq!(expand(""), "");
}
}