Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5f51ba1

Browse files
Added ListNode and TreeNode macros
1 parent 847f104 commit 5f51ba1

File tree

1 file changed

+316
-0
lines changed

1 file changed

+316
-0
lines changed

‎src/macros/mod.rs

Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
///////////////////////////////////////////////////////////////////////////////////////////////////
2+
// List Node macros
3+
///////////////////////////////////////////////////////////////////////////////////////////////////
4+
5+
/// ## Description
6+
///
7+
/// A macro to reduce the boilerplate in generating a full ListNode.
8+
///
9+
/// ## Example
10+
///
11+
/// This code:
12+
///
13+
/// ```rust
14+
/// use crate::utils::list_node;
15+
/// let node = list_node!(1, 2, 3, 4);
16+
/// ```
17+
///
18+
/// Is the equivalent of the following:
19+
///
20+
/// ```rust
21+
/// use crate::utils::ListNode;
22+
/// let node = ListNode {
23+
/// val: 1,
24+
/// next: Some(Box(ListNode {
25+
/// val: 2,
26+
/// next: Some(Box(ListNode {
27+
/// val: 3,
28+
/// next: ListNode::new(4),
29+
/// }))
30+
/// }))
31+
/// }
32+
/// ```
33+
#[macro_export]
34+
macro_rules! list_node {
35+
($val:expr) => {
36+
$crate::utils::ListNode::new($val)
37+
};
38+
($val:expr, $($rest:tt)*) => {
39+
{
40+
let mut node = $crate::utils::ListNode::new($val);
41+
node.next = Some(std::boxed::Box::new(list_node!($($rest)*)));
42+
node
43+
}
44+
};
45+
}
46+
47+
///////////////////////////////////////////////////////////////////////////////////////////////////
48+
// Tree Node macros
49+
///////////////////////////////////////////////////////////////////////////////////////////////////
50+
51+
/// TODO:
52+
/// You can generate TreeNodes manually by utilizing tuples. The first value is a single value and
53+
/// everything else is a tuple of `(Option<i32>, Option<i32>)`
54+
// #[macro_export]
55+
#[allow(unused_macros)]
56+
macro_rules! tree {
57+
($val:expr) => {
58+
$crate::utils::TreeNode::new($val)
59+
};
60+
($($left:tt, $right:tt)*) => {
61+
$(
62+
if let Some(left) = $left {
63+
$node.left = Some(std::rc::Rc::new(std::cell::RefCell::new(tree!(
64+
left
65+
))));
66+
}
67+
if let Some(right) = $right {
68+
$node.right = Some(std::rc::Rc::new(std::cell::RefCell::new(tree!(
69+
right
70+
))));
71+
}
72+
)*
73+
};
74+
($val:expr, $($left:expr, $right:expr)*) => {
75+
{
76+
let mut node = $crate::utils::TreeNode::new($val);
77+
$(
78+
tree!(node, ($left, $right));
79+
)*
80+
node
81+
}
82+
};
83+
}
84+
85+
/// ## Description
86+
///
87+
/// A macro to reduce the boilerplate in generating symmetric binary trees.
88+
///
89+
/// ## Match arms
90+
///
91+
/// Arm 1:
92+
/// - Takes the value as an argument.
93+
/// - Equivalent of doing `TreeNode::new()`.
94+
/// Arm 2:
95+
/// - Takes the value as an argument.
96+
/// - Also takes a sequence of left and right node values at the same time (which means they're
97+
/// symmetric) as an argument (and builds the `TreeNode` struct with them).
98+
///
99+
/// ## Example usage
100+
/// ```rust
101+
/// use crate::utils::symmetric_tree;
102+
/// symmetric_tree!(1, 2, 3, 4)
103+
/// ```
104+
/// The symmetric_tree! macro invocation is desugared to this:
105+
/// ```rust
106+
/// use std::rc::Rc;
107+
/// use std::cell::RefCell;
108+
///
109+
/// use crate::utils::TreeNode;
110+
///
111+
/// TreeNode {
112+
/// val: 1,
113+
/// left: Some(Box::new(TreeNode {
114+
/// val: 2,
115+
/// left: Some(Box::new(TreeNode {
116+
/// val: 3,
117+
/// left: Some(Box::new(TreeNode {
118+
/// val: 4,
119+
/// left: None,
120+
/// right: None,
121+
/// }))
122+
/// right: Some(Box::new(TreeNode {
123+
/// val: 4,
124+
/// left: None,
125+
/// right: None,
126+
/// }))
127+
/// }))
128+
/// right: Some(Box::new(TreeNode {
129+
/// val: 3,
130+
/// left: Some(Box::new(TreeNode {
131+
/// val: 4,
132+
/// left: None,
133+
/// right: None,
134+
/// }))
135+
/// right: Some(Box::new(TreeNode {
136+
/// val: 4,
137+
/// left: None,
138+
/// right: None,
139+
/// }))
140+
/// }))
141+
/// }))
142+
/// right: Some(Box::new(TreeNode {
143+
/// val: 2,
144+
/// left: Some(Box::new(TreeNode {
145+
/// val: 3,
146+
/// left: Some(Box::new(TreeNode {
147+
/// val: 4,
148+
/// left: None,
149+
/// right: None,
150+
/// }))
151+
/// right: Some(Box::new(TreeNode {
152+
/// val: 4,
153+
/// left: None,
154+
/// right: None,
155+
/// }))
156+
/// }))
157+
/// right: Some(Box::new(TreeNode {
158+
/// val: 3,
159+
/// left: Some(Box::new(TreeNode {
160+
/// val: 4,
161+
/// left: None,
162+
/// right: None,
163+
/// }))
164+
/// right: Some(Box::new(TreeNode {
165+
/// val: 4,
166+
/// left: None,
167+
/// right: None,
168+
/// }))
169+
/// }))
170+
/// }))
171+
/// }
172+
/// ```
173+
/// I bet you don't want to write that every time.
174+
/// You can have greater control with this too:
175+
/// ```rust
176+
/// use crate::utils::{symmetric_tree, TreeNode};
177+
/// TreeNode {
178+
/// val: 1,
179+
/// left: None,
180+
/// right: Some(Box::new(symmetric_tree!(2, 3, 4)))
181+
/// }
182+
/// ```
183+
/// Now you have a tree that branches all the way through the right side without having anything on
184+
/// the left.
185+
#[macro_export]
186+
macro_rules! symmetric_tree {
187+
($val:expr) => {
188+
$crate::utils::TreeNode::new($val)
189+
};
190+
($val:expr, $($both_sides:tt)*) => {
191+
{
192+
let mut node = $crate::utils::TreeNode::new($val);
193+
node.left = Some(std::rc::Rc::new(std::cell::RefCell::new(symmetric_tree!(
194+
$($both_sides)*
195+
))));
196+
node.right = Some(std::rc::Rc::new(std::cell::RefCell::new(symmetric_tree!(
197+
$($both_sides)*
198+
))));
199+
node
200+
}
201+
};
202+
}
203+
204+
/// ## Description
205+
///
206+
/// A macro to reduce the boilerplate in generating left-sided only binary trees.
207+
///
208+
/// ## Match arms
209+
///
210+
/// Arm 1:
211+
/// - Takes the value as an argument.
212+
/// - Equivalent of doing `TreeNode::new()`.
213+
/// Arm 2:
214+
/// - Takes the value as an argument.
215+
/// - Also takes a sequence of left only node values as an argument (and builds the `TreeNode`
216+
/// struct with them).
217+
///
218+
/// ## Example
219+
///
220+
/// This code:
221+
///
222+
/// ```rust
223+
/// use crate::utils::left_tree;
224+
///
225+
/// let left_only_tree = left_tree!(1, 2, 3);
226+
/// ```
227+
///
228+
/// Is equivalent to this:
229+
///
230+
/// ```rust
231+
/// use std::{rc::Rc, cell::RefCell};
232+
/// use crate::utils::TreeNode;
233+
///
234+
/// let left_only_tree = TreeNode {
235+
/// val: 1,
236+
/// left: Some(Rc::new(RefCell::new(TreeNode {
237+
/// val: 2,
238+
/// left: Some(Rc::new(RefCell::new(TreeNode {
239+
/// val: 3,
240+
/// left: None,
241+
/// right: None,
242+
/// })))
243+
/// right: None,
244+
/// })))
245+
/// right: None,
246+
/// };
247+
/// ```
248+
#[macro_export]
249+
macro_rules! left_tree {
250+
($val:expr) => {
251+
$crate::utils::TreeNode::new($val)
252+
};
253+
($val:expr, $left:tt) => {{
254+
let mut node = $crate::utils::TreeNode::new($val);
255+
node.left = Some(std::rc::Rc::new(std::cell::RefCell::new(left_tree!($left))));
256+
node
257+
}};
258+
}
259+
260+
/// ## Description
261+
///
262+
/// A macro to reduce the boilerplate in generating right-sided only binary trees.
263+
///
264+
/// ## Match arms
265+
///
266+
/// Arm 1:
267+
/// - Takes the value as an argument.
268+
/// - Equivalent of doing `TreeNode::new()`.
269+
/// Arm 2:
270+
/// - Takes the value as an argument.
271+
/// - Also takes a sequence of right only node values as an argument (and builds the `TreeNode`
272+
/// struct with them).
273+
///
274+
/// ## Example
275+
///
276+
/// This code:
277+
///
278+
/// ```rust
279+
/// use crate::utils::right_tree;
280+
///
281+
/// let right_only_tree = right_tree!(1, 2, 3);
282+
/// ```
283+
///
284+
/// Is equivalent to this:
285+
///
286+
/// ```rust
287+
/// use std::{rc::Rc, cell::RefCell};
288+
/// use crate::utils::TreeNode;
289+
///
290+
/// let right_only_tree = TreeNode {
291+
/// val: 1,
292+
/// left: None,
293+
/// right: Some(Rc::new(RefCell::new(TreeNode {
294+
/// val: 2,
295+
/// left: None,
296+
/// right: Some(Rc::new(RefCell::new(TreeNode {
297+
/// val: 3,
298+
/// left: None,
299+
/// right: None,
300+
/// })))
301+
/// })))
302+
/// };
303+
/// ```
304+
#[macro_export]
305+
macro_rules! right_tree {
306+
($val:expr) => {
307+
$crate::utils::TreeNode::new($val)
308+
};
309+
($val:expr, $right:tt) => {{
310+
let mut node = $crate::utils::TreeNode::new($val);
311+
node.right = Some(std::rc::Rc::new(std::cell::RefCell::new(right_tree!(
312+
$right
313+
))));
314+
node
315+
}};
316+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /