1use std::fmt;
2use crate::Node;
3
4pub struct Sequence {
5 pub(crate) nodes: Vec<Vec<Box<dyn Node>>>,
6 pub(crate) gap_size: usize,
7}
8
9impl Sequence {
10 pub fn new() -> Self {
11 Self::default()
12 }
13
14 pub fn push(mut self, node: Box<dyn Node>) -> Self {
15 let id = self.nodes.len() - 1;
16 self.nodes[id].push(node);
17 self
18 }
19
20 pub fn gap_size(mut self, size: usize) -> Self {
21 self.gap_size = size;
22 self
23 }
24
25 pub fn next_row(mut self) -> Self {
26 self.nodes.push(Vec::new());
27 self
28 }
29
30 pub fn num_rows(&self) -> usize {
31 self.nodes.len()
32 }
33}
34
35impl Default for Sequence {
36 fn default() -> Self {
37 Self {
38 nodes: vec![Vec::new()],
39 gap_size: 2,
40 }
41 }
42}
43
44impl Node for Sequence {
45 fn get_width(&self) -> usize {
46 let mut width = 0;
47 for row in &self.nodes {
48 let mut row_width = 0;
49 for n in row {
50 row_width += n.get_width();
51 }
52
53 if row.len() > 1 {
54 row_width += self.gap_size * (row.len() - 1);
55 }
56
57 width = row_width.max(width);
58 }
59
60 if self.nodes.len() > 1 { width += 3; }
61
62 width
63 }
64
65 fn get_height(&self) -> usize {
66 let mut height = 0;
67 for row in &self.nodes {
68 let mut row_height = 0;
69 for n in row {
70 row_height = n.get_height().max(row_height);
71 }
72
73 height += row_height;
74 }
75
76 if self.nodes.len() > 1 {
77 height += self.nodes.len() - 1;
78 }
79
80 height
81 }
82
83 fn as_str(&self) -> String {
84 let mut final_s = String::new();
85 let max_width = self.get_width() - if self.nodes.len() > 1 { 3 } else { 0 };
86
87 for row_n in 0..self.nodes.len() {
88 let row = &self.nodes[row_n];
89 let mut row_width = 0;
90 let mut widths = Vec::new();
91 let mut nodes_strs = Vec::new();
92 let mut height = 0;
93
94 for n in row {
95 let w = n.get_width();
96 let s = n.as_str();
97
98 height = n.get_height().max(height);
99 widths.push(w);
100 nodes_strs.push(s);
101 row_width += w;
102 }
103
104 if row.len() > 1 {
105 row_width += self.gap_size * (row.len() - 1);
106 }
107
108 let mut ret = String::new();
109
110 for y in 0..height {
111 if self.nodes.len() > 1 {
112 ret += if row_n == 0 {
113 if y == 1 { "─" } else { " " }
114 } else {
115 if y == 1 { "└" } else if y == 0 { "│" } else { " " }
116 };
117 }
118
119 for i in 0..row.len() {
120 let lines = nodes_strs[i].lines().collect::<Vec<_>>();
121
122 if y < lines.len() {
123 ret += lines[y];
124 } else {
125 for _ in 0..widths[i] {
126 ret += " ";
127 }
128 }
129
130 if i < row.len() - 1 {
132 let sep = if y == 1 { "─" } else { " " };
133 for _ in 0..self.gap_size { ret += sep; }
134 }
135 }
136
137 for _ in row_width..max_width { ret += if y == 1 { "─" } else { " " }; }
138
139 if self.nodes.len() > 1 {
140 if row_n < self.nodes.len() - 1 {
141 ret += if y == 0 { " " } else if y == 1 { "┐" } else { "│" };
142 }
143
144 ret += if row_n == 0 {
145 if y == 1 { "┌" } else if y == 0 { " " } else { "│" }
146 } else if row_n < self.nodes.len() - 1 {
147 "│"
148 } else {
149 if y == 0 { " │" } else if y == 1 { "─┘" } else { " " }
150 };
151 }
152
153 if y < height - 1 { ret += "\n"; }
154 }
155
156 final_s += &ret;
158
159 if self.nodes.len() > 1 && row_n < self.nodes.len() - 1 {
160 final_s += "\n┌";
161 for _ in 0..max_width { final_s += "─"; }
162 final_s += "┘│\n";
163 }
164 }
165
166 final_s
167 }
168}
169
170impl fmt::Display for Sequence {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 write!(f, "{}", self.as_str())
173 }
174}