build_fs_tree/macros.rs
1#![no_implicit_prelude]
2
3/// Create representation of a [directory](crate::FileSystemTree::Directory).
4///
5/// **NOTES:**
6/// * **Syntax:** The syntax used by this macro is similar to the syntax used by
7/// [maplit](https://docs.rs/maplit/1.0.2/maplit/) except that in this macro, commas are
8/// optional.
9/// * **Typings:** The types of `Path` and `FileContent` generic parameter isn't required to be
10/// the types provided by the expressions that users wrote as long as they implement
11/// [`From<X>`](::std::convert::From) where `X` is the types of the aforementioned user
12/// provided expressions.
13///
14/// # Syntax
15///
16/// The syntax used by this macro is similar to the syntax used by
17/// [maplit](https://docs.rs/maplit/1.0.2/maplit/) except that in this macro, commas are optional.
18///
19/// **Example:** Without commas
20///
21/// ```
22/// use build_fs_tree::{FileSystemTree, dir, file};
23///
24/// let tree: FileSystemTree<&str, &str> = dir! {
25/// "a" => file!("foo")
26/// "b" => file!("bar")
27/// "c" => dir! {
28/// "x" => file!("baz")
29/// }
30/// };
31///
32/// # dbg!(&tree);
33/// assert_eq!(
34/// tree.dir_content().unwrap()
35/// .get("a").unwrap().file_content().unwrap(),
36/// &"foo",
37/// );
38/// assert_eq!(
39/// tree.dir_content().unwrap()
40/// .get("b").unwrap().file_content().unwrap(),
41/// &"bar",
42/// );
43/// assert_eq!(
44/// tree.dir_content().unwrap()
45/// .get("c").unwrap().dir_content().unwrap()
46/// .get("x").unwrap().file_content().unwrap(),
47/// &"baz",
48/// );
49/// ```
50///
51/// **Example:** With commas
52///
53/// ```
54/// use build_fs_tree::{FileSystemTree, dir, file};
55///
56/// let tree: FileSystemTree<&str, &str> = dir! {
57/// "a" => file!("foo"),
58/// "b" => file!("bar"),
59/// "c" => dir! {
60/// "x" => file!("baz"),
61/// },
62/// };
63///
64/// # dbg!(&tree);
65/// assert_eq!(
66/// tree.dir_content().unwrap()
67/// .get("a").unwrap().file_content().unwrap(),
68/// &"foo",
69/// );
70/// assert_eq!(
71/// tree.dir_content().unwrap()
72/// .get("b").unwrap().file_content().unwrap(),
73/// &"bar",
74/// );
75/// assert_eq!(
76/// tree.dir_content().unwrap()
77/// .get("c").unwrap().dir_content().unwrap()
78/// .get("x").unwrap().file_content().unwrap(),
79/// &"baz",
80/// );
81/// ```
82///
83/// # Typings
84///
85/// The types of `Path` and `FileContent` generic parameter isn't required to be the types
86/// provided by the expressions that users wrote as long as they implement
87/// [`From<X>`](::std::convert::From) where `X` is the types of the aforementioned user
88/// provided expressions.
89///
90/// **Example:** Where `Path` is a `String`
91///
92/// ```
93/// use build_fs_tree::{FileSystemTree, dir, file};
94///
95/// let tree: FileSystemTree<String, &str> = dir! {
96/// "a" => file!("foo")
97/// "b" => file!("bar")
98/// "c" => dir! {
99/// "x" => file!("baz")
100/// }
101/// };
102///
103/// # dbg!(&tree);
104/// assert_eq!(
105/// tree.dir_content().unwrap()
106/// .get("a").unwrap().file_content().unwrap(),
107/// &"foo",
108/// );
109/// assert_eq!(
110/// tree.dir_content().unwrap()
111/// .get("b").unwrap().file_content().unwrap(),
112/// &"bar",
113/// );
114/// assert_eq!(
115/// tree.dir_content().unwrap()
116/// .get("c").unwrap().dir_content().unwrap()
117/// .get("x").unwrap().file_content().unwrap(),
118/// &"baz",
119/// );
120/// ```
121///
122/// **Example:** Where `Path` is a `PathBuf` and `FileContent` is a `Vec<u8>`
123///
124/// ```
125/// use build_fs_tree::{FileSystemTree, dir, file};
126/// use std::path::PathBuf;
127///
128/// let tree: FileSystemTree<PathBuf, Vec<u8>> = dir! {
129/// "a" => file!("foo")
130/// "b" => file!("bar")
131/// "c" => dir! {
132/// "x" => file!("baz")
133/// }
134/// };
135///
136/// # dbg!(&tree);
137/// assert_eq!(
138/// tree.dir_content().unwrap()
139/// .get(&PathBuf::from("a")).unwrap().file_content().unwrap(),
140/// &Vec::from("foo"),
141/// );
142/// assert_eq!(
143/// tree.dir_content().unwrap()
144/// .get(&PathBuf::from("b")).unwrap().file_content().unwrap(),
145/// &Vec::from("bar"),
146/// );
147/// assert_eq!(
148/// tree.dir_content().unwrap()
149/// .get(&PathBuf::from("c")).unwrap().dir_content().unwrap()
150/// .get(&PathBuf::from("x")).unwrap().file_content().unwrap(),
151/// &Vec::from("baz"),
152/// );
153/// ```
154#[macro_export]
155macro_rules! dir {
156 ($($key:expr => $value:expr $(,)?)*) => {{
157 let mut __directory_content = ::std::collections::BTreeMap::new();
158 $(
159 let _ = ::std::collections::BTreeMap::insert(
160 &mut __directory_content,
161 ::std::convert::From::from($key),
162 $value
163 );
164 )*
165 $crate::FileSystemTree::Directory(__directory_content)
166 }};
167}
168
169/// Create representation of a [file](crate::FileSystemTree::File).
170///
171/// # Syntax
172///
173/// **Example:**
174///
175/// ```
176/// use build_fs_tree::{FileSystemTree, file};
177/// let file: FileSystemTree<&str, &str> = file!("CONTENT OF THE FILE");
178/// assert_eq!(file, FileSystemTree::File("CONTENT OF THE FILE"));
179/// ```
180///
181/// # Typings
182///
183/// This macro calls [`From::from`](::std::convert::From::from) under the hood.
184///
185/// **Example:** Where `FileContent` is a `String`
186///
187/// ```
188/// use build_fs_tree::{FileSystemTree, file};
189/// let file: FileSystemTree<&str, String> = file!("CONTENT OF THE FILE");
190/// assert_eq!(file, FileSystemTree::File("CONTENT OF THE FILE".to_string()));
191/// ```
192///
193/// **Example:** Where `FileContent` is a `Vec<u8>`
194///
195/// ```
196/// use build_fs_tree::{FileSystemTree, file};
197/// let file: FileSystemTree<&str, Vec<u8>> = file!("CONTENT OF THE FILE");
198/// assert_eq!(file, FileSystemTree::File("CONTENT OF THE FILE".into()));
199/// ```
200#[macro_export]
201macro_rules! file {
202 ($content:expr) => {
203 $crate::FileSystemTree::File(::std::convert::From::from($content))
204 };
205}