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

蓝咒 提交于 2019-12-07 10:33:14

问题


In Python, a function called os.path.join() allows concatenating multiple strings into one path using the path separator of the operating system. In Rust, there is only a function join() that appends a string or a path to an existing path. This problem can't be solved with a normal function as a normal function needs to have a fixed number of arguments.

I'm looking for a macro that takes an arbitrary number of strings and paths and returns the joined path.


回答1:


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);
}



回答2:


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();



回答3:


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



来源:https://stackoverflow.com/questions/40567020/what-is-a-macro-for-concatenating-an-arbitrary-number-of-components-to-build-a-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!