I am using shellexpand simply because I want the tilde (~) handled as well.
I tested my code with three paths:
~/some.db
/Users/dimi/some.db
../../some.db (the project is two levels below my homedir)
And it works and I can accept your feedback on functionality as the final stance -- but the code just looks so very ugly. I am still learning the borrow checker and it seemed to me I am fighting with it and not working with it. Am I wrong? Is the code okay then? Is there a way to do it with less chaining?
change that Path::new(&x.into_owned()) to Path::new(x.as_ref()) to avoid a potential allocation
change what now is Path::new(x.as_ref()).canonicalize() to std::fs::canonicalize(x.as_ref()) to avoid importing Path and shortening the code a bit more
use the ? operator to avoid calling and_then over and over
fn abspath(p: &str) -> Option<String> {
let exp_path = shellexpand::full(p).ok()?;
let can_path = std::fs::canonicalize(exp_path.as_ref()).ok()?;
can_path.into_os_string().into_string().ok()
}
I feel like this could be better if:
there was an implementation of AsRef<Path> for Cow<'_ str> to avoid that .as_ref()
there was a way to directly convert a PathBuf to a String, without passing through an OsString