1#![deny(warnings)]
53
54extern crate flat_tree;
55
56use std::cmp;
57
58const DOWN: char = '│';
59const LEFT: char = '─';
60const TURN_DOWN: char = '┐';
61const TURN_UP: char = '┘';
62
63pub fn fmt(tree: &[usize]) -> String {
65 let max = tree.iter().fold(0, |prev, curr| cmp::max(prev, *curr));
67 let mut list = vec![false; max + 1];
68 println!("{:?}", list);
69 for &i in tree {
70 list[i] = true;
71 }
72
73 let width = (list.len().to_string()).len() + 1;
74 let last_block = list.len() - list.len() % 2;
75 let mut _roots = Vec::with_capacity(16);
76 flat_tree::full_roots(last_block, &mut _roots);
77
78 let blank = format!("{:width$}", ' ', width = width);
79 let mut matrix = vec![vec![blank.to_string(); max + 1]; list.len()];
80
81 for i in 0..list.len() {
82 if !list[i] {
83 continue;
84 }
85 let depth = flat_tree::depth(i);
86 let val = format!("{:width$}", i, width = width);
87 matrix[i][depth] = val;
88
89 if let Some(children) = flat_tree::children(i) {
90 add_path(&list, &mut matrix, children.0, i, depth, 1);
91 if children.1 < list.len() {
92 add_path(&list, &mut matrix, children.1, i, depth, -1);
93 }
94 }
95 }
96
97 let mut flat_tree_str = String::from("");
98 for arr in matrix {
99 let partial = arr.join("").trim_right().to_string() + "\n";
100 flat_tree_str.push_str(partial.as_str());
101 }
102
103 flat_tree_str
104}
105
106
107#[test]
108fn fmt_works_0() {
109 let tree = vec!(0);
110 let result = fmt(&tree);
111 assert_eq!(result, " 0\n");
112}
113
114#[test]
115fn fmt_works_1() {
116 let tree = vec!(1);
117 let result = fmt(&tree);
118 assert_eq!(result, "\n 1\n");
119}
120
121#[test]
122fn fmt_works_0_1_2() {
123 let tree = vec!(0, 1, 2);
124 let result = fmt(&tree);
125 assert_eq!(result, " 0─┐\n 1\n 2─┘\n");
126}
127
128fn add_path(
129 list: &[bool],
130 matrix: &mut Vec<Vec<String>>,
131 child: usize,
132 parent: usize,
133 parent_depth: usize,
134 dir: i32,
135) -> () {
136 if !list[child] {
137 return;
138 }
139
140 let depth = flat_tree::depth(child);
141 let width = (list.len().to_string()).len() + 1;
142 let ptr = depth + 1;
143
144 for i in ptr..parent_depth {
145 matrix[child][i] = pad(LEFT, LEFT, width);
146 }
147
148 let turn_char = if dir < 0 { TURN_UP } else { TURN_DOWN };
149 matrix[child][ptr] = pad(turn_char, LEFT, width);
150
151 let mut _child: i32 = child as i32;
152 loop {
153 _child += dir;
154 if _child == parent as i32 {
155 break;
156 };
157 matrix[_child as usize][ptr] = pad(DOWN, ' ', width);
158 }
159}
160
161fn pad(str: char, pad_char: char, width: usize) -> String {
162 let mut symbol = String::from("");
163 for i in 0..width {
164 if i == width - 1 {
165 symbol.push(str);
166 } else {
167 symbol.push(pad_char);
168 }
169 }
170 symbol
171}