I want to change the first ancestor of a &Path
, possibly by returning a new PathBuf
like so.
fn change_parent(path: &Path, new_parent: &Path) -> PathBuf;
Here's how I expect it to work.
let old_path = change_root(Path::new("/hello/world.html"), Path::new("/html"));
let new_path = PathBuf::from("/html/world.html");
assert_eq!(old_path, new_path)
I tried .ancestors()
but the Path::new("/hello/world.html").ancestors();
returns an iterator over ["/hello/world.html", "/hello", "/"]
which is kind of the opposite of what I want. What I want is ["/hello/world.html", "hello/world.html", "/world.html"]
so I can append a new path easily.
Should I switch to using split
on "(/|\)"
then replacing the first result instead?
This is using strip_prefix
provided by conradludgate on The Rust Programming Language Community (Discord):
use std::path::{Path, PathBuf, StripPrefixError};
fn replace_prefix(p: impl AsRef<Path>, from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<PathBuf, StripPrefixError> {
p.as_ref().strip_prefix(from).map(|p| to.as_ref().join(p))
}
(
replace_prefix("/public/file.html", "/public", "/.html_output"),
replace_prefix("/public/folder/nested/file.html", "/public", "/.html_output"),
replace_prefix("/folder/nested/file.html", "/public", "/.html_output"),
)
(Ok("/.html_output/file.html"), Ok("/.html_output/folder/nested/file.html"), Err(StripPrefixError(())))