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