macrotest/
path.rs

1// credits: dtolnay
2
3macro_rules! path {
4    ($($tt:tt)+) => {
5        tokenize_path!([] [] $($tt)+)
6    };
7}
8
9// Private implementation detail.
10macro_rules! tokenize_path {
11    ([$(($($component:tt)+))*] [$($cur:tt)+] / $($rest:tt)+) => {
12        tokenize_path!([$(($($component)+))* ($($cur)+)] [] $($rest)+)
13    };
14
15    ([$(($($component:tt)+))*] [$($cur:tt)*] $first:tt $($rest:tt)*) => {
16        tokenize_path!([$(($($component)+))*] [$($cur)* $first] $($rest)*)
17    };
18
19    ([$(($($component:tt)+))*] [$($cur:tt)+]) => {
20        tokenize_path!([$(($($component)+))* ($($cur)+)])
21    };
22
23    ([$(($($component:tt)+))*]) => {{
24        let mut path = std::path::PathBuf::new();
25        $(
26            path.push(&($($component)+));
27        )*
28        path
29    }};
30}
31
32#[test]
33fn test_path_macro() {
34    use std::path::{Path, PathBuf};
35
36    struct Project {
37        dir: PathBuf,
38    }
39
40    let project = Project {
41        dir: PathBuf::from("../target/tests"),
42    };
43
44    let cargo_dir = path!(project.dir / ".cargo" / "config.toml");
45    assert_eq!(cargo_dir, Path::new("../target/tests/.cargo/config.toml"));
46}