What is a macro for concatenating an arbitrary number of components to build a path in Rust?

There's a reasonably simple example in the documentation for PathBuf:

use std::path::PathBuf;
let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();

Once you read past the macro syntax, it's not too bad. Basically, we take require at least two arguments, and the first one needs to be convertible to a PathBuf via Into. Each subsequent argument is pushed on the end, which accepts anything that can be turned into a reference to a Path.

macro_rules! build_from_paths {
    ($base:expr, $($segment:expr),+) => {{
        let mut base: ::std::path::PathBuf = $base.into();
        $(
            base.push($segment);
        )*
        base
    }}
}

fn main() {
    use std::{
        ffi::OsStr,
        path::{Path, PathBuf},
    };

    let a = build_from_paths!("a", "b", "c");
    println!("{:?}", a);

    let b = build_from_paths!(PathBuf::from("z"), OsStr::new("x"), Path::new("y"));
    println!("{:?}", b);
}

A normal function which takes an iterable (e.g. a slice) can solve the problem in many contexts:

use std::path::{Path, PathBuf};

fn join_all<P, Ps>(parts: Ps) -> PathBuf
where
    Ps: IntoIterator<Item = P>,
    P: AsRef<Path>,
{
    parts.into_iter().fold(PathBuf::new(), |mut acc, p| {
        acc.push(p);
        acc
    })
}

fn main() {
    let parts = vec!["/usr", "bin", "man"];
    println!("{:?}", join_all(&parts));
    println!("{:?}", join_all(&["/etc", "passwd"]));
}

Playground