Is there an elegant way to append a suffix such as .bak to a Path and get a new PathBuf? Something like:
let p = Path::new("foo.c");
let p_bak = /* ? */;
assert_eq!(p_bak, Path::new("foo.c.bak"));
With a string, one could use format!("{}.bak", p). With a path, I see no obvious equivalent. with_extension() doesn't quite do it, as p.with_extension("bak") will create foo.bak rather than the desired foo.c.bak.
The most "obvious" solution is to define an append_to_path() and use append_to_path(p, ".bak"):
fn append_to_path(p: &Path, s: &str) -> PathBuf {
let mut p_osstr = p.as_os_str().to_owned();
p_osstr.push(s);
p_osstr.into()
}
Is there a shorter way of expressing that in one expression?
The tap crate allows streamlining the side effects into an expression, but it still feels rather cryptic:
// prior to Rust 1.70:
let p_bak: PathBuf = p.as_os_str().to_owned().tap_mut(|s| s.push(".bak")).into();
// since Rust 1.70:
let p_bak = p.to_owned().tap_mut(|s| s.as_mut_os_string().push(".bak"));
PathBuf::add_extension()which is useful for this.