trybuild_internals_api/
path.rs

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