efes/
lib.rs

1/// A macro that creates files and directories based on the given input.
2/// # Example
3/// ```
4/// # use tempfile::tempdir;
5/// # use efes::gen_fs;
6/// # use std::path::PathBuf;
7/// # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
8/// let root_dir = PathBuf::from("/home/user");
9/// # let root_dir = tempdir()?.into_path();
10/// gen_fs!(root_dir => (a: file1 file2) b c (another_directory: foo bar));
11/// # Ok(())
12/// # }
13/// ```
14/// would create a directory structure in `root_dir` equivalent to the following:
15/// ```shell
16/// .
17/// ├── a
18/// │   ├── file1
19/// │   └── file2
20/// ├── another_directory
21/// │   ├── bar
22/// │   └── foo
23/// ├── b
24/// └── c
25/// ```
26#[macro_export]
27macro_rules! gen_fs {
28        ($root:ident => $f:ident $($tail:tt)*) => {
29            ::std::fs::File::create($root.join(stringify!($f))).unwrap();
30            ::efes::gen_fs!($root => $($tail)*);
31        };
32        ($root:ident => ($dir:ident : $($inner:tt)*)$($tail:tt)*) => {
33            ::std::fs::create_dir($root.join(stringify!($dir))).unwrap();
34            let $dir = $root.join(stringify!($dir));
35            ::efes::gen_fs!($dir => $($inner)*);
36            ::efes::gen_fs!($root => $($tail)*);
37        };
38        ($root:ident => ) => {};
39}
40
41/// A macro that creates a vector of [`PathBufs`](std::path::PathBuf) containing paths to all files specified in the input.
42/// # Example
43/// ```
44/// # use tempfile::tempdir;
45/// # use efes::gen_paths;
46/// # use std::path::PathBuf;
47/// # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
48/// let root_dir = PathBuf::from("/home/user");
49/// # let root_dir = tempdir()?.into_path();
50/// let expected = gen_paths!(root_dir => (a: file1 file2) b c (another_directory: foo bar));
51/// assert_eq!(expected, vec![
52///     root_dir.join("a").join("file1"),
53///     root_dir.join("a").join("file2"),
54///     root_dir.join("b"),
55///     root_dir.join("c"),
56///     root_dir.join("another_directory").join("foo"),
57///     root_dir.join("another_directory").join("bar"),
58/// ]);
59/// # Ok(())
60/// # }
61#[macro_export]
62macro_rules! gen_paths {
63        ($root:ident => $f:ident $($tail:tt)*) => {
64            {
65                #[allow(clippy::vec_init_then_push)]
66                {
67                    let mut z_macro = Vec::new();
68                    ::efes::__gen_paths_private!(@$root | z_macro => $f $($tail)*);
69                    z_macro
70                }
71            }
72        };
73        ($root:ident => ($dir:ident : $($inner:tt)*)$($tail:tt)*) => {
74            {
75                #[allow(clippy::vec_init_then_push)]
76                {
77                    let mut z_macro = Vec::new();
78                    ::efes::__gen_paths_private!(@$root | z_macro => ($dir : $($inner)*) $($tail)*);
79                    z_macro
80                }
81            }
82        };
83}
84
85#[macro_export]
86#[doc(hidden)]
87macro_rules! __gen_paths_private {
88        (@$root:ident | $vec:ident => ) => {};
89        (@$root:ident | $vec:ident => $f:ident $($tail:tt)*) => {
90            $vec.push($root.join(stringify!($f)));
91            ::efes::__gen_paths_private!(@$root | $vec => $($tail)*);
92        };
93        (@$root:ident | $vec:ident => ($dir:ident : $($inner:tt)*)$($tail:tt)*) => {
94            let $dir = $root.join(stringify!($dir));
95            ::efes::__gen_paths_private!(@$dir | $vec => $($inner)*);
96            ::efes::__gen_paths_private!(@$root | $vec => $($tail)*);
97        };
98}