| 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 | |