Reputation: 7202
Documentation provides following example for joining paths:
use std::path::PathBuf;
let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
This works when all the components are strings. However, I am trying to write following function:
use std::path::PathBuf;
fn my_path<P: AsRef<Path>>(root: P, dir1: &str, dir2: &str, dir3: &str) -> PathBuf {
[root, dir1, dir2, dir3].iter().collect()
}
The above obviously doesn't work. I know I can do series of nested joins, but that is, ..., more ugly.
Is there a way to join different path-like components in array?
Upvotes: 3
Views: 1046
Reputation: 71430
You can convert them to Path
s:
fn my_path<P: AsRef<Path>>(root: P, dir1: &str, dir2: &str, dir3: &str) -> PathBuf {
[
root.as_ref(),
Path::new(dir1),
Path::new(dir2),
Path::new(dir3),
]
.iter()
.collect()
}
Or, if the list is long (but this may be less efficient):
fn my_path<P: AsRef<Path>>(root: P, dir1: &str, dir2: &str, dir3: &str) -> PathBuf {
std::iter::once(root.as_ref())
.chain([dir1, dir2, dir3].iter().map(Path::new))
.collect()
}
Upvotes: 0
Reputation: 27549
You can cast them to dynamic AsRef<Path>
objects:
use std::path::{Path, PathBuf};
fn my_path<P: AsRef<Path>>(root: P, dir1: &str, dir2: &str, dir3: &str) -> PathBuf {
[&root as &dyn AsRef<Path>, &dir1, &dir2, &dir3].iter().collect()
}
or just add the first different object with join:
use std::path::{Path, PathBuf};
fn my_path<P: AsRef<Path>>(root: P, dir1: &str, dir2: &str, dir3: &str) -> PathBuf {
root.as_ref().join([dir1, dir2, dir3].iter().collect::<PathBuf>())
}
Here it is on Rust Playground
Upvotes: 5