1macro_rules! path {
4 ($($tt:tt)+) => {
5 tokenize_path!([] [] $($tt)+)
6 };
7}
8
9macro_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}