Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 277
konstin Avatar asked Nov 12 '16 19:11

konstin


People also ask

How do you concatenate paths in Python?

join() method in Python join one or more path components intelligently. This method concatenates various path components with exactly one directory separator ('/') following each non-empty part except the last path component.

What is concatenating a string?

Concatenation is the process of appending one string to the end of another string. You concatenate strings by using the + operator. For string literals and string constants, concatenation occurs at compile time; no run-time concatenation occurs.

What is concatenating two strings?

The concatenation of strings is a process of combining two strings to form a single string.


2 Answers

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();
like image 158
CodeMonkey Avatar answered Nov 16 '22 03:11

CodeMonkey


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

like image 28
Chris Emerson Avatar answered Nov 16 '22 03:11

Chris Emerson