Function shellexpand::env_with_context

source ·
pub fn env_with_context<SI, CO, C, E>(
    input: &SI,
    context: C
) -> Result<Cow<'_, str>, LookupError<E>>
where SI: AsRef<str> + ?Sized, CO: AsRef<str>, C: FnMut(&str) -> Result<Option<CO>, E>,
Expand description

Performs the environment expansion using the provided context.

This function walks through the input string input and attempts to construct a new string by replacing all shell-like variable sequences with the corresponding values obtained via the context function. The latter may return an error; in this case the error will be returned immediately, along with the name of the offending variable. Also the context function may return [Ok(None)], indicating that the given variable is not available; in this case the variable sequence is left as it is in the output string.

The syntax of variables resembles the one of bash-like shells: all of $VAR, ${VAR}, $NAME_WITH_UNDERSCORES are valid variable references, and the form with braces may be used to separate the reference from the surrounding alphanumeric text: before${VAR}after. Note, however, that for simplicity names like $123 or $1AB are also valid, as opposed to shells where $<number> has special meaning of positional arguments. Also note that “alphanumericity” of variable names is checked with std::primitive::char::is_alphanumeric(), therefore lots of characters which are considered alphanumeric by the Unicode standard are also valid names for variables. When unsure, use braces to separate variables from the surrounding text.

This function has four generic type parameters: SI represents the input string, CO is the output of context lookups, C is the context closure and E is the type of errors returned by the context function. SI and CO must be types, a references to which can be converted to a string slice. For example, it is fine for the context function to return &str’s, String’s or Cow<str>’s, which gives the user a lot of flexibility.

If the context function returns an error, it will be wrapped into LookupError and returned immediately. LookupError, besides the original error, also contains a string with the name of the variable whose expansion caused the error. LookupError implements Error, Clone and Eq traits for further convenience and interoperability.

If you need to expand system environment variables, you can use env() or full() functions. If your context does not have errors, you may use env_with_context_no_errors() instead of this function because it provides a simpler API.

§Examples

fn context(s: &str) -> Result<Option<&'static str>, &'static str> {
    match s {
        "A" => Ok(Some("a value")),
        "B" => Ok(Some("b value")),
        "E" => Err("something went wrong"),
        _ => Ok(None)
    }
}

// Regular variables are expanded
assert_eq!(
    shellexpand::env_with_context("begin/$A/${B}s/end", context).unwrap(),
    "begin/a value/b values/end"
);

// Expand to a default value if the variable is not defined
assert_eq!(
    shellexpand::env_with_context("begin/${UNSET_ENV:-42}/end", context).unwrap(),
    "begin/42/end"
);

// Unknown variables are left as is
assert_eq!(
    shellexpand::env_with_context("begin/$UNKNOWN/end", context).unwrap(),
    "begin/$UNKNOWN/end"
);

// Errors are propagated
assert_eq!(
    shellexpand::env_with_context("begin${E}end", context),
    Err(shellexpand::LookupError {
        var_name: "E".into(),
        cause: "something went wrong"
    })
);