1use std::fmt;
2use crate::Node;
3
4pub struct Choice {
5 pub(crate) nodes: Vec<Box<dyn Node>>,
6}
7
8impl Choice {
9 pub fn new() -> Self {
10 Self::default()
11 }
12
13 pub fn push(mut self, node: Box<dyn Node>) -> Self {
14 self.nodes.push(node);
15 self
16 }
17}
18
19impl Default for Choice {
20 fn default() -> Self {
21 Self {
22 nodes: Vec::new(),
23 }
24 }
25}
26
27impl Node for Choice {
28 fn get_width(&self) -> usize {
29 let mut width = 0;
30 for n in &self.nodes {
31 width = n.get_width().max(width);
32 }
33
34 width + 2
35 }
36
37 fn get_height(&self) -> usize {
38 let mut height = 0;
39 for n in &self.nodes {
40 height += n.get_height();
41 }
42 height
43 }
44
45 fn as_str(&self) -> String {
46 let mut max_width = 0;
47 for n in &self.nodes {
48 max_width = n.get_width().max(max_width);
49 }
50
51 let mut ret = String::new();
52
53 for i in 0..self.nodes.len() {
54 let s = self.nodes[i].as_str();
55 let lines = s.lines().collect::<Vec<_>>();
56
57 for y in 0..lines.len() {
58 ret += if i == 0 {
59 if y == 1 { "┬" } else if y > 1 { "│" } else { " " }
60 } else if i < self.nodes.len() - 1 {
61 if y == 1 { "├" } else { "│" }
62 } else {
63 if y == 1 { "╰" } else if y < 1 { "│" } else { " " }
64 };
65
66 let offset = (max_width - lines[y].chars().count()) / 2;
67 let sep2 = if y == 1 { "─" } else { " " };
68 for _ in 0..offset { ret += sep2; }
69 ret += lines[y];
70 for _ in 0..(max_width - offset - lines[y].chars().count()) { ret += sep2; }
71
72 ret += if i == 0 {
73 if y == 1 { "┬" } else if y > 1 { "│" } else { " " }
74 } else if i < self.nodes.len() - 1 {
75 if y == 1 { "┤" } else { "│" }
76 } else {
77 if y == 1 { "╯" } else if y < 1 { "│" } else { " " }
78 };
79 ret += "\n";
80 }
81 }
82
83 ret
84 }
85}
86
87impl fmt::Display for Choice {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 write!(f, "{}", self.as_str())
90 }
91}