Function shellexpand::full_with_context
source · [−]pub fn full_with_context<SI: ?Sized, CO, C, E, P, HD>(
input: &SI,
home_dir: HD,
context: C
) -> Result<Cow<'_, str>, LookupError<E>> where
SI: AsRef<str>,
CO: AsRef<str>,
C: FnMut(&str) -> Result<Option<CO>, E>,
P: AsRef<Path>,
HD: FnOnce() -> Option<P>,
Expand description
Performs both tilde and environment expansion using the provided contexts.
home_dir
and context
are contexts for tilde expansion and environment expansion,
respectively. See env_with_context()
and tilde_with_context()
for more details on
them.
Unfortunately, expanding both ~
and $VAR
s at the same time is not that simple. First,
this function has to track ownership of the data. Since all functions in this crate
return Cow<str>
, this function takes some precautions in order not to allocate more than
necessary. In particular, if the input string contains neither tilde nor $
-vars, this
function will perform no allocations.
Second, if the input string starts with a variable, and the value of this variable starts with tilde, the naive approach may result into expansion of this tilde. This function avoids this.
Examples
use std::path::{PathBuf, Path};
use std::borrow::Cow;
fn home_dir() -> Option<PathBuf> { Some(Path::new("/home/user").into()) }
fn get_env(name: &str) -> Result<Option<&'static str>, &'static str> {
match name {
"A" => Ok(Some("a value")),
"B" => Ok(Some("b value")),
"T" => Ok(Some("~")),
"E" => Err("some error"),
_ => Ok(None)
}
}
// Performs both tilde and environment expansions
assert_eq!(
shellexpand::full_with_context("~/$A/$B", home_dir, get_env).unwrap(),
"/home/user/a value/b value"
);
// Errors from environment expansion are propagated to the result
assert_eq!(
shellexpand::full_with_context("~/$E/something", home_dir, get_env),
Err(shellexpand::LookupError {
var_name: "E".into(),
cause: "some error"
})
);
// Input without starting tilde and without variables does not cause allocations
let s = shellexpand::full_with_context("some/path", home_dir, get_env);
match s {
Ok(Cow::Borrowed(s)) => assert_eq!(s, "some/path"),
_ => unreachable!("the above variant is always valid")
}
// Input with a tilde inside a variable in the beginning of the string does not cause tilde
// expansion
assert_eq!(
shellexpand::full_with_context("$T/$A/$B", home_dir, get_env).unwrap(),
"~/a value/b value"
);