You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
2.2 KiB
66 lines
2.2 KiB
use crate::error::ShellError;
|
|
use once_cell::unsync::Lazy;
|
|
use regex::Regex;
|
|
use std::env;
|
|
|
|
const ENV_SET: Lazy<Regex> = Lazy::new(|| Regex::new(r#"^(?P<key>\w+)=(?P<value>\w*)$"#).unwrap());
|
|
const ENV_VARIABLE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(\\\$|\$(?P<env>\w+))").unwrap());
|
|
|
|
/// Returns `Ok(Some(...))` if a command should be triggered after calling this functions. If it
|
|
/// returns `Ok(None)`, do not execute a command.
|
|
pub fn preprocess(mut line: String) -> Result<Option<String>, ShellError> {
|
|
// check if the input line has `key=value` syntax. if so, set an env variable with `key` as key
|
|
// and `value` as value
|
|
if let Some(capture) = ENV_SET.captures(&line) {
|
|
let key = capture.name("key").unwrap().as_str();
|
|
let value = capture
|
|
.name("value")
|
|
.map_or("".to_string(), |v| v.as_str().to_string());
|
|
|
|
env::set_var(key, value);
|
|
return Ok(None);
|
|
}
|
|
|
|
// resolve env variables. if the input line contains `$key` and a env variable with the name
|
|
// `key` exists too, resolve `$key` to the variable value. if `key` env variable does not exist,
|
|
// simply resolve it with an empty string
|
|
for capture in ENV_VARIABLE.captures_iter(&line.clone()) {
|
|
let variable_name = capture.name("env").unwrap().as_str();
|
|
if variable_name.is_empty() {
|
|
continue;
|
|
}
|
|
let value = env::var(variable_name).unwrap_or_default();
|
|
|
|
line = ENV_VARIABLE.replacen(&line, 1, &value).to_string();
|
|
}
|
|
|
|
Ok(Some(line))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_preprocess_env_variable() {
|
|
assert_eq!(preprocess("key=value".to_string()), Ok(None));
|
|
assert_eq!(env::var("key").unwrap_or_default(), "value".to_string())
|
|
}
|
|
|
|
#[test]
|
|
fn test_preprocessing_resolve_env_variable() {
|
|
assert_eq!(preprocess("key=value".to_string()), Ok(None));
|
|
assert_eq!(
|
|
preprocess("$key".to_string()),
|
|
Ok(Some("value".to_string()))
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn test_preprocessing_resolve_non_existent_env_variable() {
|
|
assert_eq!(
|
|
preprocess("$nonexitent".to_string()),
|
|
Ok(Some("".to_string()))
|
|
)
|
|
}
|
|
}
|