1use indent_display::{IndentedDisplay, IndentedOptions, Indenter};
8
9const DEBUG_ITERATOR: bool = false;
12
13#[derive(Debug)]
17pub struct Node<T>
18where
19 T: std::fmt::Debug,
20{
21 parent: Option<usize>,
23 children: Vec<usize>,
25 pub data: T,
27}
28
29impl<T> Clone for Node<T>
31where
32 T: Clone + std::fmt::Debug,
33{
34 fn clone(&self) -> Self {
35 let parent = self.parent;
36 let children = self.children.clone();
37 let data = self.data.clone();
38 Self {
39 parent,
40 children,
41 data,
42 }
43 }
44}
45
46impl<T> Node<T>
48where
49 T: std::fmt::Debug,
50{
51 pub fn new(data: T, parent: Option<usize>) -> Self {
54 let children = Vec::new();
55 Self {
56 parent,
57 children,
58 data,
59 }
60 }
61
62 pub fn has_parent(&self) -> bool {
66 self.parent.is_some()
67 }
68
69 pub fn set_parent(&mut self, parent: Option<usize>) {
72 self.parent = parent;
73 }
74
75 pub fn add_child(&mut self, child: usize) {
78 self.children.push(child);
79 }
80
81 pub fn has_children(&self) -> bool {
84 !self.children.is_empty()
85 }
86
87 }
89
90#[derive(Debug)]
95pub struct Hierarchy<T>
96where
97 T: std::fmt::Debug,
98{
99 elements: Vec<Node<T>>,
101 roots: Vec<usize>,
104}
105
106impl<T> std::default::Default for Hierarchy<T>
108where
109 T: std::fmt::Debug,
110{
111 fn default() -> Self {
112 let elements = vec![];
113 let roots = vec![];
114 Self { elements, roots }
115 }
116}
117
118impl<T> Clone for Hierarchy<T>
120where
121 T: Clone + std::fmt::Debug,
122{
123 fn clone(&self) -> Self {
124 let elements = self.elements.clone();
125 let roots = self.roots.clone();
126 Self { elements, roots }
127 }
128}
129
130impl<T> Hierarchy<T>
132where
133 T: std::fmt::Debug,
134{
135 pub fn new() -> Self {
138 Self {
139 elements: Vec::new(),
140 roots: Vec::new(),
141 }
142 }
143
144 pub fn len(&self) -> usize {
147 self.elements.len()
148 }
149
150 pub fn is_empty(&self) -> bool {
153 self.elements.is_empty()
154 }
155
156 pub fn add_node(&mut self, data: T) -> usize {
159 let n = self.elements.len();
160 self.elements.push(Node::new(data, None));
161 n
162 }
163
164 pub fn relate(&mut self, parent: usize, child: usize) {
167 self.elements[parent].add_child(child);
168 self.elements[child].set_parent(Some(parent));
169 }
170
171 pub fn find_roots(&mut self) {
174 self.roots = Vec::new();
175 for (i, e) in self.elements.iter().enumerate() {
176 if !e.has_parent() {
177 self.roots.push(i);
178 }
179 }
180 }
181
182 pub fn borrow_node(&self, index: usize) -> &T {
185 &self.elements[index].data
186 }
187
188 pub fn borrow_mut(&mut self) -> (&Vec<usize>, &mut Vec<Node<T>>) {
191 (&self.roots, &mut self.elements)
192 }
193
194 pub fn borrow_roots(&self) -> &Vec<usize> {
197 &self.roots
198 }
199
200 pub fn enum_from(&self, node: usize) -> NodeEnum<T> {
203 NodeEnum::new(&self.elements, node)
204 }
205
206 pub fn iter_from(&self, node: usize) -> NodeIter<T> {
209 NodeIter::new(&self.elements, node)
210 }
211
212 pub fn borrow_elements(&self) -> &Vec<Node<T>> {
215 &self.elements
216 }
217
218 pub fn take_elements(self) -> Vec<T> {
221 self.elements.into_iter().map(|n| n.data).collect()
222 }
223
224 }
226
227impl<'a, Opt, T> IndentedDisplay<'a, Opt> for Hierarchy<T>
229where
230 Opt: IndentedOptions<'a>,
231 T: std::fmt::Debug + IndentedDisplay<'a, Opt>,
232{
233 fn indent(&self, f: &mut Indenter<'a, Opt>) -> std::fmt::Result {
236 use std::fmt::Write;
237 let mut sub = f.sub();
238 for (i, e) in self.elements.iter().enumerate() {
239 if !e.has_parent() {
240 for x in self.enum_from(i) {
241 #[allow(unreachable_patterns)]
242 match x {
243 NodeEnumOp::Push(x, _) => {
244 self.elements[x].data.indent(&mut sub)?;
245 writeln!(sub)?;
246 sub = sub.sub();
247 }
248 NodeEnumOp::Pop(_, _) => {
249 sub = sub.pop();
250 }
251 _ => {}
252 };
253 }
254 }
256 }
257 drop(sub);
258 Ok(())
259 }
260}
261
262#[derive(Debug, Clone, Copy, PartialEq)]
268pub enum NodeEnumOp<T> {
269 Push(T, bool),
271 Pop(T, bool),
273}
274
275impl<T> NodeEnumOp<T> {
277 #[inline]
280 pub fn unpack(&self) -> (bool, &T, bool) {
281 match &self {
282 Self::Pop(d, c) => (false, d, *c),
283 Self::Push(d, c) => (true, d, *c),
284 }
285 }
286
287 #[inline]
290 pub fn is_pop(&self) -> bool {
291 matches!(self, Self::Pop(_, _))
292 }
293
294 }
296
297#[derive(Debug)]
305pub struct Recipe {
306 ops: Vec<NodeEnumOp<usize>>,
308 max_depth: usize,
310 cur_depth: usize,
312}
313
314impl Default for Recipe {
316 fn default() -> Self {
317 Self::new()
318 }
319}
320
321impl Recipe {
323 pub fn new() -> Self {
326 Self {
327 ops: Vec::new(),
328 max_depth: 0,
329 cur_depth: 0,
330 }
331 }
332
333 pub fn add_op(&mut self, op: NodeEnumOp<usize>) {
336 if op.is_pop() {
337 self.cur_depth -= 1;
338 } else {
339 self.cur_depth += 1;
340 if self.cur_depth > self.max_depth {
341 self.max_depth = self.cur_depth;
342 }
343 }
344 self.ops.push(op);
345 }
346
347 pub fn take(self) -> (usize, Vec<NodeEnumOp<usize>>) {
350 (self.max_depth, self.ops)
351 }
352
353 pub fn depth(&self) -> usize {
356 self.max_depth
357 }
358
359 pub fn borrow_ops(&self) -> &Vec<NodeEnumOp<usize>> {
362 &self.ops
363 }
364
365 pub fn of_ops<T>(iter: NodeEnum<T>) -> Self
368 where
369 T: std::fmt::Debug,
370 {
371 let mut r = Self::new();
372 for op in iter {
373 r.add_op(op);
374 }
375 r
376 }
377
378 }
380
381#[derive(Debug, Clone, Copy)]
385enum NodeEnumState {
386 PreNode(usize),
388 PreChildren(usize),
389 Child(usize, usize),
390 PostChildren(usize),
391}
392
393pub struct NodeEnum<'a, T>
419where
420 T: std::fmt::Debug,
421{
422 pub hierarchy: &'a [Node<T>],
424 stack: Vec<NodeEnumState>,
426}
427
428impl<'a, T> NodeEnum<'a, T>
430where
431 T: std::fmt::Debug,
432{
433 pub fn new(hierarchy: &'a [Node<T>], root: usize) -> Self {
436 let stack = vec![NodeEnumState::PreNode(root)];
437 Self { hierarchy, stack }
438 }
439}
440
441impl<'a, T> Iterator for NodeEnum<'a, T>
443where
444 T: std::fmt::Debug,
445{
446 type Item = NodeEnumOp<usize>;
447 fn next(&mut self) -> Option<Self::Item> {
448 if self.stack.is_empty() {
449 None
450 } else {
451 let se = self.stack.pop().unwrap();
452 if DEBUG_ITERATOR {
454 println!("{se:?}");
455 }
456 match se {
457 NodeEnumState::PreNode(x) => {
458 self.stack.push(NodeEnumState::PreChildren(x));
459 let has_children = self.hierarchy[x].has_children();
460 Some(NodeEnumOp::Push(x, has_children))
461 }
462 NodeEnumState::PreChildren(x) => {
463 self.stack.push(NodeEnumState::Child(x, 0));
465 self.next()
466 }
467 NodeEnumState::Child(x, n) => {
468 if let Some(c) = self.hierarchy[x].children.get(n) {
470 self.stack.push(NodeEnumState::Child(x, n + 1));
471 self.stack.push(NodeEnumState::PreNode(*c));
472 } else {
473 self.stack.push(NodeEnumState::PostChildren(x));
475 }
476 self.next()
477 }
478 NodeEnumState::PostChildren(x) => {
479 let has_children = self.hierarchy[x].has_children();
481 Some(NodeEnumOp::Pop(x, has_children))
482 }
483 }
484 }
485 }
486}
487
488pub struct NodeIter<'a, T>
492where
493 T: std::fmt::Debug,
494{
495 node_enum: NodeEnum<'a, T>,
496}
497
498impl<'a, T> NodeIter<'a, T>
500where
501 T: std::fmt::Debug,
502{
503 pub fn new(hierarchy: &'a [Node<T>], root: usize) -> Self {
506 Self {
507 node_enum: NodeEnum::new(hierarchy, root),
508 }
509 }
510}
511
512impl<'a, T> Iterator for NodeIter<'a, T>
514where
515 T: std::fmt::Debug,
516{
517 type Item = NodeEnumOp<(usize, &'a T)>;
518 fn next(&mut self) -> Option<Self::Item> {
519 match self.node_enum.next() {
520 Some(NodeEnumOp::Push(x, c)) => {
521 Some(NodeEnumOp::Push((x, &self.node_enum.hierarchy[x].data), c))
522 }
523 Some(NodeEnumOp::Pop(x, c)) => {
524 Some(NodeEnumOp::Pop((x, &self.node_enum.hierarchy[x].data), c))
525 }
526 None => None,
527 }
528 }
529}
530
531#[cfg(test)]
533mod test_node {
534 use super::*;
535 use indent_display::NullOptions;
536
537 pub fn basic_hierarchy() -> Hierarchy<&'static str> {
539 let mut h = Hierarchy::new();
540 let a = h.add_node("A");
541 let b = h.add_node("B");
542 let c0 = h.add_node("C0");
543 let c1 = h.add_node("C1");
544 let d = h.add_node("D");
545 let e = h.add_node("E");
546 let f = h.add_node("F");
547 h.relate(a, b);
548 h.relate(a, d);
549 h.relate(a, e);
550 h.relate(b, c0);
551 h.relate(b, c1);
552 h.relate(e, f);
553 h.find_roots();
554 h
555 }
556
557 #[test]
559 fn test_0() {
560 let h = basic_hierarchy();
561 assert_eq!(h.borrow_roots(), &[0], "Expect roots to just be A");
562 }
563
564 #[test]
566 fn test_display() {
567 let h = basic_hierarchy();
568 let mut f = Vec::<u8>::new();
569 let opt = NullOptions {};
570 let mut ind = Indenter::new(&mut f, " ", &opt);
571 h.indent(&mut ind).unwrap();
572 drop(ind);
573 assert_eq!(
574 f,
575 b" A
576 B
577 C0
578 C1
579 D
580 E
581 F
582"
583 );
584 }
585
586 #[test]
588 fn test_recipe() {
589 let h = basic_hierarchy();
590 let mut r = Recipe::new();
591 for op in h.enum_from(0) {
592 r.add_op(op);
593 }
594 let (max_depth, ops) = r.take();
595 assert_eq!(max_depth, 3, "Max depth of tree is 3");
596 assert_eq!(
597 ops,
598 vec![
599 NodeEnumOp::Push(0, true),
600 NodeEnumOp::Push(1, true),
601 NodeEnumOp::Push(2, false),
602 NodeEnumOp::Pop(2, false),
603 NodeEnumOp::Push(3, false),
604 NodeEnumOp::Pop(3, false),
605 NodeEnumOp::Pop(1, true),
606 NodeEnumOp::Push(4, false),
607 NodeEnumOp::Pop(4, false),
608 NodeEnumOp::Push(5, true),
609 NodeEnumOp::Push(6, false),
610 NodeEnumOp::Pop(6, false),
611 NodeEnumOp::Pop(5, true),
612 NodeEnumOp::Pop(0, true),
613 ],
614 "Recipe mismatch"
615 );
616 }
617}